xref: /third_party/libinput/test/test-path.c (revision a46c0ec8)
1/*
2 * Copyright © 2013 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <config.h>
25
26#include <check.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <libinput.h>
30#include <stdio.h>
31#include <sys/stat.h>
32#include <unistd.h>
33
34#include "litest.h"
35#include "libinput-util.h"
36
37struct counter {
38	int open_func_count;
39	int close_func_count;
40};
41
42static int
43open_restricted_count(const char *path, int flags, void *data)
44{
45	struct counter *c = data;
46	int fd;
47
48	c->open_func_count++;
49
50	fd = open(path, flags);
51	return fd < 0 ? -errno : fd;
52}
53
54static void
55close_restricted_count(int fd, void *data)
56{
57	struct counter *c = data;
58
59	c->close_func_count++;
60	close(fd);
61}
62
63static const struct libinput_interface counting_interface = {
64	.open_restricted = open_restricted_count,
65	.close_restricted = close_restricted_count,
66};
67
68static int
69open_restricted(const char *path, int flags, void *data)
70{
71	int fd = open(path, flags);
72	return fd < 0 ? -errno : fd;
73}
74
75static void
76close_restricted(int fd, void *data)
77{
78	close(fd);
79}
80
81static const struct libinput_interface simple_interface = {
82	.open_restricted = open_restricted,
83	.close_restricted = close_restricted,
84};
85
86START_TEST(path_create_NULL)
87{
88	struct libinput *li;
89	struct counter counter;
90
91	counter.open_func_count = 0;
92	counter.close_func_count = 0;
93
94	li = libinput_path_create_context(NULL, NULL);
95	ck_assert(li == NULL);
96	li = libinput_path_create_context(&counting_interface, &counter);
97	ck_assert_notnull(li);
98	libinput_unref(li);
99
100	ck_assert_int_eq(counter.open_func_count, 0);
101	ck_assert_int_eq(counter.close_func_count, 0);
102}
103END_TEST
104
105START_TEST(path_create_invalid)
106{
107	struct libinput *li;
108	struct libinput_device *device;
109	const char *path = "/tmp";
110	struct counter counter;
111
112	counter.open_func_count = 0;
113	counter.close_func_count = 0;
114
115	li = libinput_path_create_context(&counting_interface, &counter);
116	ck_assert_notnull(li);
117
118	litest_disable_log_handler(li);
119
120	device = libinput_path_add_device(li, path);
121	ck_assert(device == NULL);
122
123	ck_assert_int_eq(counter.open_func_count, 0);
124	ck_assert_int_eq(counter.close_func_count, 0);
125
126	litest_restore_log_handler(li);
127	libinput_unref(li);
128	ck_assert_int_eq(counter.close_func_count, 0);
129}
130END_TEST
131
132START_TEST(path_create_invalid_kerneldev)
133{
134	struct libinput *li;
135	struct libinput_device *device;
136	const char *path = "/dev/uinput";
137	struct counter counter;
138
139	counter.open_func_count = 0;
140	counter.close_func_count = 0;
141
142	li = libinput_path_create_context(&counting_interface, &counter);
143	ck_assert_notnull(li);
144
145	litest_disable_log_handler(li);
146
147	device = libinput_path_add_device(li, path);
148	ck_assert(device == NULL);
149
150	ck_assert_int_eq(counter.open_func_count, 1);
151	ck_assert_int_eq(counter.close_func_count, 1);
152
153	litest_restore_log_handler(li);
154	libinput_unref(li);
155	ck_assert_int_eq(counter.close_func_count, 1);
156}
157END_TEST
158
159START_TEST(path_create_invalid_file)
160{
161	struct libinput *li;
162	struct libinput_device *device;
163	char path[] = "/tmp/litest_path_XXXXXX";
164	int fd;
165	struct counter counter;
166
167	umask(002);
168	fd = mkstemp(path);
169	ck_assert_int_ge(fd, 0);
170	close(fd);
171
172	counter.open_func_count = 0;
173	counter.close_func_count = 0;
174
175	li = libinput_path_create_context(&counting_interface, &counter);
176	unlink(path);
177
178	litest_disable_log_handler(li);
179
180	ck_assert_notnull(li);
181	device = libinput_path_add_device(li, path);
182	ck_assert(device == NULL);
183
184	ck_assert_int_eq(counter.open_func_count, 0);
185	ck_assert_int_eq(counter.close_func_count, 0);
186
187	litest_restore_log_handler(li);
188	libinput_unref(li);
189	ck_assert_int_eq(counter.close_func_count, 0);
190}
191END_TEST
192
193START_TEST(path_create_pathmax_file)
194{
195	struct libinput *li;
196	struct libinput_device *device;
197	char *path;
198	struct counter counter;
199
200	path = zalloc(PATH_MAX * 2);
201	memset(path, 'a', PATH_MAX * 2 - 1);
202
203	counter.open_func_count = 0;
204	counter.close_func_count = 0;
205
206	li = libinput_path_create_context(&counting_interface, &counter);
207
208	litest_set_log_handler_bug(li);
209	ck_assert_notnull(li);
210	device = libinput_path_add_device(li, path);
211	ck_assert(device == NULL);
212
213	ck_assert_int_eq(counter.open_func_count, 0);
214	ck_assert_int_eq(counter.close_func_count, 0);
215
216	litest_restore_log_handler(li);
217	libinput_unref(li);
218	ck_assert_int_eq(counter.close_func_count, 0);
219
220	free(path);
221}
222END_TEST
223
224
225START_TEST(path_create_destroy)
226{
227	struct libinput *li;
228	struct libinput_device *device;
229	struct libevdev_uinput *uinput;
230	struct counter counter;
231
232	counter.open_func_count = 0;
233	counter.close_func_count = 0;
234
235	uinput = litest_create_uinput_device("test device", NULL,
236					     EV_KEY, BTN_LEFT,
237					     EV_KEY, BTN_RIGHT,
238					     EV_REL, REL_X,
239					     EV_REL, REL_Y,
240					     -1);
241
242	li = libinput_path_create_context(&counting_interface, &counter);
243	ck_assert_notnull(li);
244
245	litest_disable_log_handler(li);
246
247	ck_assert(libinput_get_user_data(li) == &counter);
248
249	device = libinput_path_add_device(li,
250					  libevdev_uinput_get_devnode(uinput));
251	ck_assert_notnull(device);
252
253	ck_assert_int_eq(counter.open_func_count, 1);
254
255	libevdev_uinput_destroy(uinput);
256	libinput_unref(li);
257	ck_assert_int_eq(counter.close_func_count, 1);
258}
259END_TEST
260
261START_TEST(path_force_destroy)
262{
263	struct litest_device *dev = litest_current_device();
264	struct libinput *li;
265	struct libinput_device *device;
266
267	li = libinput_path_create_context(&simple_interface, NULL);
268	ck_assert_notnull(li);
269	libinput_ref(li);
270	device = libinput_path_add_device(li,
271				  libevdev_uinput_get_devnode(dev->uinput));
272	ck_assert_notnull(device);
273
274	while (libinput_unref(li) != NULL)
275		;
276}
277END_TEST
278
279START_TEST(path_set_user_data)
280{
281	struct libinput *li;
282	int data1, data2;
283
284	li = libinput_path_create_context(&simple_interface, &data1);
285	ck_assert_notnull(li);
286	ck_assert(libinput_get_user_data(li) == &data1);
287	libinput_set_user_data(li, &data2);
288	ck_assert(libinput_get_user_data(li) == &data2);
289
290	libinput_unref(li);
291}
292END_TEST
293
294START_TEST(path_added_seat)
295{
296	struct litest_device *dev = litest_current_device();
297	struct libinput *li = dev->libinput;
298	struct libinput_event *event;
299	struct libinput_device *device;
300	struct libinput_seat *seat;
301	const char *seat_name;
302	enum libinput_event_type type;
303
304	libinput_dispatch(li);
305
306	event = libinput_get_event(li);
307	ck_assert_notnull(event);
308
309	type = libinput_event_get_type(event);
310	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
311
312	device = libinput_event_get_device(event);
313	seat = libinput_device_get_seat(device);
314	ck_assert_notnull(seat);
315
316	seat_name = libinput_seat_get_logical_name(seat);
317	ck_assert_str_eq(seat_name, "default");
318
319	libinput_event_destroy(event);
320}
321END_TEST
322
323START_TEST(path_seat_change)
324{
325	struct litest_device *dev = litest_current_device();
326	struct libinput *li = dev->libinput;
327	struct libinput_event *event;
328	struct libinput_device *device;
329	struct libinput_seat *seat1, *seat2;
330	const char *seat1_name;
331	const char *seat2_name = "new seat";
332	int rc;
333
334	libinput_dispatch(li);
335
336	event = libinput_get_event(li);
337	ck_assert_int_eq(libinput_event_get_type(event),
338			 LIBINPUT_EVENT_DEVICE_ADDED);
339
340	device = libinput_event_get_device(event);
341	libinput_device_ref(device);
342
343	seat1 = libinput_device_get_seat(device);
344	libinput_seat_ref(seat1);
345
346	seat1_name = libinput_seat_get_logical_name(seat1);
347	libinput_event_destroy(event);
348
349	litest_drain_events(li);
350
351	rc = libinput_device_set_seat_logical_name(device,
352						   seat2_name);
353	ck_assert_int_eq(rc, 0);
354
355	libinput_dispatch(li);
356
357	event = libinput_get_event(li);
358	ck_assert_notnull(event);
359
360	ck_assert_int_eq(libinput_event_get_type(event),
361			 LIBINPUT_EVENT_DEVICE_REMOVED);
362
363	ck_assert(libinput_event_get_device(event) == device);
364	libinput_event_destroy(event);
365
366	event = libinput_get_event(li);
367	ck_assert_notnull(event);
368	ck_assert_int_eq(libinput_event_get_type(event),
369			 LIBINPUT_EVENT_DEVICE_ADDED);
370	ck_assert(libinput_event_get_device(event) != device);
371	libinput_device_unref(device);
372
373	device = libinput_event_get_device(event);
374	seat2 = libinput_device_get_seat(device);
375
376	ck_assert_str_ne(libinput_seat_get_logical_name(seat2),
377			 seat1_name);
378	ck_assert_str_eq(libinput_seat_get_logical_name(seat2),
379			 seat2_name);
380	libinput_event_destroy(event);
381
382	libinput_seat_unref(seat1);
383
384	/* litest: swap the new device in, so cleanup works */
385	libinput_device_unref(dev->libinput_device);
386	libinput_device_ref(device);
387	dev->libinput_device = device;
388}
389END_TEST
390
391START_TEST(path_added_device)
392{
393	struct litest_device *dev = litest_current_device();
394	struct libinput *li = dev->libinput;
395	struct libinput_event *event;
396	struct libinput_device *device;
397	enum libinput_event_type type;
398
399	libinput_dispatch(li);
400
401	event = libinput_get_event(li);
402	ck_assert_notnull(event);
403	type = libinput_event_get_type(event);
404	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
405	device = libinput_event_get_device(event);
406	ck_assert_notnull(device);
407
408	libinput_event_destroy(event);
409}
410END_TEST
411
412START_TEST(path_add_device)
413{
414	struct litest_device *dev = litest_current_device();
415	struct libinput *li = dev->libinput;
416	struct libinput_event *event;
417	struct libinput_device *device;
418	char *sysname1 = NULL, *sysname2 = NULL;
419	enum libinput_event_type type;
420
421	libinput_dispatch(li);
422
423	event = libinput_get_event(li);
424	ck_assert_notnull(event);
425	type = libinput_event_get_type(event);
426	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
427	device = libinput_event_get_device(event);
428	ck_assert_notnull(device);
429	sysname1 = safe_strdup(libinput_device_get_sysname(device));
430	libinput_event_destroy(event);
431
432	litest_assert_empty_queue(li);
433
434	device = libinput_path_add_device(li,
435					  libevdev_uinput_get_devnode(dev->uinput));
436	ck_assert_notnull(device);
437
438	libinput_dispatch(li);
439
440	event = libinput_get_event(li);
441	ck_assert_notnull(event);
442	type = libinput_event_get_type(event);
443	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
444	device = libinput_event_get_device(event);
445	ck_assert_notnull(device);
446	sysname2 = safe_strdup(libinput_device_get_sysname(device));
447	libinput_event_destroy(event);
448
449	ck_assert_str_eq(sysname1, sysname2);
450
451	free(sysname1);
452	free(sysname2);
453}
454END_TEST
455
456START_TEST(path_add_invalid_path)
457{
458	struct libinput *li;
459	struct libinput_device *device;
460
461	li = litest_create_context();
462
463	litest_disable_log_handler(li);
464	device = libinput_path_add_device(li, "/tmp/");
465	litest_restore_log_handler(li);
466	ck_assert(device == NULL);
467
468	libinput_dispatch(li);
469
470	litest_assert_empty_queue(li);
471
472	litest_destroy_context(li);
473}
474END_TEST
475
476START_TEST(path_device_sysname)
477{
478	struct litest_device *dev = litest_current_device();
479	struct libinput_event *ev;
480	struct libinput_device *device;
481	const char *sysname;
482	enum libinput_event_type type;
483
484	libinput_dispatch(dev->libinput);
485
486	ev = libinput_get_event(dev->libinput);
487	ck_assert_notnull(ev);
488	type = libinput_event_get_type(ev);
489	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
490	device = libinput_event_get_device(ev);
491	ck_assert_notnull(device);
492	sysname = libinput_device_get_sysname(device);
493
494	ck_assert_notnull(sysname);
495	ck_assert_int_gt(strlen(sysname), 1);
496	ck_assert(strchr(sysname, '/') == NULL);
497	ck_assert(strneq(sysname, "event", 5));
498
499	libinput_event_destroy(ev);
500}
501END_TEST
502
503START_TEST(path_remove_device)
504{
505	struct litest_device *dev = litest_current_device();
506	struct libinput *li = dev->libinput;
507	struct libinput_event *event;
508	struct libinput_device *device;
509	int remove_event = 0;
510
511	device = libinput_path_add_device(li,
512					  libevdev_uinput_get_devnode(dev->uinput));
513	ck_assert_notnull(device);
514	litest_drain_events(li);
515
516	libinput_path_remove_device(device);
517	libinput_dispatch(li);
518
519	while ((event = libinput_get_event(li))) {
520		enum libinput_event_type type;
521		type = libinput_event_get_type(event);
522
523		if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
524			remove_event++;
525
526		libinput_event_destroy(event);
527	}
528
529	ck_assert_int_eq(remove_event, 1);
530}
531END_TEST
532
533START_TEST(path_double_remove_device)
534{
535	struct litest_device *dev = litest_current_device();
536	struct libinput *li = dev->libinput;
537	struct libinput_event *event;
538	struct libinput_device *device;
539	int remove_event = 0;
540
541	device = libinput_path_add_device(li,
542					  libevdev_uinput_get_devnode(dev->uinput));
543	ck_assert_notnull(device);
544	litest_drain_events(li);
545
546	libinput_path_remove_device(device);
547	libinput_path_remove_device(device);
548	libinput_dispatch(li);
549
550	while ((event = libinput_get_event(li))) {
551		enum libinput_event_type type;
552		type = libinput_event_get_type(event);
553
554		if (type == LIBINPUT_EVENT_DEVICE_REMOVED)
555			remove_event++;
556
557		libinput_event_destroy(event);
558	}
559
560	ck_assert_int_eq(remove_event, 1);
561}
562END_TEST
563
564START_TEST(path_suspend)
565{
566	struct libinput *li;
567	struct libinput_device *device;
568	struct libevdev_uinput *uinput;
569	int rc;
570	void *userdata = &rc;
571
572	uinput = litest_create_uinput_device("test device", NULL,
573					     EV_KEY, BTN_LEFT,
574					     EV_KEY, BTN_RIGHT,
575					     EV_REL, REL_X,
576					     EV_REL, REL_Y,
577					     -1);
578
579	li = libinput_path_create_context(&simple_interface, userdata);
580	ck_assert_notnull(li);
581
582	device = libinput_path_add_device(li,
583					  libevdev_uinput_get_devnode(uinput));
584	ck_assert_notnull(device);
585
586	libinput_suspend(li);
587	libinput_resume(li);
588
589	libevdev_uinput_destroy(uinput);
590	libinput_unref(li);
591}
592END_TEST
593
594START_TEST(path_double_suspend)
595{
596	struct libinput *li;
597	struct libinput_device *device;
598	struct libevdev_uinput *uinput;
599	int rc;
600	void *userdata = &rc;
601
602	uinput = litest_create_uinput_device("test device", NULL,
603					     EV_KEY, BTN_LEFT,
604					     EV_KEY, BTN_RIGHT,
605					     EV_REL, REL_X,
606					     EV_REL, REL_Y,
607					     -1);
608
609	li = libinput_path_create_context(&simple_interface, userdata);
610	ck_assert_notnull(li);
611
612	device = libinput_path_add_device(li,
613					  libevdev_uinput_get_devnode(uinput));
614	ck_assert_notnull(device);
615
616	libinput_suspend(li);
617	libinput_suspend(li);
618	libinput_resume(li);
619
620	libevdev_uinput_destroy(uinput);
621	libinput_unref(li);
622}
623END_TEST
624
625START_TEST(path_double_resume)
626{
627	struct libinput *li;
628	struct libinput_device *device;
629	struct libevdev_uinput *uinput;
630	int rc;
631	void *userdata = &rc;
632
633	uinput = litest_create_uinput_device("test device", NULL,
634					     EV_KEY, BTN_LEFT,
635					     EV_KEY, BTN_RIGHT,
636					     EV_REL, REL_X,
637					     EV_REL, REL_Y,
638					     -1);
639
640	li = libinput_path_create_context(&simple_interface, userdata);
641	ck_assert_notnull(li);
642
643	device = libinput_path_add_device(li,
644					  libevdev_uinput_get_devnode(uinput));
645	ck_assert_notnull(device);
646
647	libinput_suspend(li);
648	libinput_resume(li);
649	libinput_resume(li);
650
651	libevdev_uinput_destroy(uinput);
652	libinput_unref(li);
653}
654END_TEST
655
656START_TEST(path_add_device_suspend_resume)
657{
658	struct libinput *li;
659	struct libinput_device *device;
660	struct libinput_event *event;
661	struct libevdev_uinput *uinput1, *uinput2;
662	int rc;
663	int nevents;
664	void *userdata = &rc;
665
666	uinput1 = litest_create_uinput_device("test device", NULL,
667					      EV_KEY, BTN_LEFT,
668					      EV_KEY, BTN_RIGHT,
669					      EV_REL, REL_X,
670					      EV_REL, REL_Y,
671					      -1);
672	uinput2 = litest_create_uinput_device("test device 2", NULL,
673					      EV_KEY, BTN_LEFT,
674					      EV_KEY, BTN_RIGHT,
675					      EV_REL, REL_X,
676					      EV_REL, REL_Y,
677					      -1);
678
679	li = libinput_path_create_context(&simple_interface, userdata);
680	ck_assert_notnull(li);
681
682	device = libinput_path_add_device(li,
683					  libevdev_uinput_get_devnode(uinput1));
684	ck_assert_notnull(device);
685	libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput2));
686
687	libinput_dispatch(li);
688
689	nevents = 0;
690	while ((event = libinput_get_event(li))) {
691		enum libinput_event_type type;
692		type = libinput_event_get_type(event);
693		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
694		libinput_event_destroy(event);
695		nevents++;
696	}
697
698	ck_assert_int_eq(nevents, 2);
699
700	libinput_suspend(li);
701	libinput_dispatch(li);
702
703	nevents = 0;
704	while ((event = libinput_get_event(li))) {
705		enum libinput_event_type type;
706		type = libinput_event_get_type(event);
707		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
708		libinput_event_destroy(event);
709		nevents++;
710	}
711
712	ck_assert_int_eq(nevents, 2);
713
714	libinput_resume(li);
715	libinput_dispatch(li);
716
717	nevents = 0;
718	while ((event = libinput_get_event(li))) {
719		enum libinput_event_type type;
720		type = libinput_event_get_type(event);
721		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
722		libinput_event_destroy(event);
723		nevents++;
724	}
725
726	ck_assert_int_eq(nevents, 2);
727
728	libevdev_uinput_destroy(uinput1);
729	libevdev_uinput_destroy(uinput2);
730	libinput_unref(li);
731}
732END_TEST
733
734START_TEST(path_add_device_suspend_resume_fail)
735{
736	struct libinput *li;
737	struct libinput_device *device;
738	struct libinput_event *event;
739	struct libevdev_uinput *uinput1, *uinput2;
740	int rc;
741	int nevents;
742	void *userdata = &rc;
743
744	uinput1 = litest_create_uinput_device("test device", NULL,
745					      EV_KEY, BTN_LEFT,
746					      EV_KEY, BTN_RIGHT,
747					      EV_REL, REL_X,
748					      EV_REL, REL_Y,
749					      -1);
750	uinput2 = litest_create_uinput_device("test device 2", NULL,
751					      EV_KEY, BTN_LEFT,
752					      EV_KEY, BTN_RIGHT,
753					      EV_REL, REL_X,
754					      EV_REL, REL_Y,
755					      -1);
756
757	li = libinput_path_create_context(&simple_interface, userdata);
758	ck_assert_notnull(li);
759
760	device = libinput_path_add_device(li,
761					  libevdev_uinput_get_devnode(uinput1));
762	ck_assert_notnull(device);
763	device = libinput_path_add_device(li,
764					  libevdev_uinput_get_devnode(uinput2));
765	ck_assert_notnull(device);
766
767	libinput_dispatch(li);
768
769	nevents = 0;
770	while ((event = libinput_get_event(li))) {
771		enum libinput_event_type type;
772		type = libinput_event_get_type(event);
773		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
774		libinput_event_destroy(event);
775		nevents++;
776	}
777
778	ck_assert_int_eq(nevents, 2);
779
780	libinput_suspend(li);
781	libinput_dispatch(li);
782
783	nevents = 0;
784	while ((event = libinput_get_event(li))) {
785		enum libinput_event_type type;
786		type = libinput_event_get_type(event);
787		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
788		libinput_event_destroy(event);
789		nevents++;
790	}
791
792	ck_assert_int_eq(nevents, 2);
793
794	/* now drop one of the devices */
795	libevdev_uinput_destroy(uinput1);
796	rc = libinput_resume(li);
797	ck_assert_int_eq(rc, -1);
798
799	libinput_dispatch(li);
800
801	nevents = 0;
802	while ((event = libinput_get_event(li))) {
803		enum libinput_event_type type;
804		type = libinput_event_get_type(event);
805		/* We expect one device being added, second one fails,
806		 * causing a removed event for the first one */
807		if (type != LIBINPUT_EVENT_DEVICE_ADDED &&
808		    type != LIBINPUT_EVENT_DEVICE_REMOVED)
809			ck_abort();
810		libinput_event_destroy(event);
811		nevents++;
812	}
813
814	ck_assert_int_eq(nevents, 2);
815
816	libevdev_uinput_destroy(uinput2);
817	libinput_unref(li);
818}
819END_TEST
820
821START_TEST(path_add_device_suspend_resume_remove_device)
822{
823	struct libinput *li;
824	struct libinput_device *device;
825	struct libinput_event *event;
826	struct libevdev_uinput *uinput1, *uinput2;
827	int rc;
828	int nevents;
829	void *userdata = &rc;
830
831	uinput1 = litest_create_uinput_device("test device", NULL,
832					      EV_KEY, BTN_LEFT,
833					      EV_KEY, BTN_RIGHT,
834					      EV_REL, REL_X,
835					      EV_REL, REL_Y,
836					      -1);
837	uinput2 = litest_create_uinput_device("test device 2", NULL,
838					      EV_KEY, BTN_LEFT,
839					      EV_KEY, BTN_RIGHT,
840					      EV_REL, REL_X,
841					      EV_REL, REL_Y,
842					      -1);
843
844	li = libinput_path_create_context(&simple_interface, userdata);
845	ck_assert_notnull(li);
846
847	device = libinput_path_add_device(li,
848					  libevdev_uinput_get_devnode(uinput1));
849	ck_assert_notnull(device);
850	device = libinput_path_add_device(li,
851					  libevdev_uinput_get_devnode(uinput2));
852
853	libinput_device_ref(device);
854	libinput_dispatch(li);
855
856	nevents = 0;
857	while ((event = libinput_get_event(li))) {
858		enum libinput_event_type type;
859		type = libinput_event_get_type(event);
860		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
861		libinput_event_destroy(event);
862		nevents++;
863	}
864
865	ck_assert_int_eq(nevents, 2);
866
867	libinput_suspend(li);
868	libinput_dispatch(li);
869
870	nevents = 0;
871	while ((event = libinput_get_event(li))) {
872		enum libinput_event_type type;
873		type = libinput_event_get_type(event);
874		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_REMOVED);
875		libinput_event_destroy(event);
876		nevents++;
877	}
878
879	ck_assert_int_eq(nevents, 2);
880
881	/* now drop and remove one of the devices */
882	libevdev_uinput_destroy(uinput2);
883	libinput_path_remove_device(device);
884	libinput_device_unref(device);
885
886	rc = libinput_resume(li);
887	ck_assert_int_eq(rc, 0);
888
889	libinput_dispatch(li);
890
891	nevents = 0;
892	while ((event = libinput_get_event(li))) {
893		enum libinput_event_type type;
894		type = libinput_event_get_type(event);
895		ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
896		libinput_event_destroy(event);
897		nevents++;
898	}
899
900	ck_assert_int_eq(nevents, 1);
901
902	libevdev_uinput_destroy(uinput1);
903	libinput_unref(li);
904}
905END_TEST
906
907START_TEST(path_device_gone)
908{
909	struct libinput *li;
910	struct libinput_device *device;
911	struct libevdev_uinput *uinput;
912	struct libinput_event *event;
913
914	uinput = litest_create_uinput_device("test device", NULL,
915					     EV_KEY, BTN_LEFT,
916					     EV_KEY, BTN_RIGHT,
917					     EV_REL, REL_X,
918					     EV_REL, REL_Y,
919					     -1);
920
921	li = libinput_path_create_context(&simple_interface, NULL);
922	ck_assert_notnull(li);
923
924	device = libinput_path_add_device(li,
925					  libevdev_uinput_get_devnode(uinput));
926	ck_assert_notnull(device);
927
928	litest_drain_events(li);
929
930	libevdev_uinput_destroy(uinput);
931
932	libinput_dispatch(li);
933
934	event = libinput_get_event(li);
935	ck_assert_notnull(event);
936	litest_assert_event_type(event, LIBINPUT_EVENT_DEVICE_REMOVED);
937	libinput_event_destroy(event);
938
939	libinput_unref(li);
940}
941END_TEST
942
943START_TEST(path_seat_recycle)
944{
945	struct libinput *li;
946	struct libevdev_uinput *uinput;
947	int rc;
948	void *userdata = &rc;
949	struct libinput_event *ev;
950	struct libinput_device *device;
951	struct libinput_seat *saved_seat = NULL;
952	struct libinput_seat *seat;
953	int data = 0;
954	int found = 0;
955	void *user_data;
956	enum libinput_event_type type;
957
958	uinput = litest_create_uinput_device("test device", NULL,
959					     EV_KEY, BTN_LEFT,
960					     EV_KEY, BTN_RIGHT,
961					     EV_REL, REL_X,
962					     EV_REL, REL_Y,
963					     -1);
964
965	li = libinput_path_create_context(&simple_interface, userdata);
966	ck_assert_notnull(li);
967
968	device = libinput_path_add_device(li,
969					  libevdev_uinput_get_devnode(uinput));
970	ck_assert_notnull(device);
971
972	libinput_dispatch(li);
973
974	ev = libinput_get_event(li);
975	ck_assert_notnull(ev);
976	type = libinput_event_get_type(ev);
977	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
978	device = libinput_event_get_device(ev);
979	ck_assert_notnull(device);
980	saved_seat = libinput_device_get_seat(device);
981	libinput_seat_set_user_data(saved_seat, &data);
982	libinput_seat_ref(saved_seat);
983	libinput_event_destroy(ev);
984	ck_assert_notnull(saved_seat);
985
986	litest_assert_empty_queue(li);
987
988	libinput_suspend(li);
989
990	litest_drain_events(li);
991
992	libinput_resume(li);
993
994	libinput_dispatch(li);
995	ev = libinput_get_event(li);
996	ck_assert_notnull(ev);
997	type = libinput_event_get_type(ev);
998	ck_assert_int_eq(type, LIBINPUT_EVENT_DEVICE_ADDED);
999	device = libinput_event_get_device(ev);
1000	ck_assert_notnull(device);
1001
1002	seat = libinput_device_get_seat(device);
1003	user_data = libinput_seat_get_user_data(seat);
1004	if (user_data == &data) {
1005		found = 1;
1006		ck_assert(seat == saved_seat);
1007	}
1008
1009	libinput_event_destroy(ev);
1010	ck_assert(found == 1);
1011
1012	libinput_unref(li);
1013
1014	libevdev_uinput_destroy(uinput);
1015}
1016END_TEST
1017
1018START_TEST(path_udev_assign_seat)
1019{
1020	struct litest_device *dev = litest_current_device();
1021	struct libinput *li = dev->libinput;
1022	int rc;
1023
1024	litest_set_log_handler_bug(li);
1025	rc = libinput_udev_assign_seat(li, "foo");
1026	ck_assert_int_eq(rc, -1);
1027	litest_restore_log_handler(li);
1028}
1029END_TEST
1030
1031START_TEST(path_ignore_device)
1032{
1033	struct litest_device *dev;
1034	struct libinput *li;
1035	struct libinput_device *device;
1036	const char *path;
1037
1038	dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
1039	path = libevdev_uinput_get_devnode(dev->uinput);
1040	ck_assert_notnull(path);
1041
1042	li = litest_create_context();
1043	device = libinput_path_add_device(li, path);
1044	ck_assert(device == NULL);
1045
1046	litest_destroy_context(li);
1047	litest_delete_device(dev);
1048}
1049END_TEST
1050
1051TEST_COLLECTION(path)
1052{
1053	litest_add_no_device(path_create_NULL);
1054	litest_add_no_device(path_create_invalid);
1055	litest_add_no_device(path_create_invalid_file);
1056	litest_add_no_device(path_create_invalid_kerneldev);
1057	litest_add_no_device(path_create_pathmax_file);
1058	litest_add_no_device(path_create_destroy);
1059	litest_add(path_force_destroy, LITEST_ANY, LITEST_ANY);
1060	litest_add_no_device(path_set_user_data);
1061	litest_add_no_device(path_suspend);
1062	litest_add_no_device(path_double_suspend);
1063	litest_add_no_device(path_double_resume);
1064	litest_add_no_device(path_add_device_suspend_resume);
1065	litest_add_no_device(path_add_device_suspend_resume_fail);
1066	litest_add_no_device(path_add_device_suspend_resume_remove_device);
1067	litest_add_for_device(path_added_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
1068	litest_add_for_device(path_seat_change, LITEST_SYNAPTICS_CLICKPAD_X220);
1069	litest_add(path_added_device, LITEST_ANY, LITEST_ANY);
1070	litest_add(path_device_sysname, LITEST_ANY, LITEST_ANY);
1071	litest_add_for_device(path_add_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1072	litest_add_no_device(path_add_invalid_path);
1073	litest_add_for_device(path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1074	litest_add_for_device(path_double_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
1075	litest_add_no_device(path_device_gone);
1076	litest_add_no_device(path_seat_recycle);
1077	litest_add_for_device(path_udev_assign_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
1078
1079	litest_add_no_device(path_ignore_device);
1080}
1081