From: Jan Janssen Date: Thu, 25 Nov 2021 09:27:51 +0000 (+0100) Subject: test: Add TEST_RET macro X-Git-Tag: v250-rc1~105^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4c0acc0761aae0370e20e118b9db3b704e9045cd;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/shared/tests.h b/src/shared/tests.h index 872b9b2d6c7..d1c96ef35b2 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, , )