test: Create convenience macros to declare tests

This commit is contained in:
Jan Janssen
2021-11-13 09:20:24 +09:00
committed by Yu Watanabe
parent c76a838589
commit 9cc6154608
2 changed files with 57 additions and 42 deletions
+47
View File
@@ -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(); \
}
+10 -42
View File
@@ -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;