kselftest: create fixture objects
authorJakub Kicinski <kuba@kernel.org>
Tue, 28 Apr 2020 01:03:48 +0000 (18:03 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Apr 2020 20:30:43 +0000 (13:30 -0700)
Grouping tests by fixture will allow us to parametrize
test runs. Create full objects for fixtures.

Add a "global" fixture for tests without a fixture.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/selftests/kselftest_harness.h

index 77f7548..de283fd 100644 (file)
 #define __TEST_IMPL(test_name, _signal) \
        static void test_name(struct __test_metadata *_metadata); \
        static struct __test_metadata _##test_name##_object = \
-               { .name = "global." #test_name, \
-                 .fn = &test_name, .termsig = _signal, \
+               { .name = #test_name, \
+                 .fn = &test_name, \
+                 .fixture = &_fixture_global, \
+                 .termsig = _signal, \
                  .timeout = TEST_TIMEOUT_DEFAULT, }; \
        static void __attribute__((constructor)) _register_##test_name(void) \
        { \
  * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().
  */
 #define FIXTURE(fixture_name) \
+       static struct __fixture_metadata _##fixture_name##_fixture_object = \
+               { .name =  #fixture_name, }; \
        static void __attribute__((constructor)) \
        _register_##fixture_name##_data(void) \
        { \
-               __fixture_count++; \
+               __register_fixture(&_##fixture_name##_fixture_object); \
        } \
        FIXTURE_DATA(fixture_name)
 
        } \
        static struct __test_metadata \
                      _##fixture_name##_##test_name##_object = { \
-               .name = #fixture_name "." #test_name, \
+               .name = #test_name, \
                .fn = &wrapper_##fixture_name##_##test_name, \
+               .fixture = &_##fixture_name##_fixture_object, \
                .termsig = signal, \
                .timeout = tmout, \
         }; \
        } \
 }
 
+/* Contains all the information about a fixture. */
+struct __fixture_metadata {
+       const char *name;
+       struct __fixture_metadata *prev, *next;
+} _fixture_global __attribute__((unused)) = {
+       .name = "global",
+       .prev = &_fixture_global,
+};
+
+static struct __fixture_metadata *__fixture_list = &_fixture_global;
+static unsigned int __fixture_count;
+static int __constructor_order;
+
+#define _CONSTRUCTOR_ORDER_FORWARD   1
+#define _CONSTRUCTOR_ORDER_BACKWARD -1
+
+static inline void __register_fixture(struct __fixture_metadata *f)
+{
+       __fixture_count++;
+       __LIST_APPEND(__fixture_list, f);
+}
+
 /* Contains all the information for test execution and status checking. */
 struct __test_metadata {
        const char *name;
        void (*fn)(struct __test_metadata *);
        pid_t pid;      /* pid of test when being run */
+       struct __fixture_metadata *fixture;
        int termsig;
        int passed;
        int trigger; /* extra handler after the evaluation */
@@ -672,11 +700,6 @@ struct __test_metadata {
 /* Storage for the (global) tests to be run. */
 static struct __test_metadata *__test_list;
 static unsigned int __test_count;
-static unsigned int __fixture_count;
-static int __constructor_order;
-
-#define _CONSTRUCTOR_ORDER_FORWARD   1
-#define _CONSTRUCTOR_ORDER_BACKWARD -1
 
 /*
  * Since constructors are called in reverse order, reverse the test
@@ -796,11 +819,12 @@ void __wait_for_test(struct __test_metadata *t)
        }
 }
 
-void __run_test(struct __test_metadata *t)
+void __run_test(struct __fixture_metadata *f,
+               struct __test_metadata *t)
 {
        t->passed = 1;
        t->trigger = 0;
-       printf("[ RUN      ] %s\n", t->name);
+       printf("[ RUN      ] %s.%s\n", f->name, t->name);
        t->pid = fork();
        if (t->pid < 0) {
                printf("ERROR SPAWNING TEST CHILD\n");
@@ -812,7 +836,8 @@ void __run_test(struct __test_metadata *t)
        } else {
                __wait_for_test(t);
        }
-       printf("[     %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name);
+       printf("[     %4s ] %s.%s\n", (t->passed ? "OK" : "FAIL"),
+              f->name, t->name);
 }
 
 static int test_harness_run(int __attribute__((unused)) argc,
@@ -828,7 +853,7 @@ static int test_harness_run(int __attribute__((unused)) argc,
               __test_count, __fixture_count + 1);
        for (t = __test_list; t; t = t->next) {
                count++;
-               __run_test(t);
+               __run_test(t->fixture, t);
                if (t->passed)
                        pass_count++;
                else