Skip to content

Commit

Permalink
HID: uclogic: Add KUnit tests for uclogic_rdesc_template_apply()
Browse files Browse the repository at this point in the history
The uclogic_rdesc_template_apply() function is used by the driver to
generate HID descriptors from templates.

In order to avoid regressions in future patches, add KUnit tests to
test the function.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
  • Loading branch information
JoseExposito authored and intel-lab-lkp committed May 16, 2022
1 parent 584b537 commit 59e13d6
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/hid/Kconfig
Expand Up @@ -458,6 +458,13 @@ config HID_UCLOGIC
help
Support for UC-Logic and Huion tablets.

config HID_UCLOGIC_KUNIT_TEST
tristate "UC-Logic tests" if !KUNIT_ALL_TESTS
depends on KUNIT=y
default KUNIT_ALL_TESTS
help
KUnit tests for the UC-Logic driver.

config HID_WALTOP
tristate "Waltop"
depends on HID
Expand Down
2 changes: 2 additions & 0 deletions drivers/hid/Makefile
Expand Up @@ -127,6 +127,8 @@ hid-uclogic-objs := hid-uclogic-core.o \
hid-uclogic-rdesc.o \
hid-uclogic-params.o
obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
obj-$(CONFIG_HID_UCLOGIC_KUNIT_TEST) += hid-uclogic-rdesc.o \
hid-uclogic-rdesc-test.o
obj-$(CONFIG_HID_UDRAW_PS3) += hid-udraw-ps3.o
obj-$(CONFIG_HID_LED) += hid-led.o
obj-$(CONFIG_HID_XIAOMI) += hid-xiaomi.o
Expand Down
179 changes: 179 additions & 0 deletions drivers/hid/hid-uclogic-rdesc-test.c
@@ -0,0 +1,179 @@
// SPDX-License-Identifier: GPL-2.0+

/*
* HID driver for UC-Logic devices not fully compliant with HID standard
*
* Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com>
*/

#include <kunit/test.h>
#include "./hid-uclogic-rdesc.h"

struct uclogic_template_case {
const char *name;
const __u8 *template;
size_t template_size;
const s32 *param_list;
size_t param_num;
const __u8 *expected;
};

static const s32 params_pen_all[UCLOGIC_RDESC_PH_ID_NUM] = {
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0xCC,
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0xDD,
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0xEE,
};

static const s32 params_pen_some[] = {
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
};

static const __u8 template_empty[] = { };
static const __u8 template_small[] = { 0x00 };
static const __u8 template_no_ph[] = { 0xAA, 0xFE, 0xAA, 0xED, 0x1D };

static const __u8 template_pen_ph_end[] = {
0xAA, 0xBB, UCLOGIC_RDESC_PEN_PH_HEAD
};

static const __u8 template_pen_all_params[] = {
UCLOGIC_RDESC_PEN_PH(X_LM),
0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
UCLOGIC_RDESC_PEN_PH(Y_PM),
0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
};

static const __u8 expected_pen_all_params[] = {
0xAA, 0x00, 0x00, 0x00,
0x47, 0xBB, 0x00, 0x00, 0x00,
0x27, 0xCC, 0x00, 0x00, 0x00,
0xDD, 0x00, 0x00, 0x00,
0x00, 0xEE, 0x00, 0x00, 0x00,
};

static const __u8 template_pen_some_params[] = {
0x01, 0x02,
UCLOGIC_RDESC_PEN_PH(X_LM),
0x03, UCLOGIC_RDESC_PEN_PH(X_PM),
0x04, 0x05,
};

static const __u8 expected_pen_some_params[] = {
0x01, 0x02,
0xAA, 0x00, 0x00, 0x00,
0x03, 0xBB, 0x00, 0x00, 0x00,
0x04, 0x05,
};

static const __u8 template_params_none[] = {
0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
UCLOGIC_RDESC_PEN_PH(Y_PM),
0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
};

static struct uclogic_template_case uclogic_template_cases[] = {
{
.name = "Empty template",
.template = template_empty,
.template_size = sizeof(template_empty),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = template_empty,
},
{
.name = "Template smaller than the placeholder",
.template = template_small,
.template_size = sizeof(template_small),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = template_small,
},
{
.name = "No placeholder",
.template = template_no_ph,
.template_size = sizeof(template_no_ph),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = template_no_ph,
},
{
.name = "Pen placeholder at the end, without ID",
.template = template_pen_ph_end,
.template_size = sizeof(template_pen_ph_end),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = template_pen_ph_end,
},
{
.name = "All params present in the pen template",
.template = template_pen_all_params,
.template_size = sizeof(template_pen_all_params),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = expected_pen_all_params,
},
{
.name = "Some params present in the pen template (complete param list)",
.template = template_pen_some_params,
.template_size = sizeof(template_pen_some_params),
.param_list = params_pen_all,
.param_num = ARRAY_SIZE(params_pen_all),
.expected = expected_pen_some_params,
},
{
.name = "Some params present in the pen template (incomplete param list)",
.template = template_pen_some_params,
.template_size = sizeof(template_pen_some_params),
.param_list = params_pen_some,
.param_num = ARRAY_SIZE(params_pen_some),
.expected = expected_pen_some_params,
},
{
.name = "No params present in the template",
.template = template_params_none,
.template_size = sizeof(template_params_none),
.param_list = params_pen_some,
.param_num = ARRAY_SIZE(params_pen_some),
.expected = template_params_none,
},
};

static void uclogic_template_case_desc(struct uclogic_template_case *t,
char *desc)
{
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
}

KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
uclogic_template_case_desc);

static void uclogic_template_test(struct kunit *test)
{
__u8 *res;
const struct uclogic_template_case *params = test->param_value;

res = uclogic_rdesc_template_apply(params->template,
params->template_size,
params->param_list,
params->param_num);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res);
KUNIT_EXPECT_EQ(test, 0,
memcmp(res, params->expected, params->template_size));
kfree(res);
}

static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
KUNIT_CASE_PARAM(uclogic_template_test, uclogic_template_gen_params),
{}
};

static struct kunit_suite hid_uclogic_rdesc_test_suite = {
.name = "hid-uclogic-rdesc-test",
.test_cases = hid_uclogic_rdesc_test_cases,
};

kunit_test_suite(hid_uclogic_rdesc_test_suite);

0 comments on commit 59e13d6

Please sign in to comment.