[PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code

Armin Wolf posted 9 patches 1 month ago
There is a newer version of this series
[PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Armin Wolf 1 month ago
The string conversion frunctions provided by the WMI driver core
have no dependencies on the remaining WMI API, making them suitable
for unit tests.

Implement such a unit test using kunit. Those unit tests verify that
converting between WMI strings and UTF8 strings works as expected.
They also verify that edge cases are handled correctly.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
 drivers/platform/wmi/tests/Kconfig        |  11 +
 drivers/platform/wmi/tests/Makefile       |   3 +
 drivers/platform/wmi/tests/string_kunit.c | 278 ++++++++++++++++++++++
 3 files changed, 292 insertions(+)
 create mode 100644 drivers/platform/wmi/tests/string_kunit.c

diff --git a/drivers/platform/wmi/tests/Kconfig b/drivers/platform/wmi/tests/Kconfig
index efcbcb51c251..f7f0f3c540f5 100644
--- a/drivers/platform/wmi/tests/Kconfig
+++ b/drivers/platform/wmi/tests/Kconfig
@@ -14,3 +14,14 @@ config ACPI_WMI_MARSHALLING_KUNIT_TEST
 	  to the KUnit documentation in Documentation/dev-tools/kunit/.
 
 	  If unsure, say N.
+
+config ACPI_WMI_STRING_KUNIT_TEST
+	tristate "KUnit Test for ACPI-WMI string conversion" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  This builds unit tests for the ACPI-WMI string conversion code.
+	  For more information on KUnit and unit tests in general, please refer
+	  to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+	  If unsure, say N.
diff --git a/drivers/platform/wmi/tests/Makefile b/drivers/platform/wmi/tests/Makefile
index 252c3125353a..62c438e26259 100644
--- a/drivers/platform/wmi/tests/Makefile
+++ b/drivers/platform/wmi/tests/Makefile
@@ -6,3 +6,6 @@
 
 wmi_marshalling_kunit-y				:= marshalling_kunit.o
 obj-$(CONFIG_ACPI_WMI_MARSHALLING_KUNIT_TEST)	+= wmi_marshalling_kunit.o
+
+wmi_string_kunit-y				:= string_kunit.o
+obj-$(CONFIG_ACPI_WMI_STRING_KUNIT_TEST)	+= wmi_string_kunit.o
diff --git a/drivers/platform/wmi/tests/string_kunit.c b/drivers/platform/wmi/tests/string_kunit.c
new file mode 100644
index 000000000000..9aa3ffa85090
--- /dev/null
+++ b/drivers/platform/wmi/tests/string_kunit.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * KUnit test for the ACPI-WMI string conversion code.
+ *
+ * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/wmi.h>
+
+#include <kunit/resource.h>
+#include <kunit/test.h>
+
+#include <asm/byteorder.h>
+
+struct wmi_string_param {
+	const char *name;
+	const struct wmi_string *wmi_string;
+	/*
+	 * Remember that using sizeof() on a struct wmi_string will
+	 * always return a size of two bytes due to the flexible
+	 * array member!
+	 */
+	size_t wmi_string_length;
+	const u8 *utf8_string;
+	size_t utf8_string_length;
+};
+
+#define TEST_WMI_STRING_LENGTH 12
+
+static const struct wmi_string test_wmi_string = {
+	.length = cpu_to_le16(10),
+	.chars = {
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'E'),
+		cpu_to_le16(u'S'),
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+static const u8 test_utf8_string[] = "TEST";
+
+#define SPECIAL_WMI_STRING_LENGTH 14
+
+static const struct wmi_string special_wmi_string = {
+	.length = cpu_to_le16(12),
+	.chars = {
+		cpu_to_le16(u'Ä'),
+		cpu_to_le16(u'Ö'),
+		cpu_to_le16(u'Ü'),
+		cpu_to_le16(u'ß'),
+		cpu_to_le16(u'€'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+static const u8 special_utf8_string[] = "ÄÖÜ߀";
+
+#define MULTI_POINT_WMI_STRING_LENGTH 12
+
+static const struct wmi_string multi_point_wmi_string = {
+	.length = cpu_to_le16(10),
+	.chars = {
+		cpu_to_le16(u'K'),
+		/* 🐧 */
+		cpu_to_le16(0xD83D),
+		cpu_to_le16(0xDC27),
+		cpu_to_le16(u'!'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+static const u8 multi_point_utf8_string[] = "K🐧!";
+
+#define PADDED_TEST_WMI_STRING_LENGTH 14
+
+static const struct wmi_string padded_test_wmi_string = {
+	.length = cpu_to_le16(12),
+	.chars = {
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'E'),
+		cpu_to_le16(u'S'),
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'\0'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+static const u8 padded_test_utf8_string[] = "TEST\0";
+
+#define OVERSIZED_TEST_WMI_STRING_LENGTH 14
+
+static const struct wmi_string oversized_test_wmi_string = {
+	.length = cpu_to_le16(8),
+	.chars = {
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'E'),
+		cpu_to_le16(u'S'),
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'!'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+static const u8 oversized_test_utf8_string[] = "TEST!";
+
+#define INVALID_TEST_WMI_STRING_LENGTH 14
+
+static const struct wmi_string invalid_test_wmi_string = {
+	.length = cpu_to_le16(12),
+	.chars = {
+		cpu_to_le16(u'T'),
+		/* 🐧, with low surrogate missing */
+		cpu_to_le16(0xD83D),
+		cpu_to_le16(u'E'),
+		cpu_to_le16(u'S'),
+		cpu_to_le16(u'T'),
+		cpu_to_le16(u'\0'),
+	},
+};
+
+/* We have to split the string here to end the hex escape sequence */
+static const u8 invalid_test_utf8_string[] = "T" "\xF0\x9F" "EST";
+
+static const struct wmi_string_param wmi_string_params_array[] = {
+	{
+		.name = "ascii_string",
+		.wmi_string = &test_wmi_string,
+		.wmi_string_length = TEST_WMI_STRING_LENGTH,
+		.utf8_string = test_utf8_string,
+		.utf8_string_length = sizeof(test_utf8_string),
+	},
+	{
+		.name = "special_string",
+		.wmi_string = &special_wmi_string,
+		.wmi_string_length = SPECIAL_WMI_STRING_LENGTH,
+		.utf8_string = special_utf8_string,
+		.utf8_string_length = sizeof(special_utf8_string),
+	},
+	{
+		.name = "multi_point_string",
+		.wmi_string = &multi_point_wmi_string,
+		.wmi_string_length = MULTI_POINT_WMI_STRING_LENGTH,
+		.utf8_string = multi_point_utf8_string,
+		.utf8_string_length = sizeof(multi_point_utf8_string),
+	},
+};
+
+static void wmi_string_param_get_desc(const struct wmi_string_param *param, char *desc)
+{
+	strscpy(desc, param->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(wmi_string, wmi_string_params_array, wmi_string_param_get_desc);
+
+static void wmi_string_to_utf8s_test(struct kunit *test)
+{
+	const struct wmi_string_param *param = test->param_value;
+	ssize_t ret;
+	u8 *result;
+
+	result = kunit_kzalloc(test, param->utf8_string_length, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, result);
+
+	ret = wmi_string_to_utf8s(param->wmi_string, result, param->utf8_string_length);
+
+	KUNIT_EXPECT_EQ(test, ret, param->utf8_string_length - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, param->utf8_string, param->utf8_string_length);
+}
+
+static void wmi_string_from_utf8s_test(struct kunit *test)
+{
+	const struct wmi_string_param *param = test->param_value;
+	struct wmi_string *result;
+	size_t max_chars;
+	ssize_t ret;
+
+	max_chars = (param->wmi_string_length - sizeof(*result)) / 2;
+	result = kunit_kzalloc(test, param->wmi_string_length, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, result);
+
+	ret = wmi_string_from_utf8s(result, max_chars, param->utf8_string,
+				    param->utf8_string_length);
+
+	KUNIT_EXPECT_EQ(test, ret, max_chars - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, param->wmi_string, param->wmi_string_length);
+}
+
+static void wmi_string_to_utf8s_padded_test(struct kunit *test)
+{
+	u8 result[sizeof(padded_test_utf8_string)];
+	ssize_t ret;
+
+	ret = wmi_string_to_utf8s(&padded_test_wmi_string, result, sizeof(result));
+
+	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, test_utf8_string, sizeof(test_utf8_string));
+}
+
+static void wmi_string_from_utf8s_padded_test(struct kunit *test)
+{
+	struct wmi_string *result;
+	size_t max_chars;
+	ssize_t ret;
+
+	max_chars = (PADDED_TEST_WMI_STRING_LENGTH - sizeof(*result)) / 2;
+	result = kunit_kzalloc(test, PADDED_TEST_WMI_STRING_LENGTH, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, result);
+
+	ret = wmi_string_from_utf8s(result, max_chars, padded_test_utf8_string,
+				    sizeof(padded_test_utf8_string));
+
+	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, &test_wmi_string, sizeof(test_wmi_string));
+}
+
+static void wmi_string_to_utf8s_oversized_test(struct kunit *test)
+{
+	u8 result[sizeof(oversized_test_utf8_string)];
+	ssize_t ret;
+
+	ret = wmi_string_to_utf8s(&oversized_test_wmi_string, result, sizeof(result));
+
+	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, test_utf8_string, sizeof(test_utf8_string));
+}
+
+static void wmi_string_to_utf8s_invalid_test(struct kunit *test)
+{
+	u8 result[sizeof(invalid_test_utf8_string)];
+	ssize_t ret;
+
+	ret = wmi_string_to_utf8s(&invalid_test_wmi_string, result, sizeof(result));
+
+	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
+	KUNIT_EXPECT_MEMEQ(test, result, test_utf8_string, sizeof(test_utf8_string));
+}
+
+static void wmi_string_from_utf8s_invalid_test(struct kunit *test)
+{
+	struct wmi_string *result;
+	size_t max_chars;
+	ssize_t ret;
+
+	max_chars = (INVALID_TEST_WMI_STRING_LENGTH - sizeof(*result)) / 2;
+	result = kunit_kzalloc(test, INVALID_TEST_WMI_STRING_LENGTH, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, result);
+
+	ret = wmi_string_from_utf8s(result, max_chars, invalid_test_utf8_string,
+				    sizeof(invalid_test_utf8_string));
+
+	KUNIT_EXPECT_EQ(test, ret, -EINVAL);
+}
+
+static struct kunit_case wmi_string_test_cases[] = {
+	KUNIT_CASE_PARAM(wmi_string_to_utf8s_test, wmi_string_gen_params),
+	KUNIT_CASE_PARAM(wmi_string_from_utf8s_test, wmi_string_gen_params),
+	KUNIT_CASE(wmi_string_to_utf8s_padded_test),
+	KUNIT_CASE(wmi_string_from_utf8s_padded_test),
+	KUNIT_CASE(wmi_string_to_utf8s_oversized_test),
+	KUNIT_CASE(wmi_string_to_utf8s_invalid_test),
+	KUNIT_CASE(wmi_string_from_utf8s_invalid_test),
+	{}
+};
+
+static struct kunit_suite wmi_string_test_suite = {
+	.name = "wmi_string",
+	.test_cases = wmi_string_test_cases,
+};
+
+kunit_test_suite(wmi_string_test_suite);
+
+MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
+MODULE_DESCRIPTION("KUnit test for the ACPI-WMI string conversion code");
+MODULE_LICENSE("GPL");
-- 
2.39.5
Re: [PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Nathan Chancellor 2 weeks, 3 days ago
Hi Armin,

On Fri, Jan 09, 2026 at 10:46:14PM +0100, Armin Wolf wrote:
> The string conversion frunctions provided by the WMI driver core
> have no dependencies on the remaining WMI API, making them suitable
> for unit tests.
> 
> Implement such a unit test using kunit. Those unit tests verify that
> converting between WMI strings and UTF8 strings works as expected.
> They also verify that edge cases are handled correctly.
> 
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
...
> +++ b/drivers/platform/wmi/tests/string_kunit.c
...
> +static const u8 oversized_test_utf8_string[] = "TEST!";
...
> +static void wmi_string_to_utf8s_oversized_test(struct kunit *test)
> +{
> +	u8 result[sizeof(oversized_test_utf8_string)];
> +	ssize_t ret;
> +
> +	ret = wmi_string_to_utf8s(&oversized_test_wmi_string, result, sizeof(result));
> +
> +	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
> +	KUNIT_EXPECT_MEMEQ(test, result, test_utf8_string, sizeof(test_utf8_string));
> +}

After this change in -next as commit 0e1a8143e797 ("platform/wmi: Add
kunit test for the string conversion code"), I am seeing a warning from
clang around oversized_test_utf8_string:

  drivers/platform/wmi/tests/string_kunit.c:108:17: error: variable 'oversized_test_utf8_string' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
    108 | static const u8 oversized_test_utf8_string[] = "TEST!";
        |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~

oversized_test_utf8_string is only used in sizeof() in
wmi_string_to_utf8s_oversized_test(). clang warns because sizeof() is
evaluated at compile time, so oversized_test_utf8_string won't end up in
the final binary. This is typically a bug since the developer may have
intended to use the variable elsewhere but I was not able to easily
determine that in this case.

If it is intentional that this variable is only needed in sizeof(), it
could either be marked with __maybe_unused or eliminated in favor of a
direct 'sizeof("TEST!")', depending on maintainer/developer preference.
I am happy to send a patch.

Cheers,
Nathan
Re: [PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Armin Wolf 2 weeks, 2 days ago
Am 23.01.26 um 00:45 schrieb Nathan Chancellor:

> Hi Armin,
>
> On Fri, Jan 09, 2026 at 10:46:14PM +0100, Armin Wolf wrote:
>> The string conversion frunctions provided by the WMI driver core
>> have no dependencies on the remaining WMI API, making them suitable
>> for unit tests.
>>
>> Implement such a unit test using kunit. Those unit tests verify that
>> converting between WMI strings and UTF8 strings works as expected.
>> They also verify that edge cases are handled correctly.
>>
>> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ...
>> +++ b/drivers/platform/wmi/tests/string_kunit.c
> ...
>> +static const u8 oversized_test_utf8_string[] = "TEST!";
> ...
>> +static void wmi_string_to_utf8s_oversized_test(struct kunit *test)
>> +{
>> +	u8 result[sizeof(oversized_test_utf8_string)];
>> +	ssize_t ret;
>> +
>> +	ret = wmi_string_to_utf8s(&oversized_test_wmi_string, result, sizeof(result));
>> +
>> +	KUNIT_EXPECT_EQ(test, ret, sizeof(test_utf8_string) - 1);
>> +	KUNIT_EXPECT_MEMEQ(test, result, test_utf8_string, sizeof(test_utf8_string));
>> +}
> After this change in -next as commit 0e1a8143e797 ("platform/wmi: Add
> kunit test for the string conversion code"), I am seeing a warning from
> clang around oversized_test_utf8_string:
>
>    drivers/platform/wmi/tests/string_kunit.c:108:17: error: variable 'oversized_test_utf8_string' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration]
>      108 | static const u8 oversized_test_utf8_string[] = "TEST!";
>          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
>
> oversized_test_utf8_string is only used in sizeof() in
> wmi_string_to_utf8s_oversized_test(). clang warns because sizeof() is
> evaluated at compile time, so oversized_test_utf8_string won't end up in
> the final binary. This is typically a bug since the developer may have
> intended to use the variable elsewhere but I was not able to easily
> determine that in this case.
>
> If it is intentional that this variable is only needed in sizeof(), it
> could either be marked with __maybe_unused or eliminated in favor of a
> direct 'sizeof("TEST!")', depending on maintainer/developer preference.
> I am happy to send a patch.
>
> Cheers,
> Nathan

Good catch, it seems that i forgot to add the test case that was supposed to use oversized_test_utf8_string.
I will send a patch that adds this missing test case, fixing this warning in the process.

Thanks,
Armin Wolf
Re: [PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Ilpo Järvinen 3 weeks, 6 days ago
On Fri, 9 Jan 2026, Armin Wolf wrote:

> The string conversion frunctions provided by the WMI driver core
> have no dependencies on the remaining WMI API, making them suitable
> for unit tests.
> 
> Implement such a unit test using kunit. Those unit tests verify that
> converting between WMI strings and UTF8 strings works as expected.
> They also verify that edge cases are handled correctly.
> 
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ---
>  drivers/platform/wmi/tests/Kconfig        |  11 +
>  drivers/platform/wmi/tests/Makefile       |   3 +
>  drivers/platform/wmi/tests/string_kunit.c | 278 ++++++++++++++++++++++
>  3 files changed, 292 insertions(+)
>  create mode 100644 drivers/platform/wmi/tests/string_kunit.c
> 
> diff --git a/drivers/platform/wmi/tests/Kconfig b/drivers/platform/wmi/tests/Kconfig
> index efcbcb51c251..f7f0f3c540f5 100644
> --- a/drivers/platform/wmi/tests/Kconfig
> +++ b/drivers/platform/wmi/tests/Kconfig
> @@ -14,3 +14,14 @@ config ACPI_WMI_MARSHALLING_KUNIT_TEST
>  	  to the KUnit documentation in Documentation/dev-tools/kunit/.
>  
>  	  If unsure, say N.
> +
> +config ACPI_WMI_STRING_KUNIT_TEST
> +	tristate "KUnit Test for ACPI-WMI string conversion" if !KUNIT_ALL_TESTS
> +	depends on KUNIT
> +	default KUNIT_ALL_TESTS
> +	help
> +	  This builds unit tests for the ACPI-WMI string conversion code.
> +	  For more information on KUnit and unit tests in general, please refer
> +	  to the KUnit documentation in Documentation/dev-tools/kunit/.
> +
> +	  If unsure, say N.
> diff --git a/drivers/platform/wmi/tests/Makefile b/drivers/platform/wmi/tests/Makefile
> index 252c3125353a..62c438e26259 100644
> --- a/drivers/platform/wmi/tests/Makefile
> +++ b/drivers/platform/wmi/tests/Makefile
> @@ -6,3 +6,6 @@
>  
>  wmi_marshalling_kunit-y				:= marshalling_kunit.o
>  obj-$(CONFIG_ACPI_WMI_MARSHALLING_KUNIT_TEST)	+= wmi_marshalling_kunit.o
> +
> +wmi_string_kunit-y				:= string_kunit.o
> +obj-$(CONFIG_ACPI_WMI_STRING_KUNIT_TEST)	+= wmi_string_kunit.o
> diff --git a/drivers/platform/wmi/tests/string_kunit.c b/drivers/platform/wmi/tests/string_kunit.c
> new file mode 100644
> index 000000000000..9aa3ffa85090
> --- /dev/null
> +++ b/drivers/platform/wmi/tests/string_kunit.c
> @@ -0,0 +1,278 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * KUnit test for the ACPI-WMI string conversion code.
> + *
> + * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/wmi.h>
> +
> +#include <kunit/resource.h>
> +#include <kunit/test.h>
> +
> +#include <asm/byteorder.h>
> +
> +struct wmi_string_param {
> +	const char *name;
> +	const struct wmi_string *wmi_string;
> +	/*
> +	 * Remember that using sizeof() on a struct wmi_string will
> +	 * always return a size of two bytes due to the flexible
> +	 * array member!
> +	 */
> +	size_t wmi_string_length;
> +	const u8 *utf8_string;
> +	size_t utf8_string_length;
> +};
> +
> +#define TEST_WMI_STRING_LENGTH 12
> +
> +static const struct wmi_string test_wmi_string = {
> +	.length = cpu_to_le16(10),
> +	.chars = {
> +		cpu_to_le16(u'T'),

I've applied this to for-next and intend to keep these there but FYI these 
trigger sparse errors. I don't know if they're fixable or not with 
reasonable effort on kernel side.

$ sparse --version
0.6.4 (Debian: 0.6.4-3)

--
 i.
Re: [PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Armin Wolf 3 weeks, 6 days ago
Am 12.01.26 um 17:34 schrieb Ilpo Järvinen:

> On Fri, 9 Jan 2026, Armin Wolf wrote:
>
>> The string conversion frunctions provided by the WMI driver core
>> have no dependencies on the remaining WMI API, making them suitable
>> for unit tests.
>>
>> Implement such a unit test using kunit. Those unit tests verify that
>> converting between WMI strings and UTF8 strings works as expected.
>> They also verify that edge cases are handled correctly.
>>
>> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
>> ---
>>   drivers/platform/wmi/tests/Kconfig        |  11 +
>>   drivers/platform/wmi/tests/Makefile       |   3 +
>>   drivers/platform/wmi/tests/string_kunit.c | 278 ++++++++++++++++++++++
>>   3 files changed, 292 insertions(+)
>>   create mode 100644 drivers/platform/wmi/tests/string_kunit.c
>>
>> diff --git a/drivers/platform/wmi/tests/Kconfig b/drivers/platform/wmi/tests/Kconfig
>> index efcbcb51c251..f7f0f3c540f5 100644
>> --- a/drivers/platform/wmi/tests/Kconfig
>> +++ b/drivers/platform/wmi/tests/Kconfig
>> @@ -14,3 +14,14 @@ config ACPI_WMI_MARSHALLING_KUNIT_TEST
>>   	  to the KUnit documentation in Documentation/dev-tools/kunit/.
>>   
>>   	  If unsure, say N.
>> +
>> +config ACPI_WMI_STRING_KUNIT_TEST
>> +	tristate "KUnit Test for ACPI-WMI string conversion" if !KUNIT_ALL_TESTS
>> +	depends on KUNIT
>> +	default KUNIT_ALL_TESTS
>> +	help
>> +	  This builds unit tests for the ACPI-WMI string conversion code.
>> +	  For more information on KUnit and unit tests in general, please refer
>> +	  to the KUnit documentation in Documentation/dev-tools/kunit/.
>> +
>> +	  If unsure, say N.
>> diff --git a/drivers/platform/wmi/tests/Makefile b/drivers/platform/wmi/tests/Makefile
>> index 252c3125353a..62c438e26259 100644
>> --- a/drivers/platform/wmi/tests/Makefile
>> +++ b/drivers/platform/wmi/tests/Makefile
>> @@ -6,3 +6,6 @@
>>   
>>   wmi_marshalling_kunit-y				:= marshalling_kunit.o
>>   obj-$(CONFIG_ACPI_WMI_MARSHALLING_KUNIT_TEST)	+= wmi_marshalling_kunit.o
>> +
>> +wmi_string_kunit-y				:= string_kunit.o
>> +obj-$(CONFIG_ACPI_WMI_STRING_KUNIT_TEST)	+= wmi_string_kunit.o
>> diff --git a/drivers/platform/wmi/tests/string_kunit.c b/drivers/platform/wmi/tests/string_kunit.c
>> new file mode 100644
>> index 000000000000..9aa3ffa85090
>> --- /dev/null
>> +++ b/drivers/platform/wmi/tests/string_kunit.c
>> @@ -0,0 +1,278 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * KUnit test for the ACPI-WMI string conversion code.
>> + *
>> + * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de>
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/string.h>
>> +#include <linux/wmi.h>
>> +
>> +#include <kunit/resource.h>
>> +#include <kunit/test.h>
>> +
>> +#include <asm/byteorder.h>
>> +
>> +struct wmi_string_param {
>> +	const char *name;
>> +	const struct wmi_string *wmi_string;
>> +	/*
>> +	 * Remember that using sizeof() on a struct wmi_string will
>> +	 * always return a size of two bytes due to the flexible
>> +	 * array member!
>> +	 */
>> +	size_t wmi_string_length;
>> +	const u8 *utf8_string;
>> +	size_t utf8_string_length;
>> +};
>> +
>> +#define TEST_WMI_STRING_LENGTH 12
>> +
>> +static const struct wmi_string test_wmi_string = {
>> +	.length = cpu_to_le16(10),
>> +	.chars = {
>> +		cpu_to_le16(u'T'),
> I've applied this to for-next and intend to keep these there but FYI these
> trigger sparse errors. I don't know if they're fixable or not with
> reasonable effort on kernel side.

To me it seems that sparse ignores the u-prefix signaling that the character constant
has a length of 16-bits, but good catch.

If this really is a problem then gcc would issue a warning anyway (happened when i was
using the 🐧 character which does not fit into a 16-bit character constant).

Thanks,
Armin Wolf

>
> $ sparse --version
> 0.6.4 (Debian: 0.6.4-3)
>
> --
>   i.
>
Re: [PATCH v3 4/9] platform/wmi: Add kunit test for the string conversion code
Posted by Ilpo Järvinen 3 weeks, 6 days ago
On Mon, 12 Jan 2026, Armin Wolf wrote:

> Am 12.01.26 um 17:34 schrieb Ilpo Järvinen:
> 
> > On Fri, 9 Jan 2026, Armin Wolf wrote:
> > 
> > > The string conversion frunctions provided by the WMI driver core
> > > have no dependencies on the remaining WMI API, making them suitable
> > > for unit tests.
> > > 
> > > Implement such a unit test using kunit. Those unit tests verify that
> > > converting between WMI strings and UTF8 strings works as expected.
> > > They also verify that edge cases are handled correctly.
> > > 
> > > Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> > > ---
> > >   drivers/platform/wmi/tests/Kconfig        |  11 +
> > >   drivers/platform/wmi/tests/Makefile       |   3 +
> > >   drivers/platform/wmi/tests/string_kunit.c | 278 ++++++++++++++++++++++
> > >   3 files changed, 292 insertions(+)
> > >   create mode 100644 drivers/platform/wmi/tests/string_kunit.c
> > > 
> > > diff --git a/drivers/platform/wmi/tests/Kconfig
> > > b/drivers/platform/wmi/tests/Kconfig
> > > index efcbcb51c251..f7f0f3c540f5 100644
> > > --- a/drivers/platform/wmi/tests/Kconfig
> > > +++ b/drivers/platform/wmi/tests/Kconfig
> > > @@ -14,3 +14,14 @@ config ACPI_WMI_MARSHALLING_KUNIT_TEST
> > >   	  to the KUnit documentation in Documentation/dev-tools/kunit/.
> > >     	  If unsure, say N.
> > > +
> > > +config ACPI_WMI_STRING_KUNIT_TEST
> > > +	tristate "KUnit Test for ACPI-WMI string conversion" if
> > > !KUNIT_ALL_TESTS
> > > +	depends on KUNIT
> > > +	default KUNIT_ALL_TESTS
> > > +	help
> > > +	  This builds unit tests for the ACPI-WMI string conversion code.
> > > +	  For more information on KUnit and unit tests in general, please
> > > refer
> > > +	  to the KUnit documentation in Documentation/dev-tools/kunit/.
> > > +
> > > +	  If unsure, say N.
> > > diff --git a/drivers/platform/wmi/tests/Makefile
> > > b/drivers/platform/wmi/tests/Makefile
> > > index 252c3125353a..62c438e26259 100644
> > > --- a/drivers/platform/wmi/tests/Makefile
> > > +++ b/drivers/platform/wmi/tests/Makefile
> > > @@ -6,3 +6,6 @@
> > >     wmi_marshalling_kunit-y				:= marshalling_kunit.o
> > >   obj-$(CONFIG_ACPI_WMI_MARSHALLING_KUNIT_TEST)	+=
> > > wmi_marshalling_kunit.o
> > > +
> > > +wmi_string_kunit-y				:= string_kunit.o
> > > +obj-$(CONFIG_ACPI_WMI_STRING_KUNIT_TEST)	+= wmi_string_kunit.o
> > > diff --git a/drivers/platform/wmi/tests/string_kunit.c
> > > b/drivers/platform/wmi/tests/string_kunit.c
> > > new file mode 100644
> > > index 000000000000..9aa3ffa85090
> > > --- /dev/null
> > > +++ b/drivers/platform/wmi/tests/string_kunit.c
> > > @@ -0,0 +1,278 @@
> > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > +/*
> > > + * KUnit test for the ACPI-WMI string conversion code.
> > > + *
> > > + * Copyright (C) 2025 Armin Wolf <W_Armin@gmx.de>
> > > + */
> > > +
> > > +#include <linux/module.h>
> > > +#include <linux/slab.h>
> > > +#include <linux/string.h>
> > > +#include <linux/wmi.h>
> > > +
> > > +#include <kunit/resource.h>
> > > +#include <kunit/test.h>
> > > +
> > > +#include <asm/byteorder.h>
> > > +
> > > +struct wmi_string_param {
> > > +	const char *name;
> > > +	const struct wmi_string *wmi_string;
> > > +	/*
> > > +	 * Remember that using sizeof() on a struct wmi_string will
> > > +	 * always return a size of two bytes due to the flexible
> > > +	 * array member!
> > > +	 */
> > > +	size_t wmi_string_length;
> > > +	const u8 *utf8_string;
> > > +	size_t utf8_string_length;
> > > +};
> > > +
> > > +#define TEST_WMI_STRING_LENGTH 12
> > > +
> > > +static const struct wmi_string test_wmi_string = {
> > > +	.length = cpu_to_le16(10),
> > > +	.chars = {
> > > +		cpu_to_le16(u'T'),
> > I've applied this to for-next and intend to keep these there but FYI these
> > trigger sparse errors. I don't know if they're fixable or not with
> > reasonable effort on kernel side.
> 
> To me it seems that sparse ignores the u-prefix signaling that the character
> constant
> has a length of 16-bits, but good catch.
> 
> If this really is a problem then gcc would issue a warning anyway (happened
> when i was
> using the 🐧 character which does not fit into a 16-bit character constant).

I guess I'll have to add another filter to my build-test.sh for this file. 
I already -v -e 'error: bad constant expression' filter in use. Sadly 
sparse seems to be rotting.

-- 
 i.