tizen 2.4 release
[framework/uifw/libevdev.git] / test / test-kernel.c
1 /*
2  * Copyright © 2014 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 <errno.h>
25 #include <inttypes.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <linux/input.h>
33
34 #include <libevdev/libevdev.h>
35 #include <libevdev/libevdev-uinput.h>
36 #include "test-common.h"
37
38 START_TEST(test_revoke)
39 {
40         struct uinput_device* uidev;
41         struct libevdev *dev, *dev2;
42         int rc, fd;
43         struct input_event ev1, ev2;
44         int dev_fd;
45
46         test_create_device(&uidev, &dev,
47                            EV_SYN, SYN_REPORT,
48                            EV_REL, REL_X,
49                            EV_REL, REL_Y,
50                            EV_REL, REL_WHEEL,
51                            EV_KEY, BTN_LEFT,
52                            EV_KEY, BTN_MIDDLE,
53                            EV_KEY, BTN_RIGHT,
54                            -1);
55
56         fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
57         ck_assert_int_gt(fd, -1);
58         rc = libevdev_new_from_fd(fd, &dev2);
59         ck_assert_msg(rc == 0, "Failed to create second device: %s", strerror(-rc));
60
61         uinput_device_event(uidev, EV_REL, REL_X, 1);
62         uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
63
64         rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
65         ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
66
67         rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
68         ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
69
70         ck_assert_int_eq(ev1.type, ev2.type);
71         ck_assert_int_eq(ev1.code, ev2.code);
72         ck_assert_int_eq(ev1.value, ev2.value);
73
74         /* revoke first device, expect it closed, second device still open */
75         dev_fd = libevdev_get_fd(dev);
76         ck_assert_int_ge(dev_fd, 0);
77         rc = ioctl(dev_fd, EVIOCREVOKE, NULL);
78         if (rc == -1 && errno == -EINVAL) {
79                 fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
80                 goto out;
81         }
82         ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
83
84         rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev1);
85         ck_assert_int_eq(rc, -ENODEV);
86
87         rc = libevdev_next_event(dev2, LIBEVDEV_READ_FLAG_NORMAL, &ev2);
88         ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SUCCESS);
89
90 out:
91         uinput_device_free(uidev);
92         libevdev_free(dev);
93         libevdev_free(dev2);
94         close(fd);
95 }
96 END_TEST
97
98 START_TEST(test_revoke_invalid)
99 {
100         struct uinput_device* uidev;
101         struct libevdev *dev;
102         int rc;
103         int dev_fd;
104
105         test_create_device(&uidev, &dev,
106                            EV_SYN, SYN_REPORT,
107                            EV_REL, REL_X,
108                            EV_REL, REL_Y,
109                            EV_REL, REL_WHEEL,
110                            EV_KEY, BTN_LEFT,
111                            EV_KEY, BTN_MIDDLE,
112                            EV_KEY, BTN_RIGHT,
113                            -1);
114
115         dev_fd = libevdev_get_fd(dev);
116         ck_assert_int_ge(dev_fd, 0);
117         /* ioctl requires 0 as value */
118         rc = ioctl(dev_fd, EVIOCREVOKE, 1);
119         ck_assert_int_eq(rc, -1);
120         ck_assert_int_eq(errno, EINVAL);
121
122         uinput_device_free(uidev);
123         libevdev_free(dev);
124 }
125 END_TEST
126
127 START_TEST(test_revoke_fail_after)
128 {
129         struct uinput_device* uidev;
130         struct libevdev *dev, *dev2 = NULL;
131         int rc, fd;
132
133         test_create_device(&uidev, &dev,
134                            EV_SYN, SYN_REPORT,
135                            EV_REL, REL_X,
136                            EV_REL, REL_Y,
137                            EV_REL, REL_WHEEL,
138                            EV_KEY, BTN_LEFT,
139                            EV_KEY, BTN_MIDDLE,
140                            EV_KEY, BTN_RIGHT,
141                            -1);
142
143         fd = open(uinput_device_get_devnode(uidev), O_RDONLY|O_NONBLOCK);
144         ck_assert_int_gt(fd, -1);
145
146         rc = ioctl(fd, EVIOCREVOKE, NULL);
147         if (rc == -1 && errno == -EINVAL) {
148                 fprintf(stderr, "WARNING: skipping EVIOCREVOKE test, not suported by current kernel\n");
149                 goto out;
150         }
151         ck_assert_msg(rc == 0, "Failed to revoke device: %s", strerror(errno));
152
153         rc = libevdev_new_from_fd(fd, &dev2);
154         ck_assert_int_eq(rc, -ENODEV);
155
156 out:
157         uinput_device_free(uidev);
158         libevdev_free(dev);
159         close(fd);
160 }
161 END_TEST
162
163 int main(int argc, char **argv)
164 {
165         SRunner *sr;
166         Suite *s;
167         TCase *tc;
168         int failed;
169
170         s = suite_create("kernel tests");
171
172         tc = tcase_create("EVIOCREVOKE");
173         tcase_add_test(tc, test_revoke);
174         tcase_add_test(tc, test_revoke_invalid);
175         tcase_add_test(tc, test_revoke_fail_after);
176         suite_add_tcase(s, tc);
177
178         sr = srunner_create(s);
179         srunner_run_all(sr, CK_NORMAL);
180
181         failed = srunner_ntests_failed(sr);
182         srunner_free(sr);
183
184         return failed;
185 }