[PATCH libinput 3/9] test: Add seat slot tests

Peter Hutterer peter.hutterer at who-t.net
Wed Apr 9 22:48:40 PDT 2014


On Wed, Apr 09, 2014 at 09:02:10PM +0200, Jonas Ådahl wrote:
> Add one test that checks uniqueness of seat slots when having multiple
> devices with active touch points.
> 
> Add one test that checks that libinput drops touch points when it could
> not represent them with a seat wide slot.
> 
> This commit also adds support for from a test case add test devices to
> an existing libinput context. Only litest-genric-highres-touch supports
> this so far and only generic artificial test devices should, in order to
> keep emulated devices closer to their originals.
> 
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> ---
>  test/litest.c |  45 ++++++++++++---
>  test/litest.h |  16 +++++
>  test/touch.c  | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 235 insertions(+), 9 deletions(-)
> 
> diff --git a/test/litest.c b/test/litest.c
> index af7fd39..495871c 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -451,12 +451,22 @@ litest_create(enum litest_device_type which,
>  
>  }
>  
> +struct libinput *
> +litest_create_context(void)
> +{
> +	struct libinput *libinput =
> +		libinput_path_create_context(&interface, NULL);
> +	ck_assert_notnull(libinput);
> +	return libinput;
> +}
> +
>  struct litest_device *
> -litest_create_device_with_overrides(enum litest_device_type which,
> -				    const char *name_override,
> -				    struct input_id *id_override,
> -				    const struct input_absinfo *abs_override,
> -				    const int *events_override)
> +litest_add_device_with_overrides(struct libinput *libinput,
> +				 enum litest_device_type which,
> +				 const char *name_override,
> +				 struct input_id *id_override,
> +				 const struct input_absinfo *abs_override,
> +				 const int *events_override)
>  {
>  	struct litest_device *d;
>  	int fd;
> @@ -477,9 +487,7 @@ litest_create_device_with_overrides(enum litest_device_type which,
>  	rc = libevdev_new_from_fd(fd, &d->evdev);
>  	ck_assert_int_eq(rc, 0);
>  
> -	d->libinput = libinput_path_create_context(&interface, NULL);
> -	ck_assert(d->libinput != NULL);
> -
> +	d->libinput = libinput;
>  	d->libinput_device = libinput_path_add_device(d->libinput, path);
>  	ck_assert(d->libinput_device != NULL);
>  	libinput_device_ref(d->libinput_device);
> @@ -494,6 +502,24 @@ litest_create_device_with_overrides(enum litest_device_type which,
>  }
>  
>  struct litest_device *
> +litest_create_device_with_overrides(enum litest_device_type which,
> +				    const char *name_override,
> +				    struct input_id *id_override,
> +				    const struct input_absinfo *abs_override,
> +				    const int *events_override)
> +{
> +	struct litest_device *dev =
> +		litest_add_device_with_overrides(litest_create_context(),
> +						 which,
> +						 name_override,
> +						 id_override,
> +						 abs_override,
> +						 events_override);
> +	dev->owns_context = true;
> +	return dev;
> +}
> +
> +struct litest_device *
>  litest_create_device(enum litest_device_type which)
>  {
>  	return litest_create_device_with_overrides(which, NULL, NULL, NULL, NULL);
> @@ -520,7 +546,8 @@ litest_delete_device(struct litest_device *d)
>  		return;
>  
>  	libinput_device_unref(d->libinput_device);
> -	libinput_destroy(d->libinput);
> +	if (d->owns_context)
> +		libinput_destroy(d->libinput);
>  	libevdev_free(d->evdev);
>  	libevdev_uinput_destroy(d->uinput);
>  	memset(d,0, sizeof(*d));
> diff --git a/test/litest.h b/test/litest.h
> index 85748cc..1533287 100644
> --- a/test/litest.h
> +++ b/test/litest.h
> @@ -61,10 +61,14 @@ struct litest_device {
>  	struct libevdev *evdev;
>  	struct libevdev_uinput *uinput;
>  	struct libinput *libinput;
> +	bool owns_context;
>  	struct libinput_device *libinput_device;
>  	struct litest_device_interface *interface;
> +	int device_id;

device_id doesn't seem to be used anywhere 

>  };
>  
> +struct libinput *litest_create_context(void);
> +
>  void litest_add(const char *name, void *func,
>  		enum litest_device_feature required_feature,
>  		enum litest_device_feature excluded_feature);
> @@ -83,6 +87,14 @@ litest_create_device_with_overrides(enum litest_device_type which,
>  				    struct input_id *id_override,
>  				    const struct input_absinfo *abs_override,
>  				    const int *events_override);
> +struct litest_device *
> +litest_add_device_with_overrides(struct libinput *libinput,
> +				 enum litest_device_type which,
> +				 const char *name_override,
> +				 struct input_id *id_override,
> +				 const struct input_absinfo *abs_override,
> +				 const int *events_override);
> +
>  struct litest_device *litest_current_device(void);
>  void litest_delete_device(struct litest_device *d);
>  int litest_handle_events(struct litest_device *d);
> @@ -118,4 +130,8 @@ struct libevdev_uinput * litest_create_uinput_abs_device(const char *name,
>  							 const struct input_absinfo *abs,
>  							 ...);
>  
> +#ifndef ck_assert_notnull
> +#define ck_assert_notnull(ptr) ck_assert_ptr_ne(ptr, NULL)
> +#endif

heh, see my comment last time this came up: isn't a simple
ck_assert(ptr != NULL) enough?

> +
>  #endif /* LITEST_H */
> diff --git a/test/touch.c b/test/touch.c
> index 27ed881..e1a8146 100644
> --- a/test/touch.c
> +++ b/test/touch.c
> @@ -22,6 +22,7 @@
>  
>  #include <config.h>
>  
> +#include <stdio.h>
>  #include <check.h>
>  #include <errno.h>
>  #include <fcntl.h>
> @@ -110,12 +111,194 @@ START_TEST(touch_abs_transform)
>  }
>  END_TEST
>  
> +START_TEST(touch_seat_slots)
> +{
> +
> +	struct libinput *libinput;
> +	struct litest_device *dev1;
> +	struct litest_device *dev2;
> +	struct libinput_event *ev;
> +	struct libinput_event_touch *tev;
> +	int32_t seat_slot;
> +	int32_t last_seat_slot = -1;
> +	bool has_last_seat_slot = false;
> +
> +	libinput = litest_create_context();
> +
> +	dev1 = litest_add_device_with_overrides(libinput,
> +						LITEST_WACOM_TOUCH,
> +						"Touch device (0)",
> +						NULL, NULL, NULL);
> +	dev2 = litest_add_device_with_overrides(libinput,
> +						LITEST_WACOM_TOUCH,
> +						"Touch device (1)",
> +						NULL, NULL, NULL);
> +
> +	litest_touch_down(dev1, 0, 0, 0);
> +	/* Use different coordinates to avoid kernel filter. */
> +	litest_touch_down(dev2, 0, 0, 1);

As said in the other email, libevdev 1.2 will simply filter those events
(and the kernel will do so eventually too) so this test will fail. maybe
it's better to wait, drop this test and then just
require or at least heartily recommend libevdev 1.2?

> +
> +	libinput_dispatch(libinput);
> +
> +	/*
> +	 * Read the two touch down events and ensure their seat slot are
> +	 * unique.
> +	 */
> +	while ((ev = libinput_get_event(libinput))) {
> +		if (libinput_event_get_type(ev) != LIBINPUT_EVENT_TOUCH_DOWN)
> +			continue;
> +
> +		tev = libinput_event_get_touch_event(ev);
> +
> +		ck_assert_int_eq(libinput_event_touch_get_slot(tev), 0);
> +		seat_slot = libinput_event_touch_get_seat_slot(tev);
> +		ck_assert_int_ge(seat_slot, 0);
> +
> +		if (!has_last_seat_slot) {
> +			has_last_seat_slot = true;
> +			last_seat_slot = seat_slot;
> +			continue;
> +		}
> +
> +		ck_assert_int_ne(seat_slot, last_seat_slot);
> +
> +		libinput_dispatch(libinput);
> +	}
> +
> +	ck_assert(has_last_seat_slot);
> +	ck_assert_int_ne(seat_slot, last_seat_slot);
> +
> +	litest_delete_device(dev1);
> +	litest_delete_device(dev2);
> +
> +	libinput_destroy(libinput);
> +}
> +END_TEST
> +
> +START_TEST(touch_seat_slot_drop)
> +{

this test too would be easier to just drop and wait for libevdev 1.2.

Cheers,
   Peter

> +	struct libinput *libinput;
> +	struct litest_device *dev;
> +	struct libinput_event *ev;
> +	struct libinput_event_touch *tev;
> +	const int num_devices = 10;
> +	const int tps_per_device = 16;
> +	const int num_tps = num_devices * tps_per_device;
> +	struct litest_device *devices[num_devices];
> +	int slot;
> +	int seat_slot;
> +	enum libinput_event_type type;
> +	int found = 0;
> +	int i;
> +	int slot_count = 0;
> +	int slot_max_count;
> +	int32_t slots[num_tps];
> +	char device_name[255];
> +
> +	libinput = litest_create_context();
> +
> +	struct input_absinfo abs[] = {
> +		{ ABS_MT_SLOT, 0, tps_per_device, 0, 0, 0 },
> +		{ .value = -1 },
> +	};
> +
> +	/* Activate touch points from several devices in order to surpass per
> +	 * device touch slot limit. */
> +	for (i = 0; i < num_devices; ++i) {
> +		sprintf(device_name, "Multi-touch device (%d)", i);
> +		devices[i] =
> +			litest_add_device_with_overrides(libinput,
> +							 LITEST_WACOM_TOUCH,
> +							 device_name,
> +							 NULL, abs, NULL);
> +	}
> +
> +	litest_drain_events(libinput);
> +
> +	/* Trigger touch down events */
> +	for (i = 0; i < num_devices; ++i) {
> +		dev = devices[i];
> +		for (slot = 0; slot < num_tps; ++slot)
> +			litest_touch_down(dev, slot, 0, 0);
> +	}
> +
> +	libinput_dispatch(libinput);
> +
> +	/* Expect up to `num_tps`, but allow fewer. */
> +	memset(slots, 0, sizeof slots);
> +	while ((ev = libinput_get_event(libinput))) {
> +		type = libinput_event_get_type(ev);
> +		if (type == LIBINPUT_EVENT_TOUCH_FRAME)
> +			continue;
> +		ck_assert_int_eq(type, LIBINPUT_EVENT_TOUCH_DOWN);
> +
> +		tev = libinput_event_get_touch_event(ev);
> +		seat_slot = libinput_event_touch_get_seat_slot(tev);
> +
> +		ck_assert_int_ge(seat_slot, 0);
> +		ck_assert_int_lt(slot_count, num_tps);
> +		ck_assert_int_eq(slots[slot_count], 0);
> +
> +		/* Assert uniqueness */
> +		for (slot = 0; slot < slot_count; ++slot)
> +			ck_assert_int_ne(seat_slot, slots[slot]);
> +
> +		slots[slot_count] = seat_slot;
> +		++slot_count;
> +
> +		libinput_dispatch(libinput);
> +	}
> +
> +	ck_assert_int_gt(slot_count, 0);
> +
> +	slot_max_count = slot_count;
> +
> +	/* Trigger touch up events */
> +	for (i = 0; i < num_devices; ++i) {
> +		dev = devices[i];
> +		for (slot = 0; slot < num_tps; ++slot)
> +			litest_touch_up(dev, slot);
> +	}
> +
> +	libinput_dispatch(libinput);
> +
> +	/* Make sure order was not shuffled and we received up before all
> +	 * down, and that we received as many up as down. */
> +	while ((ev = libinput_get_event(libinput))) {
> +		type = libinput_event_get_type(ev);
> +		if (type == LIBINPUT_EVENT_TOUCH_FRAME)
> +			continue;
> +		ck_assert_int_eq(type, LIBINPUT_EVENT_TOUCH_UP);
> +
> +		tev = libinput_event_get_touch_event(ev);
> +		seat_slot = libinput_event_touch_get_seat_slot(tev);
> +
> +		--slot_count;
> +		found = 0;
> +		for (slot = 0; slot < slot_max_count; ++slot)
> +			if (slots[slot] == seat_slot)
> +				++found;
> +		ck_assert_int_eq(found, 1);
> +
> +		libinput_dispatch(libinput);
> +	}
> +
> +	ck_assert_int_eq(slot_count, 0);
> +
> +	for (i = 0; i < num_devices; ++i)
> +		litest_delete_device(devices[i]);
> +
> +	libinput_destroy(libinput);
> +}
> +END_TEST
>  
>  int
>  main(int argc, char **argv)
>  {
>  	litest_add("touch:frame", touch_frame_events, LITEST_TOUCH, LITEST_ANY);
>  	litest_add_no_device("touch:abs-transform", touch_abs_transform);
> +	litest_add_no_device("touch:seat-slot", touch_seat_slots);
> +	litest_add_no_device("touch:seat-slot-drop", touch_seat_slot_drop);
>  
>  	return litest_run(argc, argv);
>  }
> -- 
> 1.8.3.2
> 


More information about the wayland-devel mailing list