[PATCH v3 libinput 09/10] pad: Allow for a hook to test the sysfs path

Peter Hutterer peter.hutterer at who-t.net
Thu Jun 16 23:59:18 UTC 2016


If the LIBINPUT_TEST_TABLET_PAD_SYSFS_PATH udev property is set, use that as
sysfs base path. This enables us to re-create the expected sysfs struct in
some temporary folder during tests, thus allowing for tests of the mode
groups' correct behaviours.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v2:
- fix a memleak in the test devices, the custom teardown method also needs
  to free the litest device
- add a missing "\" in the udev rules for the pad devices

 doc/device-configuration-via-udev.dox  |  4 ++
 src/evdev-tablet-pad-leds.c            |  8 ++++
 test/litest-device-wacom-ekr.c         | 84 +++++++++++++++++++++++++++++++++-
 test/litest-device-wacom-intuos5-pad.c | 56 ++++++++++++++++++++++-
 test/litest-int.h                      |  5 ++
 test/litest.c                          |  7 +++
 test/litest.h                          |  3 ++
 7 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox
index 7987073..358c5cb 100644
--- a/doc/device-configuration-via-udev.dox
+++ b/doc/device-configuration-via-udev.dox
@@ -111,6 +111,10 @@ libinput reserves the property prefixes <b>LIBINPUT_MODEL_</b> and
 <b>LIBINPUT_ATTR_*</b> for model-specific configuration. <b>These prefixes
 are reserved as private API, do not use.</b>
 
+libinput reserves the property prefixes <b>LIBINPUT_TEST_</b>
+for settings only used during libinput's test suite. <b>This prefix
+is reserved as private API, do not use.</b>
+
 The effect of these properties may be to enable or disable certain
 features on a specific device or set of devices, to change configuration
 defaults or any other reason. The effects of setting these properties, the
