summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Janssen <medhefgo@web.de>2021-11-12 10:54:44 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-11-13 09:20:24 +0900
commit9cc615460830afdb51ad23e594906bbe60a3b25a (patch)
tree4b3e172635102265f534b864d0079dc4b73a663b /src
parentc76a83858996148fea36d1018b4707ce5334363b (diff)
downloadsystemd-9cc615460830afdb51ad23e594906bbe60a3b25a.tar.gz
test: Create convenience macros to declare tests
Diffstat (limited to 'src')
-rw-r--r--src/shared/tests.h47
-rw-r--r--src/test/test-macro.c52
2 files changed, 57 insertions, 42 deletions
diff --git a/src/shared/tests.h b/src/shared/tests.h
index c1350763ad..f333ebd842 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -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(); \
+ }
diff --git a/src/test/test-macro.c b/src/test/test-macro.c
index 6db06d80c6..09cb4bf7bc 100644
--- a/src/test/test-macro.c
+++ b/src/test/test-macro.c
@@ -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;