summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Pabon <lpabon@redhat.com>2014-04-23 16:18:57 -0400
committerVijay Bellur <vbellur@redhat.com>2014-07-18 10:55:51 -0700
commit13f644f78336c79850b332c35ad439fda8dac4fa (patch)
tree7c5fc94a89b7374272451dd9608d0c90fb678ea4
parentc7f617dfe63fea23693c9ae74b8761349d17a986 (diff)
build: Support for unit tests using Cmockery2
This patch will allow for developers to create unit tests for their code. Documentation has been added to the patch and is available here: doc/hacker-guide/en-US/markdown/unittest.md Also, unit tests are run when RPM is created. This patch is a replacement for http://review.gluster.org/#/c/7281 which removed unit test infrastucture from the repo due to multiple conflicts. Cmockery2 is now available in Fedora and EPEL, and soon to be available in Debian and Ubuntu. For all other operating systems, please install from the source: https://github.com/lpabon/cmockery2 BUG: 1067059 Change-Id: I1b36cb1f56fd10916f9bf535e8ad080a3358289f Signed-off-by: Luis Pabón <lpabon@redhat.com> Reviewed-on: http://review.gluster.org/7538 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--configure.ac8
-rw-r--r--doc/hacker-guide/en-US/markdown/unittest.md8
-rw-r--r--glusterfs.spec.in7
-rw-r--r--libglusterfs/src/Makefile.am16
-rw-r--r--libglusterfs/src/mem-pool.c9
-rw-r--r--libglusterfs/src/unittest/mem_pool_unittest.c31
-rw-r--r--xlators/cluster/dht/src/Makefile.am14
-rw-r--r--xlators/cluster/dht/src/dht-layout.c19
-rw-r--r--xlators/cluster/dht/src/unittest/dht_layout_mock.c14
9 files changed, 107 insertions, 19 deletions
diff --git a/configure.ac b/configure.ac
index 8d8b971ab6f..c814a77689a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -315,6 +315,8 @@ AC_CHECK_LIB([crypto], [MD5], , AC_MSG_ERROR([OpenSSL crypto library is required
AC_CHECK_LIB([pthread], [pthread_mutex_init], , AC_MSG_ERROR([Posix threads library is required to build glusterfs]))
+AC_CHECK_LIB([cmockery], [mock_assert], , AC_MSG_ERROR([cmockery2 library is required to build glusterfs]))
+
AC_CHECK_FUNC([dlopen], [has_dlopen=yes], AC_CHECK_LIB([dl], [dlopen], , AC_MSG_ERROR([Dynamic linking library required to build glusterfs])))
AC_CHECK_LIB([readline], [rl_do_undo], [RL_UNDO="yes"], [RL_UNDO="no"])
@@ -674,6 +676,12 @@ AC_SUBST(HAVE_LINKAT)
dnl check for Monotonic clock
AC_CHECK_FUNC([clock_gettime], [has_monotonic_clock=yes], AC_CHECK_LIB([rt], [clock_gettime], , AC_MSG_WARN([System doesn't have monotonic clock using contrib])))
+dnl Add cmockery2 for unit tests
+UNITTEST_CFLAGS='-g -Wall -DUNIT_TESTING=1 -DDEBUG -Werror -O0 --coverage'
+UNITTEST_LDFLAGS='-lcmockery -lgcov'
+AC_SUBST(UNITTEST_CFLAGS)
+AC_SUBST(UNITTEST_LDFLAGS)
+
dnl Check for argp
AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp]))
AC_CONFIG_SUBDIRS(contrib/argp-standalone)
diff --git a/doc/hacker-guide/en-US/markdown/unittest.md b/doc/hacker-guide/en-US/markdown/unittest.md
index 73fe775d450..42dc210959e 100644
--- a/doc/hacker-guide/en-US/markdown/unittest.md
+++ b/doc/hacker-guide/en-US/markdown/unittest.md
@@ -193,11 +193,10 @@ Now you can add the following for each of the unit tests that you would like to
```
### UNIT TEST xxx_unittest ###
-xxx_unittest_CPPFLAGS = $(UNITTEST_CPPFLAGS) $(xxx_CPPFLAGS)
+xxx_unittest_CPPFLAGS = $(xxx_CPPFLAGS)
xxx_unittest_SOURCES = xxx.c \
unittest/xxx_unittest.c
xxx_unittest_CFLAGS = $(UNITTEST_CFLAGS)
-xxx_unittest_LDADD = $(UNITTEST_LDADD)
xxx_unittest_LDFLAGS = $(UNITTEST_LDFLAGS)
noinst_PROGRAMS += xxx_unittest
TESTS += xxx_unittest
@@ -214,11 +213,10 @@ You may see that the linker will complain about missing functions needed by the
You can type `make` in the directory where the C file is located. Once you built it and there are no errors, you can execute the test either by directly executing the program (in our example above it is called `xxx_unittest` ), or by running `make check`.
#### Debugging
-Sometimes you may need to debug your unit test. To do that, you will have to point `gdb` to the actual binary which is located in the `.libs` subdirectory. For example, you can do the following from the root of the source tree to debug `mem_pool_unittest`:
+Sometimes you may need to debug your unit test. To do that, you will have to point `gdb` to the binary which is located in the same directory as the source. For example, you can do the following from the root of the source tree to debug `mem_pool_unittest`:
```
-$ export LD_LIBRARY_PATH=cmockery2/.libs
-$ gdb ./libglusterfs/src/.libs/mem_pool_unittest
+$ gdb libglusterfs/src/mem_pool_unittest
```
diff --git a/glusterfs.spec.in b/glusterfs.spec.in
index b6068ff792a..52757262c90 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -191,6 +191,7 @@ BuildRequires: libxml2-devel openssl-devel
BuildRequires: libaio-devel
BuildRequires: python-devel
BuildRequires: python-ctypes
+BuildRequires: cmockery2-devel
%if ( 0%{!?_without_systemtap:1} )
BuildRequires: systemtap-sdt-devel
%endif
@@ -508,6 +509,9 @@ pushd xlators/features/glupy/src
FLAGS="$RPM_OPT_FLAGS" python setup.py build
popd
+%check
+make check
+
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
@@ -1026,6 +1030,9 @@ fi
%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid
%changelog
+* Wed Jul 16 2014 Luis Pabon <lpabon@redhat.com>
+- Added cmockery2 dependency
+
* Thu Jun 29 2014 Humble Chirammal <hchiramm@redhat.com>
- Added dynamic loading of fuse module with glusterfs-fuse package installation in el5.
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 25ee4c27a8b..de1b9b0b1f2 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -58,3 +58,19 @@ y.tab.h: graph.y
CLEANFILES = graph.lex.c y.tab.c y.tab.h
CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
+
+#### UNIT TESTS #####
+CLEANFILES += *.gcda *.gcno *_xunit.xml
+noinst_PROGRAMS =
+TESTS =
+
+mem_pool_unittest_CPPFLAGS = $(libglusterfs_la_CPPFLAGS)
+mem_pool_unittest_SOURCES = mem-pool.c \
+ mem-pool.h \
+ unittest/mem_pool_unittest.c \
+ unittest/log_mock.c \
+ unittest/global_mock.c
+mem_pool_unittest_CFLAGS = $(UNITTEST_CFLAGS)
+mem_pool_unittest_LDFLAGS = $(UNITTEST_LDFLAGS)
+noinst_PROGRAMS += mem_pool_unittest
+TESTS += mem_pool_unittest
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 356cfdb78ca..093592ec056 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -24,17 +24,24 @@
#define GLUSTERFS_ENV_MEM_ACCT_STR "GLUSTERFS_DISABLE_MEM_ACCT"
+#include <cmockery/pbc.h>
+#include <cmockery/cmockery_override.h>
+
void
gf_mem_acct_enable_set (void *data)
{
glusterfs_ctx_t *ctx = NULL;
+ REQUIRE(data != NULL);
+
ctx = data;
GF_ASSERT (ctx != NULL);
ctx->mem_acct_enable = 1;
+ ENSURE(1 == ctx->mem_acct_enable);
+
return;
}
@@ -151,6 +158,8 @@ __gf_realloc (void *ptr, size_t size)
if (!THIS->ctx->mem_acct_enable)
return REALLOC (ptr, size);
+ REQUIRE(NULL != ptr);
+
tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
orig_ptr = (char *)ptr - 8 - 4;
diff --git a/libglusterfs/src/unittest/mem_pool_unittest.c b/libglusterfs/src/unittest/mem_pool_unittest.c
index 3c0724d65e5..0d7aa199df0 100644
--- a/libglusterfs/src/unittest/mem_pool_unittest.c
+++ b/libglusterfs/src/unittest/mem_pool_unittest.c
@@ -35,8 +35,8 @@ typedef struct __attribute__((packed)) {
* Prototypes to private functions
*/
int
-gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr,
- size_t size, uint32_t type);
+gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,
+ uint32_t type, const char *typestr);
/*
* Helper functions
@@ -137,14 +137,14 @@ test_gf_mem_set_acct_info_asserts(void **state)
// Check xl is NULL
- expect_assert_failure(gf_mem_set_acct_info(NULL, &alloc_ptr, size, type));
+ expect_assert_failure(gf_mem_set_acct_info(NULL, &alloc_ptr, size, type, ""));
// Check xl->mem_acct.rec = NULL
- expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type));
+ expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
// Check type <= xl->mem_acct.num_types
type = 100;
- expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type));
+ expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, ""));
// Check alloc is NULL
- assert_int_equal(-1, gf_mem_set_acct_info(&xltest, NULL, size, type));
+ assert_int_equal(-1, gf_mem_set_acct_info(&xltest, NULL, size, type, ""));
// Initialize xl
xl = helper_xlator_init(10);
@@ -153,7 +153,7 @@ test_gf_mem_set_acct_info_asserts(void **state)
type = 100;
assert_true(NULL != xl->mem_acct.rec);
assert_true(type > xl->mem_acct.num_types);
- expect_assert_failure(gf_mem_set_acct_info(xl, &alloc_ptr, size, type));
+ expect_assert_failure(gf_mem_set_acct_info(xl, &alloc_ptr, size, type, ""));
helper_xlator_destroy(xl);
}
@@ -166,20 +166,23 @@ test_gf_mem_set_acct_info_memory(void **state)
char *temp_ptr;
size_t size;
uint32_t type;
+ const char *typestr = "TEST";
size = 8196;
type = 9;
// Initialize xl
xl = helper_xlator_init(10);
+ assert_null(xl->mem_acct.rec[type].typestr);
// Test allocation
temp_ptr = test_calloc(1, size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE);
assert_non_null(temp_ptr);
alloc_ptr = temp_ptr;
- gf_mem_set_acct_info(xl, &alloc_ptr, size, type);
+ gf_mem_set_acct_info(xl, &alloc_ptr, size, type, typestr);
//Check values
+ assert_ptr_equal(typestr, xl->mem_acct.rec[type].typestr);
assert_int_equal(xl->mem_acct.rec[type].size, size);
assert_int_equal(xl->mem_acct.rec[type].num_allocs, 1);
assert_int_equal(xl->mem_acct.rec[type].total_allocs, 1);
@@ -220,7 +223,7 @@ test_gf_calloc_default_calloc(void **state)
// Call __gf_calloc
size = 1024;
type = 3;
- mem = __gf_calloc(1, size, type);
+ mem = __gf_calloc(1, size, type, "3");
assert_non_null(mem);
memset(mem, 0x5A, size);
@@ -254,7 +257,7 @@ test_gf_calloc_mem_acct_enabled(void **state)
// Call __gf_calloc
size = 1024;
type = 3;
- mem = __gf_calloc(1, size, type);
+ mem = __gf_calloc(1, size, type, "3");
assert_non_null(mem);
memset(mem, 0x5A, size);
@@ -287,7 +290,7 @@ test_gf_malloc_default_malloc(void **state)
// Call __gf_malloc
size = 1024;
type = 3;
- mem = __gf_malloc(size, type);
+ mem = __gf_malloc(size, type, "3");
assert_non_null(mem);
memset(mem, 0x5A, size);
@@ -321,7 +324,7 @@ test_gf_malloc_mem_acct_enabled(void **state)
// Call __gf_malloc
size = 1024;
type = 3;
- mem = __gf_malloc(size, type);
+ mem = __gf_malloc(size, type, "3");
assert_non_null(mem);
memset(mem, 0x5A, size);
@@ -354,7 +357,7 @@ test_gf_realloc_default_realloc(void **state)
// Call __gf_malloc then realloc
size = 10;
type = 3;
- mem = __gf_malloc(size, type);
+ mem = __gf_malloc(size, type, "3");
assert_non_null(mem);
memset(mem, 0xA5, size);
@@ -393,7 +396,7 @@ test_gf_realloc_mem_acct_enabled(void **state)
// Call __gf_malloc then realloc
size = 1024;
type = 3;
- mem = __gf_malloc(size, type);
+ mem = __gf_malloc(size, type, "3");
assert_non_null(mem);
memset(mem, 0xA5, size);
diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am
index a180f9263ff..9b5d6897984 100644
--- a/xlators/cluster/dht/src/Makefile.am
+++ b/xlators/cluster/dht/src/Makefile.am
@@ -35,3 +35,17 @@ uninstall-local:
install-data-hook:
ln -sf dht.so $(DESTDIR)$(xlatordir)/distribute.so
+
+#### UNIT TESTS #####
+CLEANFILES += *.gcda *.gcno *_xunit.xml
+noinst_PROGRAMS =
+TESTS =
+
+dht_layout_unittest_CPPFLAGS = $(AM_CPPFLAGS)
+dht_layout_unittest_SOURCES = unittest/dht_layout_unittest.c \
+ unittest/dht_layout_mock.c \
+ dht-layout.c
+dht_layout_unittest_CFLAGS = $(UNITTEST_CFLAGS)
+dht_layout_unittest_LDFLAGS = $(UNITTEST_LDFLAGS)
+noinst_PROGRAMS += dht_layout_unittest
+TESTS += dht_layout_unittest
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
index 34892983a55..f39f5c1877f 100644
--- a/xlators/cluster/dht/src/dht-layout.c
+++ b/xlators/cluster/dht/src/dht-layout.c
@@ -27,12 +27,27 @@
#define layout_size(cnt) (layout_base_size + (cnt * layout_entry_size))
+#include <cmockery/pbc.h>
+#include <cmockery/cmockery_override.h>
+
+// Change GF_CALLOC and GF_FREE to use
+// cmockery2 memory allocation versions
+#ifdef UNIT_TESTING
+#undef GF_CALLOC
+#define GF_CALLOC(n, s, t) test_calloc(n, s)
+#undef GF_FREE
+#define GF_FREE test_free
+#endif
+
dht_layout_t *
dht_layout_new (xlator_t *this, int cnt)
{
dht_layout_t *layout = NULL;
dht_conf_t *conf = NULL;
+ REQUIRE(NULL != this);
+ REQUIRE(cnt >= 0);
+
conf = this->private;
layout = GF_CALLOC (1, layout_size (cnt),
@@ -51,6 +66,10 @@ dht_layout_new (xlator_t *this, int cnt)
layout->ref = 1;
+ ENSURE(NULL != layout);
+ ENSURE(layout->type == DHT_HASH_TYPE_DM);
+ ENSURE(layout->cnt == cnt);
+ ENSURE(layout->ref == 1);
out:
return layout;
}
diff --git a/xlators/cluster/dht/src/unittest/dht_layout_mock.c b/xlators/cluster/dht/src/unittest/dht_layout_mock.c
index aa19ddc575d..07c1e3249a8 100644
--- a/xlators/cluster/dht/src/unittest/dht_layout_mock.c
+++ b/xlators/cluster/dht/src/unittest/dht_layout_mock.c
@@ -61,3 +61,17 @@ int _gf_log_callingfn (const char *domain, const char *file,
{
return 0;
}
+
+void uuid_unparse(const uuid_t uu, char *out)
+{
+ // could call a will-return function here
+ // to place the correct data in *out
+}
+
+int
+_gf_msg (const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *fmt, ...)
+{
+ return 0;
+} \ No newline at end of file