diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2017-05-31 12:01:16 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2017-06-01 09:34:33 +1000 |
commit | 89ac7fd24be25191df6eb5d356a89701d1b5fc86 (patch) | |
tree | 6438e7db14039dd49e1ad854f21dfacad2db8836 /test | |
parent | f139d8fbc3041655518d55a4ff150264313bea06 (diff) |
test: make sure we search for event node, not the parent input device
This explains the heisenbugs when running the test suite. libevdev gives us
the syspath to the /sys/.../input123 node, not the one for the event node.
The device node path is created based on the sysfs tree, so there's a
window where the device node may not exist yet but we already returned the
device node path.
In litest, we're using a udev monitor to wait until the device is ready for
us, but the path interface only takes a device node path. So what happens is:
* libevdev gives us a syspath for the input node and a device path
* the monitor receives the input node udev device and matches the syspath
* we pass that up to the caller litest_add_device_with_overrides()
which opens the device node and adds it to libinput
* the path interface creates a udev device from the device node, which still
points to the old device node. Things fail because we don't have the device
we expect or it doesn't send events and eventually times out [1].
The errors triggered by this are either odd udev property mismatches or
timeouts because events are never processed.
This race is fixed by simply constructing the actual device node path we
expect from the udev device and waiting for the right device.
[1] We rely on the caller to notify us when to remove the device and thus
silently ignore ENODEV.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'test')
-rw-r--r-- | test/litest.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/test/litest.c b/test/litest.c index a099e1f..9fc1235 100644 --- a/test/litest.c +++ b/test/litest.c @@ -2721,6 +2721,7 @@ litest_create_uinput_device_from_description(const char *name, { struct libevdev_uinput *uinput; const char *syspath; + char path[PATH_MAX]; struct udev *udev; struct udev_monitor *udev_monitor; @@ -2744,6 +2745,7 @@ litest_create_uinput_device_from_description(const char *name, uinput = litest_create_uinput(name, id, abs_info, events); syspath = libevdev_uinput_get_syspath(uinput); + snprintf(path, sizeof(path), "%s/event", syspath); /* blocking, we don't want to continue until udev is ready */ while (1) { @@ -2756,7 +2758,7 @@ litest_create_uinput_device_from_description(const char *name, } udev_syspath = udev_device_get_syspath(udev_device); - if (udev_syspath && streq(udev_syspath, syspath)) + if (udev_syspath && strneq(udev_syspath, path, strlen(path))) break; udev_device_unref(udev_device); |