From 96face60c2e04d6f6739de7456d604d9f4763728 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 5 Jun 2015 10:52:04 +1000 Subject: [PATCH] test: always install our own udev rule/hwdb files for tests 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 Reviewed-by: Hans de Goede --- test/Makefile.am | 6 ++- test/litest.c | 101 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 6f2e6e45..2dfd5c1b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 diff --git a/test/litest.c b/test/litest.c index 0e2cb967..74d12927 100644 --- a/test/litest.c +++ b/test/litest.c @@ -40,6 +40,7 @@ #include #include "linux/input.h" #include +#include #include #include @@ -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,20 +380,32 @@ struct litest_test_device* devices[] = { static struct list all_tests; +static inline void +litest_system(const char *command) +{ + int ret; + + ret = system(command); + + if (ret == -1) { + litest_abort_msg("Failed to execute: %s", command); + } else if (WIFEXITED(ret)) { + if (WEXITSTATUS(ret)) + litest_abort_msg("'%s' failed with %d", + command, + WEXITSTATUS(ret)); + } else if (WIFSIGNALED(ret)) { + litest_abort_msg("'%s' terminated with signal %d", + command, + WTERMSIG(ret)); + } +} + static void litest_reload_udev_rules(void) { - int ret = system("udevadm control --reload-rules"); - if (ret == -1) { - litest_abort_msg("Failed to execute: udevadm"); - } else if (WIFEXITED(ret)) { - if (WEXITSTATUS(ret)) - litest_abort_msg("udevadm failed with %d", - WEXITSTATUS(ret)); - } else if (WIFSIGNALED(ret)) { - litest_abort_msg("udevadm terminated with signal %d", - WTERMSIG(ret)); - } + litest_system("udevadm control --reload-rules"); + litest_system("udevadm hwdb --update"); } static int @@ -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;