[PATCH] lib/tests: add KUnit test for argv_split()

Ryota Sakamoto posted 1 patch 4 days, 10 hours ago
There is a newer version of this series
lib/Kconfig.debug            | 12 ++++++
lib/tests/Makefile           |  1 +
lib/tests/argv_split_kunit.c | 93 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 106 insertions(+)
[PATCH] lib/tests: add KUnit test for argv_split()
Posted by Ryota Sakamoto 4 days, 10 hours ago
Add KUnit test for argv_split() to ensure that it correctly splits strings
and handles edge cases such as multiple spaces, leading/trailing and
whitespace.

Currently, there is no dedicated test for argv_split. Moving towards KUnit
allows for easier regression testing and validation of the function.

Sample KUnit output:
    KTAP version 1
    # Subtest: argv_split
    # module: argv_split_kunit
    1..1
        KTAP version 1
        # Subtest: test_argv_split
        ok 1 basic words
        ok 2 single word
        ok 3 leading/trailing whitespace
        ok 4 mixing space
        ok 5 quotes are treated as literals
        ok 6 empty
    # test_argv_split: pass:6 fail:0 skip:0 total:6
    ok 1 test_argv_split

Signed-off-by: Ryota Sakamoto <sakamo.ryota@gmail.com>
---
 lib/Kconfig.debug            | 12 ++++++
 lib/tests/Makefile           |  1 +
 lib/tests/argv_split_kunit.c | 93 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ba36939fda79bf890834b586c366a28acd434ef9..7dacfdccdb83f639944fcdf1d9548245eb047a30 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2817,6 +2817,18 @@ config CMDLINE_KUNIT_TEST
 
 	  If unsure, say N.
 
+config ARGV_SPLIT_KUNIT
+	tristate "KUnit test for argv_split" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  This builds the argv_split unit tests.
+
+	  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.
+
 config BASE64_KUNIT
 	tristate "KUnit test for base64 decoding and encoding" if !KUNIT_ALL_TESTS
 	depends on KUNIT
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 601dba4b7d966d568d0bb6671dffaf4d68489549..fa00737a9cf60ca881b58d915e7f931df372594a 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -4,6 +4,7 @@
 
 # KUnit tests
 CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
+obj-$(CONFIG_ARGV_SPLIT_KUNIT) += argv_split_kunit.o
 obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
 obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
 obj-$(CONFIG_BITS_TEST) += test_bits.o
