[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