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_TESTSdepends on INPUT && KUNIT=ydefault KUNIT_ALL_TESTShelpSay Y here if you want to build the KUnit tests for the inputsubsystem. For more information about KUnit and unit tests ingeneral, please refer to the KUnit documentation inDocumentation/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