style fix: Remove duplicate empty lines
[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 START_TEST(udev_create_NULL)
51 {
52         struct libinput *li;
53         const struct libinput_interface interface;
54         struct udev *udev;
55
56         udev = udev_new();
57
58         li = libinput_udev_create_context(NULL, NULL, NULL);
59         ck_assert(li == NULL);
60
61         li = libinput_udev_create_context(&interface, NULL, NULL);
62         ck_assert(li == NULL);
63
64         li = libinput_udev_create_context(NULL, NULL, udev);
65         ck_assert(li == NULL);
66
67         li = libinput_udev_create_context(&interface, NULL, udev);
68         ck_assert(li != NULL);
69         ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1);
70
71         libinput_unref(li);
72         udev_unref(udev);
73 }
74 END_TEST
75
76 START_TEST(udev_create_seat0)
77 {
78         struct libinput *li;
79         struct libinput_event *event;
80         struct udev *udev;
81         int fd;
82
83         udev = udev_new();
84         ck_assert(udev != NULL);
85
86         li = libinput_udev_create_context(&simple_interface, NULL, udev);
87         ck_assert(li != NULL);
88         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
89
90         fd = libinput_get_fd(li);
91         ck_assert_int_ge(fd, 0);
92
93         /* expect at least one event */
94         libinput_dispatch(li);
95         event = libinput_get_event(li);
96         ck_assert(event != NULL);
97
98         libinput_event_destroy(event);
99         libinput_unref(li);
100         udev_unref(udev);
101 }
102 END_TEST
103
104 START_TEST(udev_create_empty_seat)
105 {
106         struct libinput *li;
107         struct libinput_event *event;
108         struct udev *udev;
109         int fd;
110
111         udev = udev_new();
112         ck_assert(udev != NULL);
113
114         /* expect a libinput reference, but no events */
115         li = libinput_udev_create_context(&simple_interface, NULL, udev);
116         ck_assert(li != NULL);
117         ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0);
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_unref(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_context(&simple_interface, NULL, udev);
151         ck_assert(li != NULL);
152         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
153         libinput_dispatch(li);
154
155         while (!default_seat_found && (event = libinput_get_event(li))) {
156                 type = libinput_event_get_type(event);
157                 if (type != LIBINPUT_EVENT_DEVICE_ADDED) {
158                         libinput_event_destroy(event);
159                         continue;
160                 }
161
162                 device = libinput_event_get_device(event);
163                 seat = libinput_device_get_seat(device);
164                 ck_assert(seat != NULL);
165
166                 seat_name = libinput_seat_get_logical_name(seat);
167                 default_seat_found = !strcmp(seat_name, "default");
168                 libinput_event_destroy(event);
169         }
170
171         ck_assert(default_seat_found);
172
173         libinput_unref(li);
174         udev_unref(udev);
175 }
176 END_TEST
177
178 START_TEST(udev_double_suspend)
179 {
180         struct libinput *li;
181         struct libinput_event *event;
182         struct udev *udev;
183         int fd;
184
185         udev = udev_new();
186         ck_assert(udev != NULL);
187
188         li = libinput_udev_create_context(&simple_interface, NULL, udev);
189         ck_assert(li != NULL);
190         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
191
192         fd = libinput_get_fd(li);
193         ck_assert_int_ge(fd, 0);
194
195         /* expect at least one event */
196         ck_assert_int_ge(libinput_dispatch(li), 0);
197         event = libinput_get_event(li);
198         ck_assert(event != NULL);
199
200         libinput_suspend(li);
201         libinput_suspend(li);
202         libinput_resume(li);
203
204         libinput_event_destroy(event);
205         libinput_unref(li);
206         udev_unref(udev);
207 }
208 END_TEST
209
210 START_TEST(udev_double_resume)
211 {
212         struct libinput *li;
213         struct libinput_event *event;
214         struct udev *udev;
215         int fd;
216
217         udev = udev_new();
218         ck_assert(udev != NULL);
219
220         li = libinput_udev_create_context(&simple_interface, NULL, udev);
221         ck_assert(li != NULL);
222         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
223
224         fd = libinput_get_fd(li);
225         ck_assert_int_ge(fd, 0);
226
227         /* expect at least one event */
228         ck_assert_int_ge(libinput_dispatch(li), 0);
229         event = libinput_get_event(li);
230         ck_assert(event != NULL);
231
232         libinput_suspend(li);
233         libinput_resume(li);
234         libinput_resume(li);
235
236         libinput_event_destroy(event);
237         libinput_unref(li);
238         udev_unref(udev);
239 }
240 END_TEST
241
242 static void
243 process_events_count_devices(struct libinput *li, int *device_count)
244 {
245         struct libinput_event *event;
246
247         while ((event = libinput_get_event(li))) {
248                 switch (libinput_event_get_type(event)) {
249                 case LIBINPUT_EVENT_DEVICE_ADDED:
250                         (*device_count)++;
251                         break;
252                 case LIBINPUT_EVENT_DEVICE_REMOVED:
253                         (*device_count)--;
254                         break;
255                 default:
256                         break;
257                 }
258                 libinput_event_destroy(event);
259         }
260 }
261
262 START_TEST(udev_suspend_resume)
263 {
264         struct libinput *li;
265         struct udev *udev;
266         int fd;
267         int num_devices = 0;
268
269         udev = udev_new();
270         ck_assert(udev != NULL);
271
272         li = libinput_udev_create_context(&simple_interface, NULL, udev);
273         ck_assert(li != NULL);
274         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
275
276         fd = libinput_get_fd(li);
277         ck_assert_int_ge(fd, 0);
278
279         /* Check that at least one device was discovered after creation. */
280         ck_assert_int_ge(libinput_dispatch(li), 0);
281         process_events_count_devices(li, &num_devices);
282         ck_assert_int_gt(num_devices, 0);
283
284         /* Check that after a suspend, no devices are left. */
285         libinput_suspend(li);
286         ck_assert_int_ge(libinput_dispatch(li), 0);
287         process_events_count_devices(li, &num_devices);
288         ck_assert_int_eq(num_devices, 0);
289
290         /* Check that after a resume, at least one device is discovered. */
291         libinput_resume(li);
292         ck_assert_int_ge(libinput_dispatch(li), 0);
293         process_events_count_devices(li, &num_devices);
294         ck_assert_int_gt(num_devices, 0);
295
296         libinput_unref(li);
297         udev_unref(udev);
298 }
299 END_TEST
300
301 START_TEST(udev_device_sysname)
302 {
303         struct libinput *li;
304         struct libinput_event *ev;
305         struct libinput_device *device;
306         const char *sysname;
307         struct udev *udev;
308
309         udev = udev_new();
310         ck_assert(udev != NULL);
311
312         li = libinput_udev_create_context(&simple_interface, NULL, udev);
313         ck_assert(li != NULL);
314         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
315
316         libinput_dispatch(li);
317
318         while ((ev = libinput_get_event(li))) {
319                 if (libinput_event_get_type(ev) != LIBINPUT_EVENT_DEVICE_ADDED)
320                         continue;
321
322                 device = libinput_event_get_device(ev);
323                 sysname = libinput_device_get_sysname(device);
324                 ck_assert(sysname != NULL && strlen(sysname) > 1);
325                 ck_assert(strchr(sysname, '/') == NULL);
326                 ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
327                 libinput_event_destroy(ev);
328         }
329
330         libinput_unref(li);
331         udev_unref(udev);
332 }
333 END_TEST
334
335 START_TEST(udev_seat_recycle)
336 {
337         struct udev *udev;
338         struct libinput *li;
339         struct libinput_event *ev;
340         struct libinput_device *device;
341         struct libinput_seat *saved_seat = NULL;
342         struct libinput_seat *seat;
343         int data = 0;
344         int found = 0;
345         void *user_data;
346
347         udev = udev_new();
348         ck_assert(udev != NULL);
349
350         li = libinput_udev_create_context(&simple_interface, NULL, udev);
351         ck_assert(li != NULL);
352         ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
353
354         libinput_dispatch(li);
355         while ((ev = libinput_get_event(li))) {
356                 switch (libinput_event_get_type(ev)) {
357                 case LIBINPUT_EVENT_DEVICE_ADDED:
358                         if (saved_seat)
359                                 break;
360
361                         device = libinput_event_get_device(ev);
362                         ck_assert(device != NULL);
363                         saved_seat = libinput_device_get_seat(device);
364                         libinput_seat_set_user_data(saved_seat, &data);
365                         libinput_seat_ref(saved_seat);
366                         break;
367                 default:
368                         break;
369                 }
370
371                 libinput_event_destroy(ev);
372         }
373
374         ck_assert(saved_seat != NULL);
375
376         libinput_suspend(li);
377
378         litest_drain_events(li);
379
380         libinput_resume(li);
381
382         libinput_dispatch(li);
383         while ((ev = libinput_get_event(li))) {
384                 switch (libinput_event_get_type(ev)) {
385                 case LIBINPUT_EVENT_DEVICE_ADDED:
386                         device = libinput_event_get_device(ev);
387                         ck_assert(device != NULL);
388
389                         seat = libinput_device_get_seat(device);
390                         user_data = libinput_seat_get_user_data(seat);
391                         if (user_data == &data) {
392                                 found = 1;
393                                 ck_assert(seat == saved_seat);
394                         }
395                         break;
396                 default:
397                         break;
398                 }
399
400                 libinput_event_destroy(ev);
401         }
402
403         ck_assert(found == 1);
404
405         libinput_unref(li);
406         udev_unref(udev);
407 }
408 END_TEST
409
410 int main (int argc, char **argv) {
411
412         litest_add_no_device("udev:create", udev_create_NULL);
413         litest_add_no_device("udev:create", udev_create_seat0);
414         litest_add_no_device("udev:create", udev_create_empty_seat);
415
416         litest_add_no_device("udev:seat events", udev_added_seat_default);
417
418         litest_add("udev:suspend", udev_double_suspend, LITEST_ANY, LITEST_ANY);
419         litest_add("udev:suspend", udev_double_resume, LITEST_ANY, LITEST_ANY);
420         litest_add("udev:suspend", udev_suspend_resume, LITEST_ANY, LITEST_ANY);
421         litest_add("udev:device events", udev_device_sysname, LITEST_ANY, LITEST_ANY);
422         litest_add("udev:seat", udev_seat_recycle, LITEST_ANY, LITEST_ANY);
423
424         return litest_run(argc, argv);
425 }