2 * Copyright © 2013 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
37 #include <linux/input.h>
38 #include <sys/ptrace.h>
39 #include <sys/timerfd.h>
43 #include "litest-int.h"
44 #include "libinput-util.h"
46 static int in_debugger = -1;
52 enum litest_device_type devices;
62 static struct litest_device *current_device;
64 struct litest_device *litest_current_device(void) {
65 return current_device;
68 void litest_set_current_device(struct litest_device *device) {
69 current_device = device;
72 void litest_generic_device_teardown(void)
74 litest_delete_device(current_device);
75 current_device = NULL;
78 extern struct litest_test_device litest_keyboard_device;
79 extern struct litest_test_device litest_synaptics_clickpad_device;
80 extern struct litest_test_device litest_trackpoint_device;
81 extern struct litest_test_device litest_bcm5974_device;
82 extern struct litest_test_device litest_mouse_device;
83 extern struct litest_test_device litest_wacom_touch_device;
85 struct litest_test_device* devices[] = {
86 &litest_synaptics_clickpad_device,
87 &litest_keyboard_device,
88 &litest_trackpoint_device,
89 &litest_bcm5974_device,
91 &litest_wacom_touch_device,
96 static struct list all_tests;
99 litest_add_tcase_for_device(struct suite *suite,
101 const struct litest_test_device *dev)
104 const char *test_name = dev->shortname;
106 list_for_each(t, &suite->tests, node) {
107 if (strcmp(t->name, test_name) != 0)
110 tcase_add_test(t->tc, func);
114 t = zalloc(sizeof(*t));
115 t->name = strdup(test_name);
116 t->tc = tcase_create(test_name);
117 list_insert(&suite->tests, &t->node);
118 tcase_add_checked_fixture(t->tc, dev->setup, dev->teardown);
119 tcase_add_test(t->tc, func);
120 suite_add_tcase(suite->suite, t->tc);
124 litest_add_tcase_no_device(struct suite *suite, void *func)
127 const char *test_name = "no device";
129 list_for_each(t, &suite->tests, node) {
130 if (strcmp(t->name, test_name) != 0)
133 tcase_add_test(t->tc, func);
137 t = zalloc(sizeof(*t));
138 t->name = strdup(test_name);
139 t->tc = tcase_create(test_name);
140 list_insert(&suite->tests, &t->node);
141 tcase_add_test(t->tc, func);
142 suite_add_tcase(suite->suite, t->tc);
146 litest_add_tcase(struct suite *suite, void *func,
147 enum litest_device_feature required,
148 enum litest_device_feature excluded)
150 struct litest_test_device **dev = devices;
152 if (required == LITEST_DISABLE_DEVICE &&
153 excluded == LITEST_DISABLE_DEVICE) {
154 litest_add_tcase_no_device(suite, func);
155 } else if (required != LITEST_ANY || excluded != LITEST_ANY) {
157 if (((*dev)->features & required) == required &&
158 ((*dev)->features & excluded) == 0)
159 litest_add_tcase_for_device(suite, func, *dev);
164 litest_add_tcase_for_device(suite, func, *dev);
171 litest_add_no_device(const char *name, void *func)
173 litest_add(name, func, LITEST_DISABLE_DEVICE, LITEST_DISABLE_DEVICE);
177 litest_add(const char *name,
179 enum litest_device_feature required,
180 enum litest_device_feature excluded)
184 if (all_tests.next == NULL && all_tests.prev == NULL)
185 list_init(&all_tests);
187 list_for_each(s, &all_tests, node) {
188 if (strcmp(s->name, name) == 0) {
189 litest_add_tcase(s, func, required, excluded);
194 s = zalloc(sizeof(*s));
195 s->name = strdup(name);
196 s->suite = suite_create(s->name);
198 list_init(&s->tests);
199 list_insert(&all_tests, &s->node);
200 litest_add_tcase(s, func, required, excluded);
203 int is_debugger_attached()
213 int ppid = getppid();
214 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0) {
215 waitpid(ppid, NULL, 0);
216 ptrace(PTRACE_CONT, NULL, NULL);
217 ptrace(PTRACE_DETACH, ppid, NULL, NULL);
224 waitpid(pid, &status, 0);
225 rc = WEXITSTATUS(status);
233 litest_list_tests(struct list *tests)
237 list_for_each(s, tests, node) {
239 printf("%s:\n", s->name);
240 list_for_each(t, &s->tests, node) {
241 printf(" %s\n", t->name);
246 static const struct option opts[] = {
247 { "list", 0, 0, 'l' },
252 litest_run(int argc, char **argv) {
253 struct suite *s, *snext;
257 if (in_debugger == -1) {
258 in_debugger = is_debugger_attached();
260 setenv("CK_FORK", "no", 0);
263 list_for_each(s, &all_tests, node) {
265 sr = srunner_create(s->suite);
267 srunner_add_suite(sr, s->suite);
272 int option_index = 0;
274 c = getopt_long(argc, argv, "", opts, &option_index);
279 litest_list_tests(&all_tests);
282 fprintf(stderr, "usage: %s [--list]\n", argv[0]);
288 srunner_run_all(sr, CK_NORMAL);
289 failed = srunner_ntests_failed(sr);
292 list_for_each_safe(s, snext, &all_tests, node) {
293 struct test *t, *tnext;
295 list_for_each_safe(t, tnext, &s->tests, node) {
297 list_remove(&t->node);
301 list_remove(&s->node);
310 open_restricted(const char *path, int flags, void *userdata)
312 return open(path, flags);
316 close_restricted(int fd, void *userdata)
322 get_current_screen_dimensions(struct libinput_device *device,
331 const struct libinput_interface interface = {
332 .open_restricted = open_restricted,
333 .close_restricted = close_restricted,
334 .get_current_screen_dimensions = get_current_screen_dimensions,
337 struct litest_device *
338 litest_create_device(enum litest_device_type which)
340 struct litest_device *d = zalloc(sizeof(*d));
344 struct litest_test_device **dev;
346 ck_assert(d != NULL);
350 if ((*dev)->type == which) {
358 ck_abort_msg("Invalid device type %d\n", which);
362 path = libevdev_uinput_get_devnode(d->uinput);
363 ck_assert(path != NULL);
364 fd = open(path, O_RDWR|O_NONBLOCK);
365 ck_assert_int_ne(fd, -1);
367 rc = libevdev_new_from_fd(fd, &d->evdev);
368 ck_assert_int_eq(rc, 0);
370 d->libinput = libinput_create_from_path(&interface, NULL, path);
371 ck_assert(d->libinput != NULL);
373 d->interface->min[ABS_X] = libevdev_get_abs_minimum(d->evdev, ABS_X);
374 d->interface->max[ABS_X] = libevdev_get_abs_maximum(d->evdev, ABS_X);
375 d->interface->min[ABS_Y] = libevdev_get_abs_minimum(d->evdev, ABS_Y);
376 d->interface->max[ABS_Y] = libevdev_get_abs_maximum(d->evdev, ABS_Y);
381 litest_handle_events(struct litest_device *d)
385 fd.fd = libinput_get_fd(d->libinput);
388 while (poll(&fd, 1, 1))
389 libinput_dispatch(d->libinput);
395 litest_delete_device(struct litest_device *d)
400 libinput_destroy(d->libinput);
401 libevdev_free(d->evdev);
402 libevdev_uinput_destroy(d->uinput);
403 memset(d,0, sizeof(*d));
408 litest_event(struct litest_device *d, unsigned int type,
409 unsigned int code, int value)
411 libevdev_uinput_write_event(d->uinput, type, code, value);
415 litest_touch_down(struct litest_device *d, unsigned int slot, int x, int y)
417 d->interface->touch_down(d, slot, x, y);
421 litest_touch_up(struct litest_device *d, unsigned int slot)
423 struct input_event *ev;
424 struct input_event up[] = {
425 { .type = EV_ABS, .code = ABS_MT_SLOT, .value = slot },
426 { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = -1 },
427 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
430 ARRAY_FOR_EACH(up, ev)
431 litest_event(d, ev->type, ev->code, ev->value);
435 litest_touch_move(struct litest_device *d, unsigned int slot, int x, int y)
437 d->interface->touch_move(d, slot, x, y);
441 litest_touch_move_to(struct litest_device *d,
443 int x_from, int y_from,
447 for (int i = 0; i < steps - 1; i++)
448 litest_touch_move(d, slot,
449 x_from + (x_to - x_from)/steps * i,
450 y_from + (y_to - y_from)/steps * i);
451 litest_touch_move(d, slot, x_to, y_to);
455 litest_click(struct litest_device *d, unsigned int button, bool is_press)
458 struct input_event *ev;
459 struct input_event click[] = {
460 { .type = EV_KEY, .code = button, .value = is_press ? 1 : 0 },
461 { .type = EV_SYN, .code = SYN_REPORT, .value = 0 },
464 ARRAY_FOR_EACH(click, ev)
465 litest_event(d, ev->type, ev->code, ev->value);
468 int litest_scale(const struct litest_device *d, unsigned int axis, int val)
471 ck_assert_int_ge(val, 0);
472 ck_assert_int_le(val, 100);
473 ck_assert_int_le(axis, ABS_Y);
475 min = d->interface->min[axis];
476 max = d->interface->max[axis];
477 return (max - min) * val/100.0 + min;
481 litest_drain_events(struct libinput *li)
483 struct libinput_event *event;
485 libinput_dispatch(li);
486 while ((event = libinput_get_event(li))) {
487 libinput_event_destroy(event);
488 libinput_dispatch(li);