forked from torvalds/linux
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
3a93e40
commit c0455fa
Showing
5 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONFIG_KUNIT=y | ||
CONFIG_INPUT=y | ||
CONFIG_INPUT_KUNIT_TEST=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"); |