test: Make relative pointer event test more accepting
[platform/upstream/libinput.git] / test / udev.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include <config.h>
24
25 #include <check.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <libinput.h>
29 #include <libudev.h>
30 #include <unistd.h>
31
32 #include "litest.h"
33
34 static int open_restricted(const char *path, int flags, void *data)
35 {
36         int fd;
37         fd = open(path, flags);
38         return fd < 0 ? -errno : fd;
39 }
40 static void close_restricted(int fd, void *data)
41 {
42         close(fd);
43 }
44
45 const struct libinput_interface simple_interface = {
46         .open_restricted = open_restricted,
47         .close_restricted = close_restricted,
48 };
49
50
51 START_TEST(udev_create_NULL)
52 {
53         struct libinput *li;
54         const struct libinput_interface interface;
55         struct udev *udev = (struct udev*)0xdeadbeef;
56         const char *seat = (const char*)0xdeaddead;
57
58         li = libinput_udev_create_for_seat(NULL, NULL, NULL, NULL);
59         ck_assert(li == NULL);
60
61         li = libinput_udev_create_for_seat(&interface, NULL, NULL, NULL);
62         ck_assert(li == NULL);
63         li = libinput_udev_create_for_seat(NULL, NULL, udev, NULL);
64         ck_assert(li == NULL);
65         li = libinput_udev_create_for_seat(NULL, NULL, NULL, seat);
66         ck_assert(li == NULL);
67
68         li = libinput_udev_create_for_seat(&interface, NULL, udev, NULL);
69         ck_assert(li == NULL);
70         li = libinput_udev_create_for_seat(NULL, NULL, udev, seat);
71         ck_assert(li == NULL);
72
73         li = libinput_udev_create_for_seat(&interface, NULL, NULL, seat);
74         ck_assert(li == NULL);
75 }
76 END_TEST
77
78 START_TEST(udev_create_seat0)
79 {
80         struct libinput *li;
81         struct libinput_event *event;
82         struct udev *udev;
83         int fd;
84
85         udev = udev_new();
86         ck_assert(udev != NULL);
87
88         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
89         ck_assert(li != NULL);
90
91         fd = libinput_get_fd(li);
92         ck_assert_int_ge(fd, 0);
93
94         /* expect at least one event */
95         libinput_dispatch(li);
96         event = libinput_get_event(li);
97         ck_assert(event != NULL);
98
99         libinput_event_destroy(event);
100         libinput_destroy(li);
101         udev_unref(udev);
102 }
103 END_TEST
104
105 START_TEST(udev_create_empty_seat)
106 {
107         struct libinput *li;
108         struct libinput_event *event;
109         struct udev *udev;
110         int fd;
111
112         udev = udev_new();
113         ck_assert(udev != NULL);
114
115         /* expect a libinput reference, but no events */
116         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seatdoesntexist");
117         ck_assert(li != NULL);
118
119         fd = libinput_get_fd(li);
120         ck_assert_int_ge(fd, 0);
121
122         libinput_dispatch(li);
123         event = libinput_get_event(li);
124         ck_assert(event == NULL);
125
126         libinput_event_destroy(event);
127         libinput_destroy(li);
128         udev_unref(udev);
129 }
130 END_TEST
131
132 /**
133  * This test only works if there's at least one device in the system that is
134  * assigned the default seat. Should cover the 99% case.
135  */
136 START_TEST(udev_added_seat_default)
137 {
138         struct libinput *li;
139         struct libinput_event *event;
140         struct udev *udev;
141         struct libinput_device *device;
142         struct libinput_seat *seat;
143         const char *seat_name;
144         enum libinput_event_type type;
145         int default_seat_found = 0;
146
147         udev = udev_new();
148         ck_assert(udev != NULL);
149
150         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
151         ck_assert(li != NULL);
152         libinput_dispatch(li);
153
154         while (!default_seat_found && (event = libinput_get_event(li))) {
155                 type = libinput_event_get_type(event);
156                 if (type != LIBINPUT_EVENT_DEVICE_ADDED) {
157                         libinput_event_destroy(event);
158                         continue;
159                 }
160
161                 device = libinput_event_get_device(event);
162                 seat = libinput_device_get_seat(device);
163                 ck_assert(seat != NULL);
164
165                 seat_name = libinput_seat_get_logical_name(seat);
166                 default_seat_found = !strcmp(seat_name, "default");
167                 libinput_event_destroy(event);
168         }
169
170         ck_assert(default_seat_found);
171
172         libinput_destroy(li);
173         udev_unref(udev);
174 }
175 END_TEST
176
177 START_TEST(udev_double_suspend)
178 {
179         struct libinput *li;
180         struct libinput_event *event;
181         struct udev *udev;
182         int fd;
183
184         udev = udev_new();
185         ck_assert(udev != NULL);
186
187         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
188         ck_assert(li != NULL);
189
190         fd = libinput_get_fd(li);
191         ck_assert_int_ge(fd, 0);
192
193         /* expect at least one event */
194         ck_assert_int_ge(libinput_dispatch(li), 0);
195         event = libinput_get_event(li);
196         ck_assert(event != NULL);
197
198         libinput_suspend(li);
199         libinput_suspend(li);
200         libinput_resume(li);
201
202         libinput_event_destroy(event);
203         libinput_destroy(li);
204         udev_unref(udev);
205 }
206 END_TEST
207
208 START_TEST(udev_double_resume)
209 {
210         struct libinput *li;
211         struct libinput_event *event;
212         struct udev *udev;
213         int fd;
214
215         udev = udev_new();
216         ck_assert(udev != NULL);
217
218         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
219         ck_assert(li != NULL);
220
221         fd = libinput_get_fd(li);
222         ck_assert_int_ge(fd, 0);
223
224         /* expect at least one event */
225         ck_assert_int_ge(libinput_dispatch(li), 0);
226         event = libinput_get_event(li);
227         ck_assert(event != NULL);
228
229         libinput_suspend(li);
230         libinput_resume(li);
231         libinput_resume(li);
232
233         libinput_event_destroy(event);
234         libinput_destroy(li);
235         udev_unref(udev);
236 }
237 END_TEST
238
239 static void
240 process_events_count_devices(struct libinput *li, int *device_count)
241 {
242         struct libinput_event *event;
243
244         while ((event = libinput_get_event(li))) {
245                 switch (libinput_event_get_type(event)) {
246                 case LIBINPUT_EVENT_DEVICE_ADDED:
247                         (*device_count)++;
248                         break;
249                 case LIBINPUT_EVENT_DEVICE_REMOVED:
250                         (*device_count)--;
251                         break;
252                 default:
253                         break;
254                 }
255                 libinput_event_destroy(event);
256         }
257 }
258
259 START_TEST(udev_suspend_resume)
260 {
261         struct libinput *li;
262         struct udev *udev;
263         int fd;
264         int num_devices = 0;
265
266         udev = udev_new();
267         ck_assert(udev != NULL);
268
269         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
270         ck_assert(li != NULL);
271
272         fd = libinput_get_fd(li);
273         ck_assert_int_ge(fd, 0);
274
275         /* Check that at least one device was discovered after creation. */
276         ck_assert_int_ge(libinput_dispatch(li), 0);
277         process_events_count_devices(li, &num_devices);
278         ck_assert_int_gt(num_devices, 0);
279
280         /* Check that after a suspend, no devices are left. */
281         libinput_suspend(li);
282         ck_assert_int_ge(libinput_dispatch(li), 0);
283         process_events_count_devices(li, &num_devices);
284         ck_assert_int_eq(num_devices, 0);
285
286         /* Check that after a resume, at least one device is discovered. */
287         libinput_resume(li);
288         ck_assert_int_ge(libinput_dispatch(li), 0);
289         process_events_count_devices(li, &num_devices);
290         ck_assert_int_gt(num_devices, 0);
291
292         libinput_destroy(li);
293         udev_unref(udev);
294 }
295 END_TEST
296
297 START_TEST(udev_device_sysname)
298 {
299         struct libinput *li;
300         struct libinput_event *ev;
301         struct libinput_device *device;
302         const char *sysname;
303         struct udev *udev;
304
305         udev = udev_new();
306         ck_assert(udev != NULL);
307
308         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
309         ck_assert(li != NULL);
310
311         libinput_dispatch(li);
312
313         while ((ev = libinput_get_event(li))) {
314                 if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED)
315                         continue;
316
317                 device = libinput_event_get_device(ev);
318                 sysname = libinput_device_get_sysname(device);
319                 ck_assert(sysname != NULL && strlen(sysname) > 1);
320                 ck_assert(strchr(sysname, '/') == NULL);
321                 ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
322                 libinput_event_destroy(ev);
323         }
324
325         libinput_destroy(li);
326         udev_unref(udev);
327 }
328 END_TEST
329
330 START_TEST(udev_seat_recycle)
331 {
332         struct udev *udev;
333         struct libinput *li;
334         struct libinput_event *ev;
335         struct libinput_device *device;
336         struct libinput_seat *saved_seat = NULL;
337         struct libinput_seat *seat;
338         int data = 0;
339         int found = 0;
340         void *user_data;
341
342         udev = udev_new();
343         ck_assert(udev != NULL);
344
345         li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0");
346         ck_assert(li != NULL);
347
348         libinput_dispatch(li);
349         while ((ev = libinput_get_event(li))) {
350                 switch (libinput_event_get_type(ev)) {
351                 case LIBINPUT_EVENT_DEVICE_ADDED:
352                         if (saved_seat)
353                                 break;
354
355                         device = libinput_event_get_device(ev);
356                         ck_assert(device != NULL);
357                         saved_seat = libinput_device_get_seat(device);
358                         libinput_seat_set_user_data(saved_seat, &data);
359                         libinput_seat_ref(saved_seat);
360                         break;
361                 default:
362                         break;
363                 }
364
365                 libinput_event_destroy(ev);
366         }
367
368         ck_assert(saved_seat != NULL);
369
370         libinput_suspend(li);
371
372         litest_drain_events(li);
373
374         libinput_resume(li);
375
376         libinput_dispatch(li);
377         while ((ev = libinput_get_event(li))) {
378                 switch (libinput_event_get_type(ev)) {
379                 case LIBINPUT_EVENT_DEVICE_ADDED:
380                         device = libinput_event_get_device(ev);
381                         ck_assert(device != NULL);
382
383                         seat = libinput_device_get_seat(device);
384                         user_data = libinput_seat_get_user_data(seat);
385                         if (user_data == &data) {
386                                 found = 1;
387                                 ck_assert(seat == saved_seat);
388                         }
389                         break;
390                 default:
391                         break;
392                 }
393
394                 libinput_event_destroy(ev);
395         }
396
397         ck_assert(found == 1);
398
399         libinput_destroy(li);
400         udev_unref(udev);
401 }
402 END_TEST
403
404 int main (int argc, char **argv) {
405
406         litest_add_no_device("udev:create", udev_create_NULL);
407         litest_add_no_device("udev:create", udev_create_seat0);
408         litest_add_no_device("udev:create", udev_create_empty_seat);
409
410         litest_add_no_device("udev:seat events", udev_added_seat_default);
411
412         litest_add("udev:suspend", udev_double_suspend, LITEST_ANY, LITEST_ANY);
413         litest_add("udev:suspend", udev_double_resume, LITEST_ANY, LITEST_ANY);
414         litest_add("udev:suspend", udev_suspend_resume, LITEST_ANY, LITEST_ANY);
415         litest_add("udev:device events", udev_device_sysname, LITEST_ANY, LITEST_ANY);
416         litest_add("udev:seat", udev_seat_recycle, LITEST_ANY, LITEST_ANY);
417
418         return litest_run(argc, argv);
419 }