01710f29d5c902e6d676aad9e55285cc1c9ca890
[platform/upstream/libevdev.git] / test / test-uinput.c
1 /*
2  * Copyright © 2013 Red Hat, Inc.
3  *
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.
13  *
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
20  * OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24 #include <linux/input.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <fcntl.h>
29 #include <libevdev/libevdev-uinput.h>
30
31 #include "test-common.h"
32 #define UINPUT_NODE "/dev/uinput"
33
34 START_TEST(test_uinput_create_device)
35 {
36         struct libevdev *dev, *dev2;
37         struct libevdev_uinput *uidev;
38         int fd, uinput_fd;
39         unsigned int type, code;
40         int rc;
41         const char *devnode;
42
43         dev = libevdev_new();
44         ck_assert(dev != NULL);
45         libevdev_set_name(dev, TEST_DEVICE_NAME);
46         libevdev_enable_event_type(dev, EV_SYN);
47         libevdev_enable_event_type(dev, EV_REL);
48         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
49         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
50         libevdev_enable_event_code(dev, EV_REL, REL_MAX, NULL);
51
52         rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
53         ck_assert_int_eq(rc, 0);
54         ck_assert(uidev != NULL);
55
56         uinput_fd = libevdev_uinput_get_fd(uidev);
57         ck_assert_int_gt(uinput_fd, -1);
58
59         devnode = libevdev_uinput_get_devnode(uidev);
60         ck_assert(devnode != NULL);
61
62         fd = open(devnode, O_RDONLY);
63         ck_assert_int_gt(fd, -1);
64         rc = libevdev_new_from_fd(fd, &dev2);
65         ck_assert_int_eq(rc, 0);
66
67         for (type = 0; type < EV_CNT; type++) {
68                 int max = libevdev_event_type_get_max(type);
69                 if (max == -1)
70                         continue;
71
72                 for (code = 0; code < (unsigned int)max; code++) {
73                         ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
74                                          libevdev_has_event_code(dev2, type, code));
75                 }
76         }
77
78         libevdev_free(dev);
79         libevdev_free(dev2);
80         libevdev_uinput_destroy(uidev);
81         close(fd);
82
83         /* uinput fd is managed, so make sure it did get closed */
84         ck_assert_int_eq(close(uinput_fd), -1);
85         ck_assert_int_eq(errno, EBADF);
86
87 }
88 END_TEST
89
90 START_TEST(test_uinput_create_device_invalid)
91 {
92         struct libevdev *dev;
93         struct libevdev_uinput *uidev = NULL;
94         int rc;
95
96         dev = libevdev_new();
97         ck_assert(dev != NULL);
98         libevdev_set_name(dev, TEST_DEVICE_NAME);
99         libevdev_enable_event_type(dev, EV_SYN);
100         libevdev_enable_event_type(dev, EV_REL);
101         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
102         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
103
104         libevdev_set_log_function(test_logfunc_ignore_error, NULL);
105         rc = libevdev_uinput_create_from_device(dev, -1, &uidev);
106         ck_assert_int_eq(rc, -EBADF);
107         ck_assert(uidev == NULL);
108         libevdev_set_log_function(test_logfunc_abort_on_error, NULL);
109
110         libevdev_free(dev);
111 }
112 END_TEST
113
114 START_TEST(test_uinput_create_device_from_fd)
115 {
116         struct libevdev *dev, *dev2;
117         struct libevdev_uinput *uidev;
118         int fd, fd2;
119         unsigned int type, code;
120         int rc;
121         const char *devnode;
122
123         dev = libevdev_new();
124         ck_assert(dev != NULL);
125         libevdev_set_name(dev, TEST_DEVICE_NAME);
126         libevdev_enable_event_type(dev, EV_SYN);
127         libevdev_enable_event_type(dev, EV_REL);
128         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
129         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
130
131         fd = open(UINPUT_NODE, O_RDWR);
132         ck_assert_int_gt(fd, -1);
133
134         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
135         ck_assert_int_eq(rc, 0);
136         ck_assert(uidev != NULL);
137
138         ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd);
139
140         devnode = libevdev_uinput_get_devnode(uidev);
141         ck_assert(devnode != NULL);
142
143         fd2 = open(devnode, O_RDONLY);
144         ck_assert_int_gt(fd2, -1);
145         rc = libevdev_new_from_fd(fd2, &dev2);
146         ck_assert_int_eq(rc, 0);
147
148         for (type = 0; type < EV_CNT; type++) {
149                 int max = libevdev_event_type_get_max(type);
150                 if (max == -1)
151                         continue;
152
153                 for (code = 0; code < (unsigned int)max; code++) {
154                         ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
155                                          libevdev_has_event_code(dev2, type, code));
156                 }
157         }
158
159         libevdev_free(dev);
160         libevdev_free(dev2);
161         libevdev_uinput_destroy(uidev);
162         close(fd);
163         close(fd2);
164 }
165 END_TEST
166
167 START_TEST(test_uinput_check_syspath_time)
168 {
169         struct libevdev *dev;
170         struct libevdev_uinput *uidev, *uidev2;
171         const char *syspath, *syspath2;
172         int fd, fd2;
173         int rc;
174
175         dev = libevdev_new();
176         ck_assert(dev != NULL);
177         libevdev_set_name(dev, TEST_DEVICE_NAME);
178         libevdev_enable_event_type(dev, EV_SYN);
179         libevdev_enable_event_type(dev, EV_REL);
180         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
181         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
182
183         fd = open(UINPUT_NODE, O_RDWR);
184         ck_assert_int_gt(fd, -1);
185         fd2 = open(UINPUT_NODE, O_RDWR);
186         ck_assert_int_gt(fd2, -1);
187
188         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
189         ck_assert_int_eq(rc, 0);
190
191         /* sleep for 1.5 seconds. sysfs resolution is 1 second, so
192            creating both devices without delay means
193            libevdev_uinput_get_syspath can't actually differ between
194            them. By waiting, we get different ctime for uidev and uidev2,
195            and exercise that part of the code.
196          */
197         usleep(1500000);
198
199         /* create a second one to test the syspath time filtering code */
200         rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
201         ck_assert_int_eq(rc, 0);
202
203         syspath = libevdev_uinput_get_syspath(uidev);
204         ck_assert(syspath != NULL);
205
206         /* get syspath twice returns same pointer */
207         syspath2 = libevdev_uinput_get_syspath(uidev);
208         ck_assert(syspath == syspath2);
209
210         /* second dev has different syspath */
211         syspath2 = libevdev_uinput_get_syspath(uidev2);
212         ck_assert(strcmp(syspath, syspath2) != 0);
213
214         libevdev_free(dev);
215         libevdev_uinput_destroy(uidev);
216         libevdev_uinput_destroy(uidev2);
217
218         close(fd);
219         close(fd2);
220 }
221 END_TEST
222
223 START_TEST(test_uinput_check_syspath_name)
224 {
225         struct libevdev *dev;
226         struct libevdev_uinput *uidev, *uidev2;
227         const char *syspath, *syspath2;
228         int fd, fd2;
229         int rc;
230
231         dev = libevdev_new();
232         ck_assert(dev != NULL);
233         libevdev_set_name(dev, TEST_DEVICE_NAME);
234         libevdev_enable_event_type(dev, EV_SYN);
235         libevdev_enable_event_type(dev, EV_REL);
236         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
237         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
238
239         fd = open(UINPUT_NODE, O_RDWR);
240         ck_assert_int_gt(fd, -1);
241         fd2 = open(UINPUT_NODE, O_RDWR);
242         ck_assert_int_gt(fd2, -1);
243
244         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
245         ck_assert_int_eq(rc, 0);
246
247         /* create a second one to stress the syspath filtering code */
248         libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
249         rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
250         ck_assert_int_eq(rc, 0);
251
252         syspath = libevdev_uinput_get_syspath(uidev);
253         ck_assert(syspath != NULL);
254
255         /* get syspath twice returns same pointer */
256         syspath2 = libevdev_uinput_get_syspath(uidev);
257         ck_assert(syspath == syspath2);
258
259         /* second dev has different syspath */
260         syspath2 = libevdev_uinput_get_syspath(uidev2);
261         ck_assert(strcmp(syspath, syspath2) != 0);
262
263         libevdev_free(dev);
264         libevdev_uinput_destroy(uidev);
265         libevdev_uinput_destroy(uidev2);
266
267         close(fd);
268         close(fd2);
269 }
270 END_TEST
271
272 START_TEST(test_uinput_events)
273 {
274         struct libevdev *dev;
275         struct libevdev_uinput *uidev;
276         int fd, fd2;
277         int rc;
278         const char *devnode;
279         int i;
280         const int nevents = 5;
281         struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1},
282                                         {{0, 0}, EV_REL, REL_Y, -1},
283                                         {{0, 0}, EV_SYN, SYN_REPORT, 0},
284                                         {{0, 0}, EV_KEY, BTN_LEFT, 1},
285                                         {{0, 0}, EV_SYN, SYN_REPORT, 0}};
286         struct input_event events_read[nevents];
287
288         dev = libevdev_new();
289         ck_assert(dev != NULL);
290         libevdev_set_name(dev, TEST_DEVICE_NAME);
291         libevdev_enable_event_type(dev, EV_SYN);
292         libevdev_enable_event_type(dev, EV_REL);
293         libevdev_enable_event_type(dev, EV_KEY);
294         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
295         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
296         libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
297
298         fd = open(UINPUT_NODE, O_RDWR);
299         ck_assert_int_gt(fd, -1);
300
301         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
302         ck_assert_int_eq(rc, 0);
303         ck_assert(uidev != NULL);
304
305         devnode = libevdev_uinput_get_devnode(uidev);
306         ck_assert(devnode != NULL);
307
308         fd2 = open(devnode, O_RDONLY);
309
310         for (i = 0; i < nevents; i++)
311                 libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value);
312
313         rc = read(fd2, events_read, sizeof(events_read));
314         ck_assert_int_eq(rc, sizeof(events_read));
315
316         for (i = 0; i < nevents; i++) {
317                 ck_assert_int_eq(events[i].type, events_read[i].type);
318                 ck_assert_int_eq(events[i].code, events_read[i].code);
319                 ck_assert_int_eq(events[i].value, events_read[i].value);
320         }
321
322         libevdev_free(dev);
323         libevdev_uinput_destroy(uidev);
324         close(fd);
325         close(fd2);
326 }
327 END_TEST
328
329 START_TEST(test_uinput_properties)
330 {
331         struct libevdev *dev, *dev2;
332         struct libevdev_uinput *uidev;
333         int fd;
334         int rc;
335         const char *devnode;
336
337         dev = libevdev_new();
338         ck_assert(dev != NULL);
339         libevdev_set_name(dev, TEST_DEVICE_NAME);
340         libevdev_enable_event_type(dev, EV_SYN);
341         libevdev_enable_event_type(dev, EV_REL);
342         libevdev_enable_event_type(dev, EV_KEY);
343         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
344         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
345         libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
346         libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
347         libevdev_enable_property(dev, INPUT_PROP_MAX);
348
349         rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
350         ck_assert_int_eq(rc, 0);
351         ck_assert(uidev != NULL);
352
353         devnode = libevdev_uinput_get_devnode(uidev);
354         ck_assert(devnode != NULL);
355
356         fd = open(devnode, O_RDONLY);
357         ck_assert_int_gt(fd, -1);
358         rc = libevdev_new_from_fd(fd, &dev2);
359         ck_assert_int_eq(rc, 0);
360
361         ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD));
362         ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX));
363
364         libevdev_free(dev);
365         libevdev_free(dev2);
366         libevdev_uinput_destroy(uidev);
367         close(fd);
368 }
369 END_TEST
370
371 TEST_SUITE_ROOT_PRIVILEGES(uinput_suite)
372 {
373         Suite *s = suite_create("libevdev uinput device tests");
374
375         add_test(s, test_uinput_create_device);
376         add_test(s, test_uinput_create_device_invalid);
377         add_test(s, test_uinput_create_device_from_fd);
378         add_test(s, test_uinput_check_syspath_time);
379         add_test(s, test_uinput_check_syspath_name);
380
381         add_test(s, test_uinput_events);
382
383         add_test(s, test_uinput_properties);
384
385         return s;
386 }