test: add filtering to litest framework
authorPeter Hutterer <peter.hutterer@who-t.net>
Wed, 20 May 2015 00:12:39 +0000 (10:12 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 21 May 2015 22:45:35 +0000 (08:45 +1000)
Complementary to CK_RUN_SUITE and CK_RUN_CASE, this filters on actual test
function names with a simple fnmatch.

./test/test-touchpad --filter-test="*1fg_tap*"

Most of this patch is renaming litest_add_* to _litest_add_* so we can use the
macros to get at the function names.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
doc/test-suite.dox
test/litest.c
test/litest.h

index 5bcaee059878d1fd7bf817bce0dc37cf3dd8b37d..079018c0fc9992d6b474c5c9f05709a32d970443 100644 (file)
@@ -62,8 +62,12 @@ $ CK_RUN_CASE="wheel only" ./test/test-device
 $ CK_RUN_SUITE="device:wheel" CK_RUN_CASE="wheel only" ./test/test-device
 @endcode
 
-Check and litest currently do not provide a way to run a specific test
-function only.
+The `--filter-test` argument enables selective running of tests through
+basic shell-style function name matching. For example:
+
+@code
+$ ./test/test-touchpad --filter-test="*1fg_tap*"
+@endcode
 
 @section test-verbosity Controlling test output
 
index d5810185da32c862fa1cd950a7c50faa33096d43..fb0403db98c75c0d772b37047efa04ec3447fda0 100644 (file)
@@ -29,6 +29,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <getopt.h>
 #include <poll.h>
 #include <stdint.h>
@@ -50,6 +51,7 @@
 
 static int in_debugger = -1;
 static int verbose = 0;
+const char *filter_test = NULL;
 
 struct test {
        struct list node;
@@ -187,6 +189,7 @@ litest_drop_udev_rules(void)
 
 static void
 litest_add_tcase_for_device(struct suite *suite,
+                           const char *funcname,
                            void *func,
                            const struct litest_test_device *dev,
                            const struct range *range)
@@ -254,17 +257,50 @@ litest_add_tcase_no_device(struct suite *suite,
        suite_add_tcase(suite->suite, t->tc);
 }
 
+static struct suite *
+get_suite(const char *name)
+{
+       struct suite *s;
+
+       if (all_tests.next == NULL && all_tests.prev == NULL)
+               list_init(&all_tests);
+
+       list_for_each(s, &all_tests, node) {
+               if (strcmp(s->name, name) == 0)
+                       return s;
+       }
+
+       s = zalloc(sizeof(*s));
+       assert(s != NULL);
+       s->name = strdup(name);
+       s->suite = suite_create(s->name);
+
+       list_init(&s->tests);
+       list_insert(&all_tests, &s->node);
+
+       return s;
+}
+
 static void
-litest_add_tcase(struct suite *suite, void *func,
+litest_add_tcase(const char *suite_name,
+                const char *funcname,
+                void *func,
                 enum litest_device_feature required,
                 enum litest_device_feature excluded,
                 const struct range *range)
 {
        struct litest_test_device **dev = devices;
+       struct suite *suite;
 
        assert(required >= LITEST_DISABLE_DEVICE);
        assert(excluded >= LITEST_DISABLE_DEVICE);
 
+       if (filter_test &&
+           fnmatch(filter_test, funcname, 0) != 0)
+               return;
+
+       suite = get_suite(suite_name);
+
        if (required == LITEST_DISABLE_DEVICE &&
            excluded == LITEST_DISABLE_DEVICE) {
                litest_add_tcase_no_device(suite, func, range);
@@ -272,91 +308,86 @@ litest_add_tcase(struct suite *suite, void *func,
                while (*dev) {
                        if (((*dev)->features & required) == required &&
                            ((*dev)->features & excluded) == 0)
-                               litest_add_tcase_for_device(suite, func, *dev, range);
+                               litest_add_tcase_for_device(suite,
+                                                           funcname,
+                                                           func,
+                                                           *dev,
+                                                           range);
                        dev++;
                }
        } else {
                while (*dev) {
-                       litest_add_tcase_for_device(suite, func, *dev, range);
+                       litest_add_tcase_for_device(suite,
+                                                   funcname,
+                                                   func,
+                                                   *dev,
+                                                   range);
                        dev++;
                }
        }
 }
 
 void
-litest_add_no_device(const char *name, void *func)
+_litest_add_no_device(const char *name, const char *funcname, void *func)
 {
-       litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
+       _litest_add(name, funcname, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
 }
 
 void
-litest_add_ranged_no_device(const char *name,
-                           void *func,
-                           const struct range *range)
-{
-       litest_add_ranged(name,
-                         func,
-                         LITEST_DISABLE_DEVICE,
-                         LITEST_DISABLE_DEVICE,
-                         range);
-}
-
-static struct suite *
-get_suite(const char *name)
+_litest_add_ranged_no_device(const char *name,
+                            const char *funcname,
+                            void *func,
+                            const struct range *range)
 {
-       struct suite *s;
-
-       if (all_tests.next == NULL && all_tests.prev == NULL)
-               list_init(&all_tests);
-
-       list_for_each(s, &all_tests, node) {
-               if (strcmp(s->name, name) == 0)
-                       return s;
-       }
-
-       s = zalloc(sizeof(*s));
-       assert(s != NULL);
-       s->name = strdup(name);
-       s->suite = suite_create(s->name);
-
-       list_init(&s->tests);
-       list_insert(&all_tests, &s->node);
-
-       return s;
+       _litest_add_ranged(name,
+                          funcname,
+                          func,
+                          LITEST_DISABLE_DEVICE,
+                          LITEST_DISABLE_DEVICE,
+                          range);
 }
 
 void
-litest_add(const char *name,
-          void *func,
-          enum litest_device_feature required,
-          enum litest_device_feature excluded)
+_litest_add(const char *name,
+           const char *funcname,
+           void *func,
+           enum litest_device_feature required,
+           enum litest_device_feature excluded)
 {
-       litest_add_ranged(name, func, required, excluded, NULL);
+       _litest_add_ranged(name,
+                          funcname,
+                          func,
+                          required,
+                          excluded,
+                          NULL);
 }
 
 void
-litest_add_ranged(const char *name,
-                 void *func,
-                 enum litest_device_feature required,
-                 enum litest_device_feature excluded,
-                 const struct range *range)
+_litest_add_ranged(const char *name,
+                  const char *funcname,
+                  void *func,
+                  enum litest_device_feature required,
+                  enum litest_device_feature excluded,
+                  const struct range *range)
 {
-       litest_add_tcase(get_suite(name), func, required, excluded, range);
+       litest_add_tcase(name, funcname, func, required, excluded, range);
 }
 
 void
-litest_add_for_device(const char *name,
-                     void *func,
-                     enum litest_device_type type)
+_litest_add_for_device(const char *name,
+                      const char *funcname,
+                      void *func,
+                      enum litest_device_type type)
 {
-       litest_add_ranged_for_device(name, func, type, NULL);
+       _litest_add_ranged_for_device(name, funcname, func, type, NULL);
 }
 
 void
-litest_add_ranged_for_device(const char *name,
-                            void *func,
-                            enum litest_device_type type,
-                            const struct range *range)
+_litest_add_ranged_for_device(const char *name,
+                             const char *funcname,
+                             void *func,
+                             enum litest_device_type type,
+                             const struct range *range)
 {
        struct suite *s;
        struct litest_test_device **dev = devices;
@@ -366,7 +397,11 @@ litest_add_ranged_for_device(const char *name,
        s = get_suite(name);
        while (*dev) {
                if ((*dev)->type == type) {
-                       litest_add_tcase_for_device(s, func, *dev, range);
+                       litest_add_tcase_for_device(s,
+                                                   funcname,
+                                                   func,
+                                                   *dev,
+                                                   range);
                        return;
                }
                dev++;
@@ -1863,9 +1898,15 @@ litest_semi_mt_touch_up(struct litest_device *d,
 static int
 litest_parse_argv(int argc, char **argv)
 {
+       enum {
+               OPT_FILTER_TEST,
+               OPT_LIST,
+               OPT_VERBOSE,
+       };
        static const struct option opts[] = {
-               { "list", 0, 0, 'l' },
-               { "verbose", 0, 0, 'v' },
+               { "filter-test", 1, 0, OPT_FILTER_TEST },
+               { "list", 0, 0, OPT_LIST },
+               { "verbose", 0, 0, OPT_VERBOSE },
                { 0, 0, 0, 0}
        };
 
@@ -1877,10 +1918,13 @@ litest_parse_argv(int argc, char **argv)
                if (c == -1)
                        break;
                switch(c) {
-               case 'l':
+               case OPT_FILTER_TEST:
+                       filter_test = optarg;
+                       break;
+               case OPT_LIST:
                        litest_list_tests(&all_tests);
                        exit(0);
-               case 'v':
+               case OPT_VERBOSE:
                        verbose = 1;
                        break;
                default:
index b6aaa6f5d0532dadca2c01bdac7d1b92ecca9348..47bbe544bf213acca88db7fb1a4486597878bf44 100644 (file)
@@ -109,26 +109,45 @@ struct libinput *litest_create_context(void);
 void litest_disable_log_handler(struct libinput *libinput);
 void litest_restore_log_handler(struct libinput *libinput);
 
-void litest_add(const char *name, void *func,
-               enum litest_device_feature required_feature,
-               enum litest_device_feature excluded_feature);
-void litest_add_ranged(const char *name,
-                      void *func,
-                      enum litest_device_feature required,
-                      enum litest_device_feature excluded,
-                      const struct range *range);
-void
-litest_add_for_device(const char *name,
-                     void *func,
-                     enum litest_device_type type);
-void litest_add_ranged_for_device(const char *name,
+#define litest_add(name_, func_, ...) \
+       _litest_add(name_, #func_, func_, __VA_ARGS__)
+#define litest_add_ranged(name_, func_, ...) \
+       _litest_add_ranged(name_, #func_, func_, __VA_ARGS__)
+#define litest_add_for_device(name_, func_, ...) \
+       _litest_add_for_device(name_, #func_, func_, __VA_ARGS__)
+#define litest_add_ranged_for_device(name_, func_, ...) \
+       _litest_add_ranged_for_device(name_, #func_, func_, __VA_ARGS__)
+#define litest_add_no_device(name_, func_) \
+       _litest_add_no_device(name_, #func_, func_)
+#define litest_add_ranged_no_device(name_, func_, ...) \
+       _litest_add_ranged_no_device(name_, #func_, func_, __VA_ARGS__)
+void _litest_add(const char *name,
+                const char *funcname,
+                void *func,
+                enum litest_device_feature required_feature,
+                enum litest_device_feature excluded_feature);
+void _litest_add_ranged(const char *name,
+                       const char *funcname,
+                       void *func,
+                       enum litest_device_feature required,
+                       enum litest_device_feature excluded,
+                       const struct range *range);
+void _litest_add_for_device(const char *name,
+                           const char *funcname,
+                           void *func,
+                           enum litest_device_type type);
+void _litest_add_ranged_for_device(const char *name,
+                                  const char *funcname,
+                                  void *func,
+                                  enum litest_device_type type,
+                                  const struct range *range);
+void _litest_add_no_device(const char *name,
+                          const char *funcname,
+                          void *func);
+void _litest_add_ranged_no_device(const char *name,
+                                 const char *funcname,
                                  void *func,
-                                 enum litest_device_type type,
                                  const struct range *range);
-void litest_add_no_device(const char *name, void *func);
-void litest_add_ranged_no_device(const char *name,
-                                void *func,
-                                const struct range *range);
 
 extern void litest_setup_tests(void);
 struct litest_device * litest_create_device(enum litest_device_type which);