2023-03-30 08:21:25

by Javier Martinez Canillas

[permalink] [raw]
Subject: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions

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


2023-03-30 11:05:03

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions

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

2023-03-30 11:14:59

by Javier Martinez Canillas

[permalink] [raw]
Subject: Re: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions

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

2023-03-30 16:20:46

by Daniel Latypov

[permalink] [raw]
Subject: Re: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions

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

2023-04-02 05:51:29

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH v2] Input: Add KUnit tests for some of the input core helper functions

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