diff options
author | Jan Janssen <medhefgo@web.de> | 2021-11-25 10:27:51 +0100 |
---|---|---|
committer | Jan Janssen <medhefgo@web.de> | 2021-11-28 11:40:45 +0100 |
commit | 4c0acc0761aae0370e20e118b9db3b704e9045cd (patch) | |
tree | 6708374e0bc2073bf15d3187e57004c8f020f8d3 /src/shared/tests.h | |
parent | 788e720181aead8c85ba30fc7ec9a1455a865cbe (diff) | |
download | systemd-4c0acc0761aae0370e20e118b9db3b704e9045cd.tar.gz |
test: Add TEST_RET macro
This declares a test function whose return code will be passed from
main(). The first test that does not return EXIT_SUCCESS wins.
Diffstat (limited to 'src/shared/tests.h')
-rw-r--r-- | src/shared/tests.h | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/src/shared/tests.h b/src/shared/tests.h index 872b9b2d6c..d1c96ef35b 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -46,46 +46,68 @@ bool can_memlock(void); const char *ci_environment(void); typedef struct TestFunc { - void (*f)(void); - const char * const n; + union f { + void (*void_func)(void); + int (*int_func)(void); + } f; + const char * const name; + bool has_ret; } 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), \ +#define REGISTER_TEST(func) \ + _section_("SYSTEMD_TEST_TABLE") _alignptr_ _used_ _variable_no_sanitize_address_ \ + static const TestFunc UNIQ_T(static_test_table_entry, UNIQ) = { \ + .f = (union f) &(func), \ + .name = STRINGIFY(func), \ + .has_ret = __builtin_types_compatible_p(typeof((union f){}.int_func), typeof(&(func))), \ } extern const TestFunc _weak_ __start_SYSTEMD_TEST_TABLE[]; extern const TestFunc _weak_ __stop_SYSTEMD_TEST_TABLE[]; -#define TEST(name) \ - REGISTER_TEST(test_##name); \ +#define TEST(name) \ + static void test_##name(void); \ + REGISTER_TEST(test_##name); \ static void test_##name(void) -static inline void run_test_table(void) { +#define TEST_RET(name) \ + static int test_##name(void); \ + REGISTER_TEST(test_##name); \ + static int test_##name(void) + +static inline int run_test_table(void) { + int r = EXIT_SUCCESS; + if (!__start_SYSTEMD_TEST_TABLE) - return; + return r; 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(); + log_info("/* %s */", t->name); + + if (t->has_ret) { + int r2 = t->f.int_func(); + if (r == EXIT_SUCCESS) + r = r2; + } else + t->f.void_func(); + t = ALIGN_TO_PTR(t + 1, sizeof(TestFunc*)); } + + return r; } #define DEFINE_CUSTOM_TEST_MAIN(log_level, intro, outro) \ int main(int argc, char *argv[]) { \ + int _r = EXIT_SUCCESS; \ test_setup_logging(log_level); \ save_argc_argv(argc, argv); \ intro; \ - run_test_table(); \ + _r = run_test_table(); \ outro; \ - return EXIT_SUCCESS; \ + return _r; \ } #define DEFINE_TEST_MAIN(log_level) DEFINE_CUSTOM_TEST_MAIN(log_level, , ) |