Drop semicolons after getter/setter macros
[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 < 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         rc = libevdev_uinput_create_from_device(dev, -1, &uidev);
105         ck_assert_int_eq(rc, -EBADF);
106         ck_assert(uidev == NULL);
107
108         libevdev_free(dev);
109 }
110 END_TEST
111
112 START_TEST(test_uinput_create_device_from_fd)
113 {
114         struct libevdev *dev, *dev2;
115         struct libevdev_uinput *uidev;
116         int fd, fd2;
117         unsigned int type, code;
118         int rc;
119         const char *devnode;
120
121         dev = libevdev_new();
122         ck_assert(dev != NULL);
123         libevdev_set_name(dev, TEST_DEVICE_NAME);
124         libevdev_enable_event_type(dev, EV_SYN);
125         libevdev_enable_event_type(dev, EV_REL);
126         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
127         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
128
129         fd = open(UINPUT_NODE, O_RDWR);
130         ck_assert_int_gt(fd, -1);
131
132         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
133         ck_assert_int_eq(rc, 0);
134         ck_assert(uidev != NULL);
135
136         ck_assert_int_eq(libevdev_uinput_get_fd(uidev), fd);
137
138         devnode = libevdev_uinput_get_devnode(uidev);
139         ck_assert(devnode != NULL);
140
141         fd2 = open(devnode, O_RDONLY);
142         ck_assert_int_gt(fd2, -1);
143         rc = libevdev_new_from_fd(fd2, &dev2);
144         ck_assert_int_eq(rc, 0);
145
146         for (type = 0; type < EV_CNT; type++) {
147                 int max = libevdev_event_type_get_max(type);
148                 if (max == -1)
149                         continue;
150
151                 for (code = 0; code < max; code++) {
152                         ck_assert_int_eq(libevdev_has_event_code(dev, type, code),
153                                          libevdev_has_event_code(dev2, type, code));
154                 }
155         }
156
157         libevdev_free(dev);
158         libevdev_free(dev2);
159         libevdev_uinput_destroy(uidev);
160         close(fd);
161         close(fd2);
162 }
163 END_TEST
164
165 START_TEST(test_uinput_check_syspath_time)
166 {
167         struct libevdev *dev;
168         struct libevdev_uinput *uidev, *uidev2;
169         const char *syspath, *syspath2;
170         int fd, fd2;
171         int rc;
172
173         dev = libevdev_new();
174         ck_assert(dev != NULL);
175         libevdev_set_name(dev, TEST_DEVICE_NAME);
176         libevdev_enable_event_type(dev, EV_SYN);
177         libevdev_enable_event_type(dev, EV_REL);
178         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
179         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
180
181         fd = open(UINPUT_NODE, O_RDWR);
182         ck_assert_int_gt(fd, -1);
183         fd2 = open(UINPUT_NODE, O_RDWR);
184         ck_assert_int_gt(fd2, -1);
185
186         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
187         ck_assert_int_eq(rc, 0);
188
189         /* sleep for 1.5 seconds. sysfs resolution is 1 second, so
190            creating both devices without delay means
191            libevdev_uinput_get_syspath can't actually differ between
192            them. By waiting, we get different ctime for uidev and uidev2,
193            and exercise that part of the code.
194          */
195         usleep(1500000);
196
197         /* create a second one to test the syspath time filtering code */
198         rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
199         ck_assert_int_eq(rc, 0);
200
201         syspath = libevdev_uinput_get_syspath(uidev);
202         ck_assert(syspath != NULL);
203
204         /* get syspath twice returns same pointer */
205         syspath2 = libevdev_uinput_get_syspath(uidev);
206         ck_assert(syspath == syspath2);
207
208         /* second dev has different syspath */
209         syspath2 = libevdev_uinput_get_syspath(uidev2);
210         ck_assert(strcmp(syspath, syspath2) != 0);
211
212         libevdev_free(dev);
213         libevdev_uinput_destroy(uidev);
214         libevdev_uinput_destroy(uidev2);
215
216         close(fd);
217         close(fd2);
218 }
219 END_TEST
220
221 START_TEST(test_uinput_check_syspath_name)
222 {
223         struct libevdev *dev;
224         struct libevdev_uinput *uidev, *uidev2;
225         const char *syspath, *syspath2;
226         int fd, fd2;
227         int rc;
228
229         dev = libevdev_new();
230         ck_assert(dev != NULL);
231         libevdev_set_name(dev, TEST_DEVICE_NAME);
232         libevdev_enable_event_type(dev, EV_SYN);
233         libevdev_enable_event_type(dev, EV_REL);
234         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
235         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
236
237         fd = open(UINPUT_NODE, O_RDWR);
238         ck_assert_int_gt(fd, -1);
239         fd2 = open(UINPUT_NODE, O_RDWR);
240         ck_assert_int_gt(fd2, -1);
241
242         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
243         ck_assert_int_eq(rc, 0);
244
245         /* create a second one to stress the syspath filtering code */
246         libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
247         rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
248         ck_assert_int_eq(rc, 0);
249
250         syspath = libevdev_uinput_get_syspath(uidev);
251         ck_assert(syspath != NULL);
252
253         /* get syspath twice returns same pointer */
254         syspath2 = libevdev_uinput_get_syspath(uidev);
255         ck_assert(syspath == syspath2);
256
257         /* second dev has different syspath */
258         syspath2 = libevdev_uinput_get_syspath(uidev2);
259         ck_assert(strcmp(syspath, syspath2) != 0);
260
261         libevdev_free(dev);
262         libevdev_uinput_destroy(uidev);
263         libevdev_uinput_destroy(uidev2);
264
265         close(fd);
266         close(fd2);
267 }
268 END_TEST
269
270 START_TEST(test_uinput_events)
271 {
272         struct libevdev *dev;
273         struct libevdev_uinput *uidev;
274         int fd, fd2;
275         int rc;
276         const char *devnode;
277         int i;
278         const int nevents = 5;
279         struct input_event events[] = { {{0, 0}, EV_REL, REL_X, 1},
280                                         {{0, 0}, EV_REL, REL_Y, -1},
281                                         {{0, 0}, EV_SYN, SYN_REPORT, 0},
282                                         {{0, 0}, EV_KEY, BTN_LEFT, 1},
283                                         {{0, 0}, EV_SYN, SYN_REPORT, 0}};
284         struct input_event events_read[nevents];
285
286         dev = libevdev_new();
287         ck_assert(dev != NULL);
288         libevdev_set_name(dev, TEST_DEVICE_NAME);
289         libevdev_enable_event_type(dev, EV_SYN);
290         libevdev_enable_event_type(dev, EV_REL);
291         libevdev_enable_event_type(dev, EV_KEY);
292         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
293         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
294         libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
295
296         fd = open(UINPUT_NODE, O_RDWR);
297         ck_assert_int_gt(fd, -1);
298
299         rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
300         ck_assert_int_eq(rc, 0);
301         ck_assert(uidev != NULL);
302
303         devnode = libevdev_uinput_get_devnode(uidev);
304         ck_assert(devnode != NULL);
305
306         fd2 = open(devnode, O_RDONLY);
307
308         for (i = 0; i < nevents; i++)
309                 libevdev_uinput_write_event(uidev, events[i].type, events[i].code, events[i].value);
310
311         rc = read(fd2, events_read, sizeof(events_read));
312         ck_assert_int_eq(rc, sizeof(events_read));
313
314         for (i = 0; i < nevents; i++) {
315                 ck_assert_int_eq(events[i].type, events_read[i].type);
316                 ck_assert_int_eq(events[i].code, events_read[i].code);
317                 ck_assert_int_eq(events[i].value, events_read[i].value);
318         }
319
320         libevdev_free(dev);
321         libevdev_uinput_destroy(uidev);
322         close(fd);
323         close(fd2);
324 }
325 END_TEST
326
327 START_TEST(test_uinput_properties)
328 {
329         struct libevdev *dev, *dev2;
330         struct libevdev_uinput *uidev;
331         int fd;
332         int rc;
333         const char *devnode;
334
335         dev = libevdev_new();
336         ck_assert(dev != NULL);
337         libevdev_set_name(dev, TEST_DEVICE_NAME);
338         libevdev_enable_event_type(dev, EV_SYN);
339         libevdev_enable_event_type(dev, EV_REL);
340         libevdev_enable_event_type(dev, EV_KEY);
341         libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
342         libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
343         libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL);
344         libevdev_enable_property(dev, INPUT_PROP_BUTTONPAD);
345         libevdev_enable_property(dev, INPUT_PROP_MAX);
346
347         rc = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev);
348         ck_assert_int_eq(rc, 0);
349         ck_assert(uidev != NULL);
350
351         devnode = libevdev_uinput_get_devnode(uidev);
352         ck_assert(devnode != NULL);
353
354         fd = open(devnode, O_RDONLY);
355         ck_assert_int_gt(fd, -1);
356         rc = libevdev_new_from_fd(fd, &dev2);
357         ck_assert_int_eq(rc, 0);
358
359         ck_assert(libevdev_has_property(dev2, INPUT_PROP_BUTTONPAD));
360         ck_assert(libevdev_has_property(dev2, INPUT_PROP_MAX));
361
362         libevdev_free(dev);
363         libevdev_free(dev2);
364         libevdev_uinput_destroy(uidev);
365         close(fd);
366 }
367 END_TEST
368
369 Suite *
370 uinput_suite(void)
371 {
372         Suite *s = suite_create("libevdev uinput device tests");
373
374         TCase *tc = tcase_create("device creation");
375         tcase_add_test(tc, test_uinput_create_device);
376         tcase_add_test(tc, test_uinput_create_device_invalid);
377         tcase_add_test(tc, test_uinput_create_device_from_fd);
378         tcase_add_test(tc, test_uinput_check_syspath_time);
379         tcase_add_test(tc, test_uinput_check_syspath_name);
380         suite_add_tcase(s, tc);
381
382         tc = tcase_create("device events");
383         tcase_add_test(tc, test_uinput_events);
384         suite_add_tcase(s, tc);
385
386         tc = tcase_create("device properties");
387         tcase_add_test(tc, test_uinput_properties);
388         suite_add_tcase(s, tc);
389
390         return s;
391 }