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, version and events 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/
Signed-off-by: Javier Martinez Canillas javierm@redhat.com Tested-by: Enric Balletbo i Serra eballetbo@redhat.com ---
Changes in v2: - Add Enric's Tested-by tag. - Drop the .kunitconfig from the example command (Daniel Latypov). - Add .kunitconfig that wasn't added by mistake (Daniel Latypov). - Remove ref to KUnit docs in the Kconfig help text (Daniel Latypov). - Inline function calls in the KUNIT_ASSERT_*() calls (Daniel Latypov). - Add some comments to explain why a fail or success is expected.
drivers/input/Kconfig | 10 +++ drivers/input/Makefile | 1 + drivers/input/tests/.kunitconfig | 3 + drivers/input/tests/Makefile | 3 + drivers/input/tests/input_test.c | 150 +++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 drivers/input/tests/.kunitconfig 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..735f90b74ee5 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -166,6 +166,16 @@ 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. + + 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/.kunitconfig b/drivers/input/tests/.kunitconfig new file mode 100644 index 000000000000..2f5bedf8028e --- /dev/null +++ b/drivers/input/tests/.kunitconfig @@ -0,0 +1,3 @@ +CONFIG_KUNIT=y +CONFIG_INPUT=y +CONFIG_INPUT_KUNIT_TEST=y 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..e5a6c1ad2167 --- /dev/null +++ b/drivers/input/tests/input_test.c @@ -0,0 +1,150 @@ +// 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); + if (ret) { + input_free_device(input_dev); + KUNIT_ASSERT_FAILURE(test, "Register device failed: %d", ret); + } + + 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); + input_free_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; + + /* Must fail because a poll handler has not been set-up yet */ + KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), -EINVAL); + + KUNIT_ASSERT_EQ(test, input_setup_polling(input_dev, input_test_poll), 0); + + input_set_poll_interval(input_dev, POLL_INTERVAL); + + /* Must succeed because poll handler was set-up and poll interval set */ + KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), 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; + + timestamp = input_get_timestamp(input_dev); + time = timestamp[INPUT_CLK_MONO]; + + /* The returned timestamp must always be valid */ + KUNIT_ASSERT_EQ(test, ktime_compare(time, invalid_timestamp), 1); + + time = ktime_get(); + input_set_timestamp(input_dev, time); + + timestamp = input_get_timestamp(input_dev); + /* The timestamp must be the same than set before */ + 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; + + /* + * Must match when the input device bus, vendor, product, version + * and events capable of handling are the same and fail to match + * otherwise. + */ + 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
Hi Javier,
I love your patch! Perhaps something to improve:
[auto build test WARNING on 3a93e40326c8f470e71d20b4c42d36767450f38f]
url: https://github.com/intel-lab-lkp/linux/commits/Javier-Martinez-Canillas/Inpu... base: 3a93e40326c8f470e71d20b4c42d36767450f38f patch link: https://lore.kernel.org/r/20230330081831.2291351-1-javierm%40redhat.com patch subject: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions config: powerpc-allnoconfig (https://download.01.org/0day-ci/archive/20230330/202303301815.kRKFM3NH-lkp@i...) compiler: powerpc-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/c0455fa125039a03d011836a8f82a2... git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Javier-Martinez-Canillas/Input-Add-KUnit-tests-for-some-of-the-input-core-helper-functions/20230330-162045 git checkout c0455fa125039a03d011836a8f82a2427591e51c # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot lkp@intel.com | Link: https://lore.kernel.org/oe-kbuild-all/202303301815.kRKFM3NH-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/clk/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/vc4/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/hid/.kunitconfig: warning: ignored by one of the .gitignore files
drivers/input/tests/.kunitconfig: warning: ignored by one of the .gitignore files
fs/ext4/.kunitconfig: warning: ignored by one of the .gitignore files fs/fat/.kunitconfig: warning: ignored by one of the .gitignore files kernel/kcsan/.kunitconfig: warning: ignored by one of the .gitignore files lib/kunit/.kunitconfig: warning: ignored by one of the .gitignore files mm/kfence/.kunitconfig: warning: ignored by one of the .gitignore files net/sunrpc/.kunitconfig: warning: ignored by one of the .gitignore files tools/testing/selftests/arm64/tags/.gitignore: warning: ignored by one of the .gitignore files tools/testing/selftests/arm64/tags/Makefile: warning: ignored by one of the .gitignore files tools/testing/selftests/arm64/tags/run_tags_test.sh: warning: ignored by one of the .gitignore files tools/testing/selftests/arm64/tags/tags_test.c: warning: ignored by one of the .gitignore files tools/testing/selftests/kvm/.gitignore: warning: ignored by one of the .gitignore files tools/testing/selftests/kvm/Makefile: warning: ignored by one of the .gitignore files tools/testing/selftests/kvm/config: warning: ignored by one of the .gitignore files tools/testing/selftests/kvm/settings: warning: ignored by one of the .gitignore files
kernel test robot lkp@intel.com writes:
Hello,
[...]
All warnings (new ones prefixed by >>):
drivers/clk/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/vc4/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/hid/.kunitconfig: warning: ignored by one of the .gitignore files
drivers/input/tests/.kunitconfig: warning: ignored by one of the .gitignore files
KUnit folks, what should we do about this? I believe the correct thing here would be for these dot-files to not be ignored by git.
Not only to prevent these reports, but also to avoid the need to add them using `git add -f`, since is quite error prone and easy to miss.
I was thinking about posting the following patch:
From f1dc1733001682886458c23b676123635bc29da0 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas javierm@redhat.com Date: Thu, 30 Mar 2023 13:04:42 +0200 Subject: [PATCH] .gitignore: Exclude KUnit config dot-files
There's a rule to ignore all the dot-files (.*) but we want to exclude the config files used by KUnit (.kunitconfig) since those are usually added to allow executing test suites without having to enable custom config options.
Signed-off-by: Javier Martinez Canillas javierm@redhat.com --- .gitignore | 1 + 1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore index 70ec6037fa7a..7f86e0837909 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ modules.order !.get_maintainer.ignore !.gitattributes !.gitignore +!.kunitconfig !.mailmap !.rustfmt.toml
base-commit: 197b6b60ae7bc51dd0814953c562833143b292aa
On Thu, Mar 30, 2023 at 4:12 AM Javier Martinez Canillas javierm@redhat.com wrote:
kernel test robot lkp@intel.com writes:
Hello,
[...]
All warnings (new ones prefixed by >>):
drivers/clk/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/gpu/drm/vc4/tests/.kunitconfig: warning: ignored by one of the .gitignore files drivers/hid/.kunitconfig: warning: ignored by one of the .gitignore files
drivers/input/tests/.kunitconfig: warning: ignored by one of the .gitignore files
KUnit folks, what should we do about this? I believe the correct thing here would be for these dot-files to not be ignored by git.
Not only to prevent these reports, but also to avoid the need to add them using `git add -f`, since is quite error prone and easy to miss.
I was thinking about posting the following patch:
From f1dc1733001682886458c23b676123635bc29da0 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas javierm@redhat.com Date: Thu, 30 Mar 2023 13:04:42 +0200 Subject: [PATCH] .gitignore: Exclude KUnit config dot-files
Ah, I forgot/didn't realize lkp bot was complaining about .kunitconfig's. Agreed, we should go with something like that.
As I noted in my reply on the patch, there was a previous patch to do just the same thing here, https://lore.kernel.org/linux-kselftest/20230127145708.12915-1-andriy.shevch...
I'm not sure who is intended to pick up the patch, but maybe bringing up the fact this causes spurious warnings will help argue for the change.
Thanks, Daniel
On Thu, Mar 30, 2023 at 10:18:31AM +0200, Javier Martinez Canillas 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, version and events 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/
Signed-off-by: Javier Martinez Canillas javierm@redhat.com Tested-by: Enric Balletbo i Serra eballetbo@redhat.com
Applied, thank you.
linux-kselftest-mirror@lists.linaro.org