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