1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-08 21:17:47 +03:00

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.
This commit is contained in:
Jan Janssen 2021-11-25 10:27:51 +01:00
parent 788e720181
commit 4c0acc0761

View File

@ -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, , )