1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * KUnit test for the input core. |
4 | * |
5 | * Copyright (c) 2023 Red Hat Inc |
6 | */ |
7 | |
8 | #include <linux/delay.h> |
9 | #include <linux/input.h> |
10 | |
11 | #include <kunit/test.h> |
12 | |
13 | #define POLL_INTERVAL 100 |
14 | |
15 | static int input_test_init(struct kunit *test) |
16 | { |
17 | struct input_dev *input_dev; |
18 | int ret; |
19 | |
20 | input_dev = input_allocate_device(); |
21 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev); |
22 | |
23 | input_dev->name = "Test input device" ; |
24 | input_dev->id.bustype = BUS_VIRTUAL; |
25 | input_dev->id.vendor = 1; |
26 | input_dev->id.product = 1; |
27 | input_dev->id.version = 1; |
28 | input_set_capability(dev: input_dev, EV_KEY, BTN_LEFT); |
29 | input_set_capability(dev: input_dev, EV_KEY, BTN_RIGHT); |
30 | |
31 | ret = input_register_device(input_dev); |
32 | if (ret) { |
33 | input_free_device(dev: input_dev); |
34 | KUNIT_ASSERT_FAILURE(test, "Register device failed: %d" , ret); |
35 | } |
36 | |
37 | test->priv = input_dev; |
38 | |
39 | return 0; |
40 | } |
41 | |
42 | static void input_test_exit(struct kunit *test) |
43 | { |
44 | struct input_dev *input_dev = test->priv; |
45 | |
46 | if (input_dev) |
47 | input_unregister_device(input_dev); |
48 | } |
49 | |
50 | static void input_test_poll(struct input_dev *input) { } |
51 | |
52 | static void input_test_polling(struct kunit *test) |
53 | { |
54 | struct input_dev *input_dev = test->priv; |
55 | |
56 | /* Must fail because a poll handler has not been set-up yet */ |
57 | KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), -EINVAL); |
58 | |
59 | KUNIT_ASSERT_EQ(test, input_setup_polling(input_dev, input_test_poll), 0); |
60 | |
61 | input_set_poll_interval(dev: input_dev, POLL_INTERVAL); |
62 | |
63 | /* Must succeed because poll handler was set-up and poll interval set */ |
64 | KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), POLL_INTERVAL); |
65 | } |
66 | |
67 | static void input_test_timestamp(struct kunit *test) |
68 | { |
69 | const ktime_t invalid_timestamp = ktime_set(secs: 0, nsecs: 0); |
70 | struct input_dev *input_dev = test->priv; |
71 | ktime_t *timestamp, time; |
72 | |
73 | timestamp = input_get_timestamp(dev: input_dev); |
74 | time = timestamp[INPUT_CLK_MONO]; |
75 | |
76 | /* The returned timestamp must always be valid */ |
77 | KUNIT_ASSERT_EQ(test, ktime_compare(time, invalid_timestamp), 1); |
78 | |
79 | time = ktime_get(); |
80 | input_set_timestamp(dev: input_dev, timestamp: time); |
81 | |
82 | timestamp = input_get_timestamp(dev: input_dev); |
83 | /* The timestamp must be the same than set before */ |
84 | KUNIT_ASSERT_EQ(test, ktime_compare(timestamp[INPUT_CLK_MONO], time), 0); |
85 | } |
86 | |
87 | static void input_test_match_device_id(struct kunit *test) |
88 | { |
89 | struct input_dev *input_dev = test->priv; |
90 | struct input_device_id id = { 0 }; |
91 | |
92 | /* |
93 | * Must match when the input device bus, vendor, product, version |
94 | * and events capable of handling are the same and fail to match |
95 | * otherwise. |
96 | */ |
97 | id.flags = INPUT_DEVICE_ID_MATCH_BUS; |
98 | id.bustype = BUS_VIRTUAL; |
99 | KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); |
100 | |
101 | id.bustype = BUS_I2C; |
102 | KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); |
103 | |
104 | id.flags = INPUT_DEVICE_ID_MATCH_VENDOR; |
105 | id.vendor = 1; |
106 | KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); |
107 | |
108 | id.vendor = 2; |
109 | KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); |
110 | |
111 | id.flags = INPUT_DEVICE_ID_MATCH_PRODUCT; |
112 | id.product = 1; |
113 | KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); |
114 | |
115 | id.product = 2; |
116 | KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); |
117 | |
118 | id.flags = INPUT_DEVICE_ID_MATCH_VERSION; |
119 | id.version = 1; |
120 | KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); |
121 | |
122 | id.version = 2; |
123 | KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); |
124 | |
125 | id.flags = INPUT_DEVICE_ID_MATCH_EVBIT; |
126 | __set_bit(EV_KEY, id.evbit); |
127 | KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); |
128 | |
129 | __set_bit(EV_ABS, id.evbit); |
130 | KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); |
131 | } |
132 | |
133 | static void input_test_grab(struct kunit *test) |
134 | { |
135 | struct input_dev *input_dev = test->priv; |
136 | struct input_handle test_handle; |
137 | struct input_handler handler; |
138 | struct input_handle handle; |
139 | struct input_device_id id; |
140 | int res; |
141 | |
142 | handler.name = "handler" ; |
143 | handler.id_table = &id; |
144 | |
145 | handle.dev = input_get_device(dev: input_dev); |
146 | handle.name = dev_name(dev: &input_dev->dev); |
147 | handle.handler = &handler; |
148 | res = input_grab_device(&handle); |
149 | KUNIT_ASSERT_TRUE(test, res == 0); |
150 | |
151 | test_handle.dev = input_get_device(dev: input_dev); |
152 | test_handle.name = dev_name(dev: &input_dev->dev); |
153 | test_handle.handler = &handler; |
154 | res = input_grab_device(&test_handle); |
155 | KUNIT_ASSERT_EQ(test, res, -EBUSY); |
156 | |
157 | input_release_device(&handle); |
158 | input_put_device(dev: input_dev); |
159 | res = input_grab_device(&test_handle); |
160 | KUNIT_ASSERT_TRUE(test, res == 0); |
161 | input_put_device(dev: input_dev); |
162 | } |
163 | |
164 | static struct kunit_case input_tests[] = { |
165 | KUNIT_CASE(input_test_polling), |
166 | KUNIT_CASE(input_test_timestamp), |
167 | KUNIT_CASE(input_test_match_device_id), |
168 | KUNIT_CASE(input_test_grab), |
169 | { /* sentinel */ } |
170 | }; |
171 | |
172 | static struct kunit_suite input_test_suite = { |
173 | .name = "input_core" , |
174 | .init = input_test_init, |
175 | .exit = input_test_exit, |
176 | .test_cases = input_tests, |
177 | }; |
178 | |
179 | kunit_test_suite(input_test_suite); |
180 | |
181 | MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>" ); |
182 | MODULE_LICENSE("GPL" ); |
183 | |