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

Jonas Ådahl jadahl at gmail.com
Wed Apr 9 23:25:20 PDT 2014


On Thu, Apr 10, 2014 at 03:48:40PM +1000, Peter Hutterer wrote:
> 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 

Amended locally.

> 
> >  };
> >  
> > +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?

Actually it should be ck_assert_ptr_ne(ptr, NULL) but I got tired of
writing that over and over as mostly I asserted that the ptr was not
NULL, so I added this.

> 
> > +
> >  #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?

I suppose that would work as well. Recommend would not be enough IMO,
because then the API promises we'd make would only be valid for certain
libevdev versions.

> 
> > +
> > +	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.

This test tests that if libinput can't associate a touch event with a
seat touch slot, it'll be dropped, so its a bit orthogonal to using
libevdev 1.2 isn't it?

> 
> 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