Hi Javier,
Many thanks for the patch and to work on this.
On Wed, Mar 29, 2023 at 11:23 AM Javier Martinez Canillas javierm@redhat.com wrote:
The input subsystem doesn't currently have any unit tests, let's add a CONFIG_INPUT_KUNIT_TEST option that builds a test suite to be executed with the KUnit test infrastructure.
For now, only three tests were added for some of the input core helper functions that are trivial to test:
input_test_polling: set/get poll interval and set-up a poll handler.
input_test_timestamp: set/get input event timestamps.
input_test_match_device_id: match a device by bus, vendor, product and events that is capable of handling.
But having the minimal KUnit support allows to add more tests and suites as follow-up changes. The tests can be run with the following command:
$ ./tools/testing/kunit/kunit.py run \ --kunitconfig=drivers/input/tests/.kunitconfig
Signed-off-by: Javier Martinez Canillas javierm@redhat.com
I'll let other more experienced people comment on the kunit tests. In my opinion it's a starting point and after applying your patch and giving a try I can confirm that it works as expected, so just wanted to give my.
Tested-by: Enric Balletbo i Serra eballetbo@redhat.com
Thanks, Enric
drivers/input/Kconfig | 12 +++ drivers/input/Makefile | 1 + drivers/input/tests/Makefile | 3 + drivers/input/tests/input_test.c | 144 +++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 drivers/input/tests/Makefile create mode 100644 drivers/input/tests/input_test.c
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index e2752f7364bc..e094e5bbaa0c 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -166,6 +166,18 @@ config INPUT_EVBUG To compile this driver as a module, choose M here: the module will be called evbug.
+config INPUT_KUNIT_TEST
tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS
depends on INPUT && KUNIT=y
default KUNIT_ALL_TESTS
help
Say Y here if you want to build the KUnit tests for the input
subsystem. For more information about KUnit and unit tests in
general, please refer to the KUnit documentation in
Documentation/dev-tools/kunit/.
If in doubt, say "N".
config INPUT_APMPOWER tristate "Input Power Event -> APM Bridge" if EXPERT depends on INPUT && APM_EMULATION diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 2266c7d010ef..c78753274921 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ +obj-$(CONFIG_INPUT_KUNIT_TEST) += tests/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
diff --git a/drivers/input/tests/Makefile b/drivers/input/tests/Makefile new file mode 100644 index 000000000000..90cf954181bc --- /dev/null +++ b/drivers/input/tests/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c new file mode 100644 index 000000000000..25bbf51b5c87 --- /dev/null +++ b/drivers/input/tests/input_test.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- KUnit test for the input core.
- Copyright (c) 2023 Red Hat Inc
- */
+#include <linux/delay.h> +#include <linux/input.h>
+#include <kunit/test.h>
+#define POLL_INTERVAL 100
+static int input_test_init(struct kunit *test) +{
struct input_dev *input_dev;
int ret;
input_dev = input_allocate_device();
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev);
input_dev->name = "Test input device";
input_dev->id.bustype = BUS_VIRTUAL;
input_dev->id.vendor = 1;
input_dev->id.product = 1;
input_dev->id.version = 1;
input_set_capability(input_dev, EV_KEY, BTN_LEFT);
input_set_capability(input_dev, EV_KEY, BTN_RIGHT);
ret = input_register_device(input_dev);
KUNIT_ASSERT_EQ(test, ret, 0);
test->priv = input_dev;
return 0;
+}
+static void input_test_exit(struct kunit *test) +{
struct input_dev *input_dev = test->priv;
input_unregister_device(input_dev);
+}
+static void input_test_poll(struct input_dev *input) { }
+static void input_test_polling(struct kunit *test) +{
struct input_dev *input_dev = test->priv;
int ret;
ret = input_get_poll_interval(input_dev);
KUNIT_ASSERT_EQ(test, ret, -EINVAL);
ret = input_setup_polling(input_dev, input_test_poll);
KUNIT_ASSERT_EQ(test, ret, 0);
input_set_poll_interval(input_dev, POLL_INTERVAL);
ret = input_get_poll_interval(input_dev);
KUNIT_ASSERT_EQ(test, ret, POLL_INTERVAL);
+}
+static void input_test_timestamp(struct kunit *test) +{
const ktime_t invalid_timestamp = ktime_set(0, 0);
struct input_dev *input_dev = test->priv;
ktime_t *timestamp, time;
int ret;
timestamp = input_get_timestamp(input_dev);
time = timestamp[INPUT_CLK_MONO];
ret = ktime_compare(time, invalid_timestamp);
KUNIT_ASSERT_EQ(test, ret, 1);
time = ktime_get();
input_set_timestamp(input_dev, time);
timestamp = input_get_timestamp(input_dev);
KUNIT_ASSERT_EQ(test, ktime_compare(timestamp[INPUT_CLK_MONO],
time), 0);
+}
+static void input_test_match_device_id(struct kunit *test) +{
struct input_dev *input_dev = test->priv;
struct input_device_id id;
id.flags = INPUT_DEVICE_ID_MATCH_BUS;
id.bustype = BUS_VIRTUAL;
KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
id.bustype = BUS_I2C;
KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
id.flags = INPUT_DEVICE_ID_MATCH_VENDOR;
id.vendor = 1;
KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
id.vendor = 2;
KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
id.flags = INPUT_DEVICE_ID_MATCH_PRODUCT;
id.product = 1;
KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
id.product = 2;
KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
id.flags = INPUT_DEVICE_ID_MATCH_VERSION;
id.version = 1;
KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
id.version = 2;
KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
id.flags = INPUT_DEVICE_ID_MATCH_EVBIT;
__set_bit(EV_KEY, id.evbit);
KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id));
__set_bit(EV_ABS, id.evbit);
KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id));
+}
+static struct kunit_case input_tests[] = {
KUNIT_CASE(input_test_polling),
KUNIT_CASE(input_test_timestamp),
KUNIT_CASE(input_test_match_device_id),
{ /* sentinel */ }
+};
+static struct kunit_suite input_test_suite = {
.name = "input_core",
.init = input_test_init,
.exit = input_test_exit,
.test_cases = input_tests,
+};
+kunit_test_suite(input_test_suite);
+MODULE_AUTHOR("Javier Martinez Canillas javierm@redhat.com"); +MODULE_LICENSE("GPL");
base-commit: 3a93e40326c8f470e71d20b4c42d36767450f38f
2.40.0