xref: /openbmc/linux/drivers/input/tests/input_test.c (revision 3286f88f)
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(input_dev, EV_KEY, BTN_LEFT);
29 	input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
30 
31 	ret = input_register_device(input_dev);
32 	if (ret) {
33 		input_free_device(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(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(0, 0);
70 	struct input_dev *input_dev = test->priv;
71 	ktime_t *timestamp, time;
72 
73 	timestamp = input_get_timestamp(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(input_dev, time);
81 
82 	timestamp = input_get_timestamp(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(input_dev);
146 	handle.name = dev_name(&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(input_dev);
152 	test_handle.name = dev_name(&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(input_dev);
159 	res = input_grab_device(&test_handle);
160 	KUNIT_ASSERT_TRUE(test, res == 0);
161 	input_put_device(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