[PATCH v2 05/19] multipath-tools tests: add tests for shared pointer code

Martin Wilck <[email protected]>
Newsgroups dev.linux.lists.dm-devel
Message-ID <[email protected]>
Add a few tests (mostly meaningful with valgrind or ASAN) to test the
shared pointer code.

Signed-off-by: Martin Wilck <[email protected]>
---
 tests/Makefile     |   4 +-
 tests/shared_ptr.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 tests/shared_ptr.c

diff --git a/tests/Makefile b/tests/Makefile
index f0e5dd3..fc2a7ed 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -9,7 +9,8 @@ CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter -Wno-unused-function $(W_MISSING_I
 LIBDEPS += -L. -L $(mpathutildir) -L$(mpathcmddir) -lmultipath -lmpathutil -lmpathcmd -lcmocka
 
 TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \
-	 alias directio valid devt mpathvalid strbuf sysfs features cli mapinfo runner
+	 alias directio valid devt mpathvalid strbuf sysfs features cli mapinfo runner \
+	 shared_ptr
 HELPERS := test-lib.o test-log.o
 
 .PRECIOUS: $(TESTS:%=%-test)
@@ -66,6 +67,7 @@ features-test_OBJDEPS := $(mpathutildir)/mt-libudev.o
 cli-test_OBJDEPS := $(daemondir)/cli.o
 mapinfo-test_LIBDEPS = -lpthread -ldevmapper
 runner-test_LIBDEPS = -lpthread
+shared_ptr-test_LIBDEPS = -lpthread
 
 %.o: %.c
 	@echo building $@ because of $?
diff --git a/tests/shared_ptr.c b/tests/shared_ptr.c
new file mode 100644
index 0000000..2194ddd
--- /dev/null
+++ b/tests/shared_ptr.c
@@ -0,0 +1,120 @@
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <pthread.h>
+#include <urcu/uatomic.h>
+#include "cmocka-compat.h"
+#include "util.h"
+#include "globals.c"
+
+struct s_4 {
+	uint32_t val;
+};
+
+struct s_8 {
+	char pad[4];
+	uint32_t val;
+};
+
+struct s_64 {
+	char pad[60];
+	uint32_t val;
+};
+
+// clang-format off
+#define make_destruct(n, size)	     \
+static void destruct_ ## n ## _ ## size(void *ptr) \
+{						  \
+	struct s_##size *s = ptr;		  \
+						  \
+	assert_ptr_not_equal(ptr, NULL);	  \
+	assert_int_equal(s->val, n);		  \
+}
+
+#define make_fn(size) \
+static void *thread_##size(void *arg)		\
+{						\
+	struct s_##size *s = arg;		\
+						\
+	get_shared_ptr(s);			\
+	uatomic_add(&s->val, 1);		\
+	put_shared_ptr(s);			\
+	return NULL;				\
+}
+
+make_fn(4)
+make_fn(8)
+make_fn(64)
+
+#define make_test(n, size)					\
+make_destruct(n, size)						\
+								\
+static void test_ ## n ## _ ## size(void **state)		\
+{								\
+	pthread_attr_t attr;					\
+	pthread_t threads[n];					\
+	struct s_##size *s;					\
+	int i, rc;						\
+								\
+	rc = pthread_attr_init(&attr);				\
+	assert_int_equal(rc, 0);				\
+	rc = pthread_attr_setstacksize(&attr,			\
+			PTHREAD_STACK_MIN + 4096);		\
+	assert_int_equal(rc, 0);				\
+	s = alloc_shared_ptr(size, destruct_ ## n## _ ## size);	\
+	assert_ptr_not_equal(s, NULL);				\
+	s->val = 0;						\
+	for (i = 0; i < n; i++) {				\
+		rc = pthread_create(&threads[i], &attr,		\
+				    thread_##size, s);		\
+		assert_int_equal(rc, 0);			\
+	}							\
+	pthread_attr_destroy(&attr);				\
+	for (i = 0; i < n; i++) {				\
+		rc = pthread_join(threads[i], NULL);		\
+		assert_int_equal(rc, 0);			\
+	}							\
+	assert_int_equal(uatomic_read(&s->val), n);		\
+	put_shared_ptr(s);					\
+}
+
+make_test(0, 4)
+make_test(100, 4)
+make_test(1000, 4)
+make_test(0, 8)
+make_test(100, 8)
+make_test(1000, 8)
+make_test(0, 64)
+make_test(100, 64)
+make_test(1000, 64)
+	// clang-format on
+
+	int test_shared_ptr(void)
+{
+	// clang-format off
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(test_0_4),
+		cmocka_unit_test(test_100_4),
+		cmocka_unit_test(test_1000_4),
+		cmocka_unit_test(test_0_8),
+		cmocka_unit_test(test_100_8),
+		cmocka_unit_test(test_1000_8),
+		cmocka_unit_test(test_0_64),
+		cmocka_unit_test(test_100_64),
+		cmocka_unit_test(test_1000_64),
+	};
+	// clang-format on
+	return cmocka_run_group_tests(tests, NULL, NULL);
+}
+
+int main(void)
+{
+	int ret = 0;
+
+	init_test_verbosity(-1);
+	ret += test_shared_ptr();
+	return ret;
+}
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.