]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: Add TEST_RET macro
authorJan Janssen <medhefgo@web.de>
Thu, 25 Nov 2021 09:27:51 +0000 (10:27 +0100)
committerJan Janssen <medhefgo@web.de>
Sun, 28 Nov 2021 10:40:45 +0000 (11:40 +0100)
This declares a test function whose return code will be passed from
main(). The first test that does not return EXIT_SUCCESS wins.

src/shared/tests.h

index 872b9b2d6c776bdae72d2e356da0667724c68742..d1c96ef35b2cb99d2995821d150e40f552719ec3 100644 (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, , )