test: always install our own udev rule/hwdb files for tests
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 5 Jun 2015 00:52:04 +0000 (10:52 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 11 Jun 2015 22:51:57 +0000 (08:51 +1000)
We can't rely on the system having these files installed, at least not in the
latest version that we'd like.
Copy them over from the source directory into the /run/ and /etc/ directories
for each test and update udev and the hwdb. This ensures the tags we set in
the hwdb file are always set, regardless of the system configuration.

Note that the /run/udev/* files need to have a different filename to the ones
we ship to avoid getting overridden by local configuration.

systemd does not have support for /run/udev/hwdb.d [1]. So our hwdb.d file
is in /etc/udev/hwdb.d instead and marked them with a REMOVEME and a comment
that if that file is left after the tests, it should be removed by the user.

[1] https://github.com/systemd/systemd/issues/127

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
test/Makefile.am
test/litest.c

index 6f2e6e45fd7108bd50a877222abb983ebf707526..2dfd5c1bb8e704ab7a860cd356665f002ad6b9cd 100644 (file)
@@ -38,7 +38,9 @@ liblitest_la_SOURCES = \
        litest-vmware-virtual-usb-mouse.c \
        litest.c
 liblitest_la_LIBADD = $(top_builddir)/src/libinput-util.la
-liblitest_la_CFLAGS = $(AM_CFLAGS)
+liblitest_la_CFLAGS = $(AM_CFLAGS) \
+             -DLIBINPUT_UDEV_RULES_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.rules\"" \
+             -DLIBINPUT_UDEV_HWDB_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.hwdb\""
 if HAVE_LIBUNWIND
 liblitest_la_LIBADD += $(LIBUNWIND_LIBS) -ldl
 liblitest_la_CFLAGS += $(LIBUNWIND_CFLAGS)
@@ -110,7 +112,7 @@ test_device_LDADD = $(TEST_LIBS)
 test_device_LDFLAGS = -no-install
 
 test_litest_selftest_SOURCES = litest-selftest.c litest.c litest-int.h litest.h
-test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN
+test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN $(liblitest_la_CFLAGS)
 test_litest_selftest_LDADD = $(TEST_LIBS)
 test_litest_selftest_LDFLAGS = -no-install
 if HAVE_LIBUNWIND
index 0e2cb967a8f2d5e1bcef02aa9736947915c46814..74d1292760809dafe91df595041e5b166e6a2f63 100644 (file)
@@ -40,6 +40,7 @@
 #include <unistd.h>
 #include "linux/input.h"
 #include <sys/ptrace.h>
+#include <sys/sendfile.h>
 #include <sys/timerfd.h>
 #include <sys/wait.h>
 
@@ -49,6 +50,9 @@
 
 #define UDEV_RULES_D "/run/udev/rules.d"
 #define UDEV_RULE_PREFIX "99-litest-"
+#define UDEV_HWDB_D "/etc/udev/hwdb.d"
+#define UDEV_COMMON_RULE_FILE UDEV_RULES_D "/91-litest-model-quirks.rules"
+#define UDEV_COMMON_HWDB_FILE UDEV_HWDB_D "/91-litest-model-quirks-REMOVEME.hwdb"
 
 static int in_debugger = -1;
 static int verbose = 0;
@@ -56,6 +60,8 @@ const char *filter_test = NULL;
 const char *filter_device = NULL;
 const char *filter_group = NULL;
 
+static inline void litest_remove_model_quirks(void);
+
 /* defined for the litest selftest */
 #ifndef LITEST_DISABLE_BACKTRACE_LOGGING
 #define litest_log(...) fprintf(stderr, __VA_ARGS__)
@@ -374,22 +380,34 @@ struct litest_test_device* devices[] = {
 
 static struct list all_tests;
 
-static void
-litest_reload_udev_rules(void)
+static inline void
+litest_system(const char *command)
 {
-       int ret = system("udevadm control --reload-rules");
+       int ret;
+
+       ret = system(command);
+
        if (ret == -1) {
-               litest_abort_msg("Failed to execute: udevadm");
+               litest_abort_msg("Failed to execute: %s", command);
        } else if (WIFEXITED(ret)) {
                if (WEXITSTATUS(ret))
-                       litest_abort_msg("udevadm failed with %d",
+                       litest_abort_msg("'%s' failed with %d",
+                                        command,
                                         WEXITSTATUS(ret));
        } else if (WIFSIGNALED(ret)) {
-               litest_abort_msg("udevadm terminated with signal %d",
+               litest_abort_msg("'%s' terminated with signal %d",
+                                command,
                                 WTERMSIG(ret));
        }
 }
 
+static void
+litest_reload_udev_rules(void)
+{
+       litest_system("udevadm control --reload-rules");
+       litest_system("udevadm hwdb --update");
+}
+
 static int
 litest_udev_rule_filter(const struct dirent *entry)
 {
@@ -430,6 +448,7 @@ litest_drop_udev_rules(void)
        }
        free(entries);
 
+       litest_remove_model_quirks();
        litest_reload_udev_rules();
 }
 
@@ -873,21 +892,70 @@ merge_events(const int *orig, const int *override)
        return events;
 }
 
+static inline void
+litest_copy_file(const char *dest, const char *src, const char *header)
+{
+       int in, out;
+
+       out = open(dest, O_CREAT|O_WRONLY, 0644);
+       litest_assert_int_gt(out, -1);
+
+       if (header)
+               write(out, header, strlen(header));
+
+       in = open(src, O_RDONLY);
+       litest_assert_int_gt(in, -1);
+       /* lazy, just check for error and empty file copy */
+       litest_assert_int_gt(sendfile(out, in, NULL, 4096), 0);
+       close(out);
+       close(in);
+}
+
+static inline void
+litest_install_model_quirks(void)
+{
+       litest_copy_file(UDEV_COMMON_RULE_FILE, LIBINPUT_UDEV_RULES_FILE, NULL);
+       litest_copy_file(UDEV_COMMON_HWDB_FILE,
+                        LIBINPUT_UDEV_HWDB_FILE,
+                        "#################################################################\n"
+                        "# WARNING: REMOVE THIS FILE\n"
+                        "# This is the run-time hwdb file for the libinput test suite and\n"
+                        "# should be removed on exit. If the test-suite is not currently \n"
+                        "# running, remove this file and update your hwdb: \n"
+                        "#       sudo udevadm hwdb --update\n"
+                        "#################################################################\n\n");
+}
+
+static inline void
+litest_remove_model_quirks(void)
+{
+       unlink(UDEV_COMMON_RULE_FILE);
+       unlink(UDEV_COMMON_HWDB_FILE);
+}
+
 static char *
 litest_init_udev_rules(struct litest_test_device *dev)
 {
        int rc;
        FILE *f;
-       char *path;
-
-       if (!dev->udev_rule)
-               return NULL;
+       char *path = NULL;
 
        rc = mkdir(UDEV_RULES_D, 0755);
        if (rc == -1 && errno != EEXIST)
                ck_abort_msg("Failed to create udev rules directory (%s)\n",
                             strerror(errno));
 
+       rc = mkdir(UDEV_HWDB_D, 0755);
+       if (rc == -1 && errno != EEXIST)
+               ck_abort_msg("Failed to create udev hwdb directory (%s)\n",
+                            strerror(errno));
+
+       litest_install_model_quirks();
+
+       /* device-specific udev rules */
+       if (!dev->udev_rule)
+               goto out;
+
        rc = xasprintf(&path,
                      "%s/%s%s.rules",
                      UDEV_RULES_D,
@@ -903,6 +971,7 @@ litest_init_udev_rules(struct litest_test_device *dev)
        litest_assert_int_ge(fputs(dev->udev_rule, f), 0);
        fclose(f);
 
+out:
        litest_reload_udev_rules();
 
        return path;
@@ -942,6 +1011,7 @@ litest_create(enum litest_device_type which,
        if ((*dev)->create) {
                (*dev)->create(d);
                if (abs_override || events_override) {
+                       litest_remove_model_quirks();
                        if (udev_file)
                                unlink(udev_file);
                        litest_abort_msg("Custom create cannot be overridden");
@@ -1120,6 +1190,7 @@ litest_delete_device(struct litest_device *d)
                return;
 
        if (d->udev_rule_file) {
+               litest_remove_model_quirks();
                unlink(d->udev_rule_file);
                free(d->udev_rule_file);
                d->udev_rule_file = NULL;