test: Create convenience macros to declare tests
This commit is contained in:
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user