diff --git a/src/evdev-tablet-pad-leds.c b/src/evdev-tablet-pad-leds.c
index 7136917..900f8bd 100644
--- a/src/evdev-tablet-pad-leds.c
+++ b/src/evdev-tablet-pad-leds.c
@@ -231,6 +231,14 @@ pad_get_hid_sysfs_base_path(struct evdev_device *device)
 {
 	struct udev_device *udev_device = device->udev_device,
 			   *hid_device;
+	const char *test_path;
+
+	/* For testing purposes only allow for a base path set through a
+	 * udev rule. We still expect the normal directory hierarchy inside */
+	test_path = udev_device_get_property_value(udev_device,
+				   "LIBINPUT_TEST_TABLET_PAD_SYSFS_PATH");
+	if (test_path)
+		return test_path;
 
 	hid_device = udev_device_get_parent_with_subsystem_devtype(udev_device,
 								   "hid",
diff --git a/test/litest-device-wacom-ekr.c b/test/litest-device-wacom-ekr.c
index fa73927..85569e4 100644
--- a/test/litest-device-wacom-ekr.c
+++ b/test/litest-device-wacom-ekr.c
@@ -24,16 +24,92 @@
 #include "config.h"
 #endif
 
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
 #include "litest.h"
 #include "litest-int.h"
+#include "libinput-util.h"
+
+#define SYSFS_LED_BASE "/tmp/wacom-ekr-leds"
+
+static inline void
+init_sysfs(void)
+{
+	int fd;
+	int rc;
+	char buf[] = "2\n";
+
+	rc = mkdir(SYSFS_LED_BASE, 0755);
+	if (rc != 0 && errno != EEXIST)
+		litest_assert_int_eq(rc, 0);
+	rc = mkdir(SYSFS_LED_BASE "/wacom_remote", 0755);
+	if (rc != 0 && errno != EEXIST)
+		litest_assert_int_eq(rc, 0);
+	rc = mkdir(SYSFS_LED_BASE "/wacom_remote/123456", 0755);
+	if (rc != 0 && errno != EEXIST)
+		litest_assert_int_eq(rc, 0);
+
+	fd = creat(SYSFS_LED_BASE "/wacom_remote/123456/remote_mode", O_WRONLY);
+	litest_assert_int_ge(fd, 0);
+	rc = write(fd, buf, sizeof(buf));
+	ck_assert_int_eq(rc, sizeof(buf));
+	close(fd);
+}
+
+static int
+toggle_mode(struct litest_device *d)
+{
+	int fd, rc;
+	char buf[3] = {0}; /* content: 2\n */
+	int mode;
+
+	fd = open(SYSFS_LED_BASE "/wacom_remote/123456/remote_mode", O_RDWR);
+	litest_assert_int_ge(fd, 0);
+	rc = read(fd, buf, sizeof(buf) - 1);
+	litest_assert_int_ne(rc, -1);
+
+	mode = buf[0] - '0';
+	litest_assert_int_le(mode, 2);
+	litest_assert_int_ge(mode, 0);
+
+	mode = (mode + 1) % 3; /* EKR has 3 modes */
+	buf[0] = '0' + mode;
+
+	rc = lseek(fd, 0, SEEK_SET);
+	litest_assert_int_ne(rc, -1);
+	rc = write(fd, buf, sizeof(buf));
+	litest_assert_int_ne(rc, -1);
+	close(fd);
+
+	return 0;
+}
 
 static void
 litest_wacom_ekr_setup(void)
 {
-	struct litest_device *d = litest_create_device(LITEST_WACOM_EKR);
+	struct litest_device *d;
+
+	init_sysfs();
+
+	d = litest_create_device(LITEST_WACOM_EKR);
+
 	litest_set_current_device(d);
 }
 
+static void
+litest_wacom_ekr_teardown(void)
+{
+	unlink(SYSFS_LED_BASE "/wacom_remote/123456/remote_mode");
+	rmdir(SYSFS_LED_BASE "/wacom_remote/123456");
+	rmdir(SYSFS_LED_BASE "/wacom_remote");
+	rmdir(SYSFS_LED_BASE);
+
+	litest_generic_device_teardown();
+}
+
 static struct input_event down[] = {
 	{ .type = -1, .code = -1 },
 };
@@ -68,6 +144,8 @@ static struct litest_device_interface interface = {
 	.pad_ring_start_events = ring_start,
 	.pad_ring_change_events = ring_change,
 	.pad_ring_end_events = ring_end,
+
+	.toggle_mode = toggle_mode,
 };
 
 static struct input_absinfo absinfo[] = {
@@ -113,7 +191,8 @@ static const char udev_rule[] =
 "KERNEL!=\"event*\", GOTO=\"pad_end\"\n"
 "\n"
 "ATTRS{name}==\"litest Wacom Express Key Remote Pad*\",\\\n"
-"    ENV{ID_INPUT_TABLET_PAD}=\"1\"\n"
+"    ENV{ID_INPUT_TABLET_PAD}=\"1\",\\\n"
+"    ENV{LIBINPUT_TEST_TABLET_PAD_SYSFS_PATH}=\"" SYSFS_LED_BASE "\"\n"
 "\n"
 "LABEL=\"pad_end\"";
 
@@ -122,6 +201,7 @@ struct litest_test_device litest_wacom_ekr_device = {
 	.features = LITEST_TABLET_PAD | LITEST_RING,
 	.shortname = "wacom-ekr",
 	.setup = litest_wacom_ekr_setup,
+	.teardown = litest_wacom_ekr_teardown,
 	.interface = &interface,
 
 	.name = "Wacom Express Key Remote Pad",
diff --git a/test/litest-device-wacom-intuos5-pad.c b/test/litest-device-wacom-intuos5-pad.c
index 7cff412..33b6d99 100644
--- a/test/litest-device-wacom-intuos5-pad.c
+++ b/test/litest-device-wacom-intuos5-pad.c
@@ -24,16 +24,66 @@
 #include "config.h"
 #endif
 
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
 #include "litest.h"
 #include "litest-int.h"
 
+#define SYSFS_LED_BASE "/tmp/wacom-intuos5-leds"
+
+static inline void
+init_sysfs(void)
+{
+	int fd;
+	int rc;
+	char buf[] = "2\n";
+
+	rc = mkdir(SYSFS_LED_BASE, 0755);
+	if (rc != 0 && errno != EEXIST)
+		litest_assert_int_eq(rc, 0);
+	rc = mkdir(SYSFS_LED_BASE "/wacom_led", 0755);
+	if (rc != 0 && errno != EEXIST)
+		litest_assert_int_eq(rc, 0);
+
+	fd = creat(SYSFS_LED_BASE "/wacom_led/status_led0_select", O_WRONLY);
+	litest_assert_int_ge(fd, 0);
+	rc = write(fd, buf, sizeof(buf));
+	ck_assert_int_eq(rc, sizeof(buf));
+	close(fd);
+
+	fd = creat(SYSFS_LED_BASE "/wacom_led/status0_luminance", O_WRONLY);
+	litest_assert_int_ge(fd, 0);
+	rc = write(fd, buf, sizeof(buf));
+	ck_assert_int_eq(rc, sizeof(buf));
+	close(fd);
+}
+
 static void
 litest_wacom_intuos5_pad_setup(void)
 {
-	struct litest_device *d = litest_create_device(LITEST_WACOM_INTUOS5_PAD);
+	struct litest_device *d;
+
+	init_sysfs();
+
+	d = litest_create_device(LITEST_WACOM_INTUOS5_PAD);
+
 	litest_set_current_device(d);
 }
 
+static void
+litest_wacom_intuos5_pad_teardown(void)
+{
+	unlink(SYSFS_LED_BASE "wacom_led/status_led0_select");
+	unlink(SYSFS_LED_BASE "wacom_led/status0_luminance");
+	rmdir(SYSFS_LED_BASE "wacom_led");
+	rmdir(SYSFS_LED_BASE);
+
+	litest_generic_device_teardown();
+}
+
 static struct input_event down[] = {
 	{ .type = -1, .code = -1 },
 };
@@ -103,7 +153,8 @@ static const char udev_rule[] =
 "KERNEL!=\"event*\", GOTO=\"pad_end\"\n"
 "\n"
 "ATTRS{name}==\"litest Wacom Intuos5 touch M Pad*\",\\\n"
-"    ENV{ID_INPUT_TABLET_PAD}=\"1\"\n"
+"    ENV{ID_INPUT_TABLET_PAD}=\"1\",\\\n"
+"    ENV{LIBINPUT_TEST_TABLET_PAD_SYSFS_PATH}=\"" SYSFS_LED_BASE "\"\n"
 "\n"
 "LABEL=\"pad_end\"";
 
@@ -112,6 +163,7 @@ struct litest_test_device litest_wacom_intuos5_pad_device = {
 	.features = LITEST_TABLET_PAD | LITEST_RING,
 	.shortname = "wacom-pad",
 	.setup = litest_wacom_intuos5_pad_setup,
+	.teardown = litest_wacom_intuos5_pad_teardown,
 	.interface = &interface,
 
 	.name = "Wacom Intuos5 touch M Pad",
diff --git a/test/litest-int.h b/test/litest-int.h
index 1a9060d..6ba985d 100644
--- a/test/litest-int.h
+++ b/test/litest-int.h
@@ -86,6 +86,11 @@ struct litest_device_interface {
 	int (*get_axis_default)(struct litest_device *d, unsigned int code, int32_t *value);
 
 	/**
+	 * Switch to the next mode
+	 */
+	int (*toggle_mode)(struct litest_device *d);
+
+	/**
 	 * Set of of events to execute on touch down, terminated by a .type
 	 * and .code value of -1. If the event value is LITEST_AUTO_ASSIGN,
 	 * it will be automatically assigned by the framework (valid for x,
diff --git a/test/litest.c b/test/litest.c
index abca666..749aa57 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -1953,6 +1953,13 @@ litest_pad_strip_end(struct litest_device *d)
 }
 
 void
+litest_pad_toggle_mode(struct litest_device *d)
+{
+	if (d->interface->toggle_mode)
+		d->interface->toggle_mode(d);
+}
+
+void
 litest_wait_for_event(struct libinput *li)
 {
 	return litest_wait_for_event_of_type(li, -1);
diff --git a/test/litest.h b/test/litest.h
index e990d9e..601096f 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -467,6 +467,9 @@ void
 litest_pad_strip_end(struct litest_device *d);
 
 void
+litest_pad_toggle_mode(struct litest_device *d);
+
+void
 litest_hover_start(struct litest_device *d,
 		   unsigned int slot,
 		   double x,
-- 
2.7.4



More information about the wayland-devel mailing list