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 | 111 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 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..ca5aa1a --- /dev/null +++ b/tests/shared_ptr.c @@ -0,0 +1,111 @@ +#include <inttypes.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <pthread.h> +#include "cmocka-compat.h" +#include "util.h" + +#include "globals.c" + +struct s_8 { + uint64_t val; +}; + +struct s_4 { + uint32_t val; +}; + +struct s_2 { + uint16_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); \ + s->val++; \ + put_shared_ptr(s); \ + return NULL; \ +} + +make_fn(2) +make_fn(4) +make_fn(8) + +#define make_test(n, size) \ +make_destruct(n, size) \ + \ +static void test_ ## n ## _ ## size(void **state) \ +{ \ + pthread_t threads[n]; \ + struct s_##size *s; \ + int i, rc; \ + \ + 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], NULL, \ + thread_##size, s); \ + assert_int_equal(rc, 0); \ + } \ + for (i = 0; i < n; i++) { \ + rc = pthread_join(threads[i], NULL); \ + assert_int_equal(rc, 0); \ + } \ + assert_int_equal(s->val, n); \ + put_shared_ptr(s); \ +} + +make_test(0, 2) +make_test(0, 4) +make_test(0, 8) +make_test(100, 2) +make_test(100, 4) +make_test(100, 8) +make_test(1000, 2) +make_test(1000, 4) +make_test(1000, 8) + // clang-format on + + int test_shared_ptr(void) +{ + // clang-format off + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_0_2), + cmocka_unit_test(test_0_4), + cmocka_unit_test(test_0_8), + cmocka_unit_test(test_100_2), + cmocka_unit_test(test_100_4), + cmocka_unit_test(test_100_8), + cmocka_unit_test(test_1000_2), + cmocka_unit_test(test_1000_4), + cmocka_unit_test(test_1000_8), + }; + // 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
