diff options
author | Jan Janssen <medhefgo@web.de> | 2021-11-12 10:54:44 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-11-13 09:20:24 +0900 |
commit | 9cc615460830afdb51ad23e594906bbe60a3b25a (patch) | |
tree | 4b3e172635102265f534b864d0079dc4b73a663b /src | |
parent | c76a83858996148fea36d1018b4707ce5334363b (diff) | |
download | systemd-9cc615460830afdb51ad23e594906bbe60a3b25a.tar.gz |
test: Create convenience macros to declare tests
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/tests.h | 47 | ||||
-rw-r--r-- | src/test/test-macro.c | 52 |
2 files changed, 57 insertions, 42 deletions
diff --git a/src/shared/tests.h b/src/shared/tests.h index c1350763ad..f333ebd842 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -43,3 +43,50 @@ bool can_memlock(void); /* Provide a convenient way to check if we're running in CI. */ const char *ci_environment(void); + +typedef struct TestFunc { + void (*f)(void); + const char * const n; +} TestFunc; + +/* See static-destruct.h for an explanation of how this works. */ +#define REGISTER_TEST(func) \ + static void func(void); \ + _section_("SYSTEMD_TEST_TABLE") _alignptr_ _used_ _variable_no_sanitize_address_ \ + static const TestFunc UNIQ_T(static_test_table_entry, UNIQ) = { \ + .f = &(func), \ + .n = STRINGIFY(func), \ + } + +extern const TestFunc _weak_ __start_SYSTEMD_TEST_TABLE[]; +extern const TestFunc _weak_ __stop_SYSTEMD_TEST_TABLE[]; + +#define TEST(name) \ + REGISTER_TEST(test_##name); \ + static void test_##name(void) + +static inline void run_test_table(void) { + if (!__start_SYSTEMD_TEST_TABLE) + return; + + const TestFunc *t = ALIGN_TO_PTR(__start_SYSTEMD_TEST_TABLE, sizeof(TestFunc*)); + while (t < __stop_SYSTEMD_TEST_TABLE) { + log_info("/* %s */", t->n); + t->f(); + t = ALIGN_TO_PTR(t + 1, sizeof(TestFunc*)); + } +} + +#define DEFINE_TEST_MAIN \ + int main(int argc, char *argv[]) { \ + test_setup_logging(LOG_INFO); \ + run_test_table(); \ + return EXIT_SUCCESS; \ + } + +#define DEFINE_CUSTOM_TEST_MAIN(impl) \ + int main(int argc, char *argv[]) { \ + test_setup_logging(LOG_INFO); \ + run_test_table(); \ + return impl(); \ + } diff --git a/src/test/test-macro.c b/src/test/test-macro.c index 6db06d80c6..09cb4bf7bc 100644 --- a/src/test/test-macro.c +++ b/src/test/test-macro.c @@ -6,11 +6,9 @@ #include "macro.h" #include "tests.h" -static void test_align_power2(void) { +TEST(align_power2) { unsigned long i, p2; - log_info("/* %s */", __func__); - assert_se(ALIGN_POWER2(0) == 0); assert_se(ALIGN_POWER2(1) == 1); assert_se(ALIGN_POWER2(2) == 2); @@ -50,7 +48,7 @@ static void test_align_power2(void) { } } -static void test_max(void) { +TEST(max) { static const struct { int a; int b[CONST_MAX(10, 100)]; @@ -65,8 +63,6 @@ static void test_max(void) { void *p = (void *)str; void *q = (void *)&str[16]; - log_info("/* %s */", __func__); - assert_cc(sizeof(val1.b) == sizeof(int) * 100); /* CONST_MAX returns (void) instead of a value if the passed arguments @@ -134,7 +130,7 @@ static void test_max(void) { # pragma GCC diagnostic ignored "-Waddress-of-packed-member" #endif -static void test_container_of(void) { +TEST(container_of) { struct mytype { uint8_t pad1[3]; uint64_t v1; @@ -142,8 +138,6 @@ static void test_container_of(void) { uint32_t v2; } myval = { }; - log_info("/* %s */", __func__); - assert_cc(sizeof(myval) >= 17); assert_se(container_of(&myval.v1, struct mytype, v1) == &myval); assert_se(container_of(&myval.v2, struct mytype, v2) == &myval); @@ -156,11 +150,9 @@ static void test_container_of(void) { #pragma GCC diagnostic pop -static void test_div_round_up(void) { +TEST(div_round_up) { int div; - log_info("/* %s */", __func__); - /* basic tests */ assert_se(DIV_ROUND_UP(0, 8) == 0); assert_se(DIV_ROUND_UP(1, 8) == 1); @@ -191,9 +183,7 @@ static void test_div_round_up(void) { assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U); } -static void test_ptr_to_int(void) { - log_info("/* %s */", __func__); - +TEST(ptr_to_int) { /* Primary reason to have this test is to validate that pointers are large enough to hold entire int range */ assert_se(PTR_TO_INT(INT_TO_PTR(0)) == 0); assert_se(PTR_TO_INT(INT_TO_PTR(1)) == 1); @@ -202,9 +192,7 @@ static void test_ptr_to_int(void) { assert_se(PTR_TO_INT(INT_TO_PTR(INT_MIN)) == INT_MIN); } -static void test_in_set(void) { - log_info("/* %s */", __func__); - +TEST(in_set) { assert_se(IN_SET(1, 1)); assert_se(IN_SET(1, 1, 2, 3, 4)); assert_se(IN_SET(2, 1, 2, 3, 4)); @@ -214,12 +202,10 @@ static void test_in_set(void) { assert_se(!IN_SET(0, 1, 2, 3, 4)); } -static void test_foreach_pointer(void) { +TEST(foreach_pointer) { int a, b, c, *i; size_t k = 0; - log_info("/* %s */", __func__); - FOREACH_POINTER(i, &a, &b, &c) { switch (k) { @@ -295,9 +281,7 @@ static void test_foreach_pointer(void) { assert_se(k == 11); } -static void test_align_to(void) { - log_info("/* %s */", __func__); - +TEST(align_to) { assert_se(ALIGN_TO(0, 1) == 0); assert_se(ALIGN_TO(1, 1) == 1); assert_se(ALIGN_TO(2, 1) == 2); @@ -336,7 +320,7 @@ static void test_align_to(void) { assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(SIZE_MAX, 512)), void)); } -static void test_flags(void) { +TEST(flags) { enum { F1 = 1 << 0, F2 = 1 << 1, @@ -345,8 +329,6 @@ static void test_flags(void) { }; unsigned n, f; - log_info("/* %s */", __func__); - assert_se(FLAGS_SET(0, 0)); assert_se(FLAGS_SET(F1, F1)); assert_se(FLAGS_SET(F1 | F2, F1)); @@ -405,18 +387,4 @@ static void test_flags(void) { assert_se(f == F2); } -int main(int argc, char *argv[]) { - test_setup_logging(LOG_INFO); - - test_align_power2(); - test_max(); - test_container_of(); - test_div_round_up(); - test_in_set(); - test_foreach_pointer(); - test_ptr_to_int(); - test_align_to(); - test_flags(); - - return 0; -} +DEFINE_TEST_MAIN; |