diff --git a/lib/tests/argv_split_kunit.c b/lib/tests/argv_split_kunit.c
new file mode 100644
index 0000000000000000000000000000000000000000..608ec29d8688b94265d2ec920b5fea59a5ce1b4f
--- /dev/null
+++ b/lib/tests/argv_split_kunit.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for argv_split module.
+ */
+
+#include <kunit/test.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+struct argv_split_test_case {
+	const char *str;
+	const char *input;
+	const int argc;
+	const char *const *argv;
+};
+
+KUNIT_DEFINE_ACTION_WRAPPER(argv_free_wrapper, argv_free, char **);
+
+static struct argv_split_test_case argv_split_cases[] = {
+	{
+		.str = "basic words",
+		.input = "foo bar",
+		.argc = 2,
+		.argv = (const char *[]){ "foo", "bar" },
+	},
+	{
+		.str = "single word",
+		.input = "foobar",
+		.argc = 1,
+		.argv = (const char *[]){ "foobar" },
+	},
+	{
+		.str = "leading/trailing whitespace",
+		.input = "   hello  world ",
+		.argc = 2,
+		.argv = (const char *[]){ "hello", "world" },
+	},
+	{
+		.str = "mixing space",
+		.input = " \t foo \n bar   baz",
+		.argc = 3,
+		.argv = (const char *[]){ "foo", "bar", "baz" },
+	},
+	{
+		.str = "quotes are treated as literals",
+		.input = "ls \"my file/\"",
+		.argc = 3,
+		.argv = (const char *[]){ "ls", "\"my", "file/\"" },
+	},
+	{
+		.str = "empty",
+		.input = "",
+		.argc = 0,
+		.argv = {},
+	},
+};
+
+KUNIT_ARRAY_PARAM_DESC(argv_split, argv_split_cases, str);
+
+static void test_argv_split(struct kunit *test)
+{
+	const struct argv_split_test_case *params = test->param_value;
+	int argc;
+	char **argv;
+	int i;
+
+	argv = argv_split(GFP_KERNEL, params->input, &argc);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, argv);
+	kunit_add_action(test, argv_free_wrapper, argv);
+
+	KUNIT_EXPECT_EQ(test, argc, params->argc);
+	for (i = 0; i < argc; i++)
+		KUNIT_EXPECT_STREQ(test, argv[i], params->argv[i]);
+
+	KUNIT_EXPECT_NULL(test, argv[argc]);
+}
+
+static struct kunit_case argv_split_test_cases[] = {
+	KUNIT_CASE_PARAM(test_argv_split, argv_split_gen_params),
+	{},
+};
+
+static struct kunit_suite argv_split_test_suite = {
+	.name = "argv_split",
+	.test_cases = argv_split_test_cases,
+};
+
+kunit_test_suite(argv_split_test_suite);
+
+MODULE_AUTHOR("Ryota Sakamoto <sakamo.ryota@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("argv_split testing module");

---
base-commit: 18f7fcd5e69a04df57b563360b88be72471d6b62
change-id: 20260131-kunit-argv_split-ca2a1d9fd82b

Best regards,
-- 
Ryota Sakamoto <sakamo.ryota@gmail.com>
Re: [PATCH] lib/tests: add KUnit test for argv_split()
Posted by kernel test robot 4 days, 4 hours ago
Hi Ryota,

kernel test robot noticed the following build errors:

[auto build test ERROR on 18f7fcd5e69a04df57b563360b88be72471d6b62]

url:    https://github.com/intel-lab-lkp/linux/commits/Ryota-Sakamoto/lib-tests-add-KUnit-test-for-argv_split/20260203-004209
base:   18f7fcd5e69a04df57b563360b88be72471d6b62
patch link:    https://lore.kernel.org/r/20260203-kunit-argv_split-v1-1-0d3545314a41%40gmail.com
patch subject: [PATCH] lib/tests: add KUnit test for argv_split()
config: sparc-randconfig-001-20260203 (https://download.01.org/0day-ci/archive/20260203/202602030650.7n64kb2g-lkp@intel.com/config)
compiler: sparc-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260203/202602030650.7n64kb2g-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602030650.7n64kb2g-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

>> lib/tests/argv_split_kunit.c:55:3: warning: braces around scalar initializer
      .argv = {},
      ^
   lib/tests/argv_split_kunit.c:55:3: note: (near initialization for 'argv_split_cases[5].argv')
>> lib/tests/argv_split_kunit.c:55:11: error: empty scalar initializer
      .argv = {},
              ^
   lib/tests/argv_split_kunit.c:55:11: note: (near initialization for 'argv_split_cases[5].argv')


vim +55 lib/tests/argv_split_kunit.c

    19	
    20	static struct argv_split_test_case argv_split_cases[] = {
    21		{
    22			.str = "basic words",
    23			.input = "foo bar",
    24			.argc = 2,
    25			.argv = (const char *[]){ "foo", "bar" },
    26		},
    27		{
    28			.str = "single word",
    29			.input = "foobar",
    30			.argc = 1,
    31			.argv = (const char *[]){ "foobar" },
    32		},
    33		{
    34			.str = "leading/trailing whitespace",
    35			.input = "   hello  world ",
    36			.argc = 2,
    37			.argv = (const char *[]){ "hello", "world" },
    38		},
    39		{
    40			.str = "mixing space",
    41			.input = " \t foo \n bar   baz",
    42			.argc = 3,
    43			.argv = (const char *[]){ "foo", "bar", "baz" },
    44		},
    45		{
    46			.str = "quotes are treated as literals",
    47			.input = "ls \"my file/\"",
    48			.argc = 3,
    49			.argv = (const char *[]){ "ls", "\"my", "file/\"" },
    50		},
    51		{
    52			.str = "empty",
    53			.input = "",
    54			.argc = 0,
  > 55			.argv = {},
    56		},
    57	};
    58	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki