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;