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 <[email protected]>
Tested-by: Enric Balletbo i Serra <[email protected]>
---
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 <[email protected]>");
+MODULE_LICENSE("GPL");
base-commit: 3a93e40326c8f470e71d20b4c42d36767450f38f
--
2.40.0
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/Input-Add-KUnit-tests-for-some-of-the-input-core-helper-functions/20230330-162045
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/[email protected]/config)
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/c0455fa125039a03d011836a8f82a2427591e51c
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 <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
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
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests
kernel test robot <[email protected]> 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 <[email protected]>
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 <[email protected]>
---
.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
--
2.40.0
--
Best regards,
Javier Martinez Canillas
Core Platforms
Red Hat
On Thu, Mar 30, 2023 at 4:12 AM Javier Martinez Canillas
<[email protected]> wrote:
>
> kernel test robot <[email protected]> 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 <[email protected]>
> 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/[email protected]/
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 <[email protected]>
> Tested-by: Enric Balletbo i Serra <[email protected]>
Applied, thank you.
--
Dmitry