]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
testsuite: use a section to put tests in instead of array
authorLucas De Marchi <lucas.demarchi@intel.com>
Thu, 9 Oct 2014 17:14:58 +0000 (14:14 -0300)
committerLucas De Marchi <lucas.demarchi@intel.com>
Thu, 9 Oct 2014 17:17:24 +0000 (14:17 -0300)
Intead of having to declare an array of tests, tweak the definition of
DEFINE_TEST and TESTSUITE_MAIN so they know the tests are put in a
particular section of the ELF file.

This avoids the mistake of adding a test and forgetting to add it to the
array. Now once a test is defined, it's ready to run, so one less step
to define new tests.

The removal of the arrays is left for another patch so not to clutter
the diff on this one.

testsuite/testsuite.c
testsuite/testsuite.h

index c7843748f551d47f28cfdff7af9d25c3f12da699..397e28b1312e65bc312400b0e81f7bf717b15a7e 100644 (file)
@@ -88,16 +88,17 @@ static void help(void)
                printf("\t-%c, --%s\n", *itr_short, itr->name);
 }
 
-static void test_list(const struct test *tests[])
+static void test_list(const struct test *start, const struct test *stop)
 {
-       size_t i;
+       const struct test *t;
 
        printf("Available tests:\n");
-       for (i = 0; tests[i] != NULL; i++)
-               printf("\t%s, %s\n", tests[i]->name, tests[i]->description);
+       for (t = start; t < stop; t++)
+               printf("\t%s, %s\n", t->name, t->description);
 }
 
-int test_init(int argc, char *const argv[], const struct test *tests[])
+int test_init(const struct test *start, const struct test *stop,
+             int argc, char *const argv[])
 {
        progname = argv[0];
 
@@ -108,7 +109,7 @@ int test_init(int argc, char *const argv[], const struct test *tests[])
                        break;
                switch (c) {
                case 'l':
-                       test_list(tests);
+                       test_list(start, stop);
                        return 0;
                case 'h':
                        help();
@@ -133,13 +134,14 @@ int test_init(int argc, char *const argv[], const struct test *tests[])
        return optind;
 }
 
-const struct test *test_find(const struct test *tests[], const char *name)
+const struct test *test_find(const struct test *start,
+                            const struct test *stop, const char *name)
 {
-       size_t i;
+       const struct test *t;
 
-       for (i = 0; tests[i] != NULL; i++) {
-               if (strcmp(tests[i]->name, name) == 0)
-                       return tests[i];
+       for (t = start; t < stop; t++) {
+               if (strcmp(t->name, name) == 0)
+                       return t;
        }
 
        return NULL;
index ea40e8f48a20bfa4b7e389d658171454d106f17f..f9a6e91550fc42598ef7e022e5400ec48a79da21 100644 (file)
@@ -103,13 +103,14 @@ struct test {
        const struct keyval *env_vars;
        bool need_spawn;
        bool expected_fail;
-};
+} __attribute__((aligned(8)));
 
 
-const struct test *test_find(const struct test *tests[], const char *name);
-int test_init(int argc, char *const argv[], const struct test *tests[]);
+int test_init(const struct test *start, const struct test *stop,
+             int argc, char *const argv[]);
+const struct test *test_find(const struct test *start, const struct test *stop,
+                            const char *name);
 int test_spawn_prog(const char *prog, const char *const args[]);
-
 int test_run(const struct test *t);
 
 #define TS_EXPORT __attribute__ ((visibility("default")))
@@ -122,7 +123,7 @@ int test_run(const struct test *t);
 #define assert_return(expr, r)                                         \
        do {                                                            \
                if ((!(expr))) {                                        \
-                       ERR("Failed assertion: " #expr "%s:%d %s",                      \
+                       ERR("Failed assertion: " #expr "%s:%d %s",      \
                            __FILE__, __LINE__, __PRETTY_FUNCTION__);   \
                        return (r);                                     \
                }                                                       \
@@ -131,40 +132,42 @@ int test_run(const struct test *t);
 
 /* Test definitions */
 #define DEFINE_TEST(_name, ...) \
-       static const struct test s##_name = { \
+       static const struct test s##_name \
+       __attribute__((used, section("kmod_tests"), aligned(8))) = { \
                .name = #_name, \
                .func = _name, \
                ## __VA_ARGS__ \
-       }
+       };
 
 #define TESTSUITE_MAIN(_tests) \
-       int main(int argc, char *argv[])                        \
-       {                                                       \
-               const struct test *t;                           \
-               int arg;                                        \
-               size_t i;                                       \
-                                                               \
-               arg = test_init(argc, argv, tests);             \
-               if (arg == 0)                                   \
-                       return 0;                               \
-                                                               \
-               if (arg < argc) {                               \
-                       t = test_find(tests, argv[arg]);        \
-                       if (t == NULL) {                        \
-                               fprintf(stderr, "could not find test %s\n", argv[arg]);\
-                               exit(EXIT_FAILURE);             \
-                       }                                       \
-                                                               \
-                       return test_run(t);                     \
-               }                                               \
-                                                               \
-               for (i = 0; tests[i] != NULL; i++) {            \
-                       if (test_run(tests[i]) != 0)            \
-                               exit(EXIT_FAILURE);             \
-               }                                               \
-                                                               \
-               exit(EXIT_SUCCESS);                             \
-       }                                                       \
+       extern struct test __start_kmod_tests[] __attribute__((weak, visibility("hidden")));    \
+       extern struct test __stop_kmod_tests[] __attribute__((weak, visibility("hidden")));     \
+       int main(int argc, char *argv[])                                                        \
+       {                                                                                       \
+               const struct test *t;                                                           \
+               int arg;                                                                        \
+                                                                                               \
+               arg = test_init(__start_kmod_tests, __stop_kmod_tests, argc, argv);             \
+               if (arg == 0)                                                                   \
+                       return 0;                                                               \
+                                                                                               \
+               if (arg < argc) {                                                               \
+                       t = test_find(__start_kmod_tests, __stop_kmod_tests, argv[arg]);        \
+                       if (t == NULL) {                                                        \
+                               fprintf(stderr, "could not find test %s\n", argv[arg]);         \
+                               exit(EXIT_FAILURE);                                             \
+                       }                                                                       \
+                                                                                               \
+                       return test_run(t);                                                     \
+               }                                                                               \
+                                                                                               \
+               for (t = __start_kmod_tests; t < __stop_kmod_tests; t++) {                      \
+                       if (test_run(t) != 0)                                                   \
+                               exit(EXIT_FAILURE);                                             \
+               }                                                                               \
+                                                                                               \
+               exit(EXIT_SUCCESS);                                                             \
+       }                                                                                       \
 
 #ifdef noreturn
 # define __noreturn noreturn