mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
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 <javierm@redhat.com> Tested-by: Enric Balletbo i Serra <eballetbo@redhat.com> config: powerpc-allnoconfig (https://download.01.org/0day-ci/archive/20230330/202303301815.kRKFM3NH-lkp@intel.com/config) Link: https://lore.kernel.org/r/20230330081831.2291351-1-javierm@redhat.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
57d94d150d
commit
fdefcbdd6f
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
3
drivers/input/tests/.kunitconfig
Normal file
3
drivers/input/tests/.kunitconfig
Normal file
@ -0,0 +1,3 @@
|
||||
CONFIG_KUNIT=y
|
||||
CONFIG_INPUT=y
|
||||
CONFIG_INPUT_KUNIT_TEST=y
|
3
drivers/input/tests/Makefile
Normal file
3
drivers/input/tests/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o
|
150
drivers/input/tests/input_test.c
Normal file
150
drivers/input/tests/input_test.c
Normal file
@ -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");
|
Loading…
Reference in New Issue
Block a user