kunit: tool: add --kernel_args to allow setting module params
authorDaniel Latypov <dlatypov@google.com>
Thu, 15 Jul 2021 16:08:19 +0000 (09:08 -0700)
committerShuah Khan <skhan@linuxfoundation.org>
Fri, 13 Aug 2021 19:28:47 +0000 (13:28 -0600)
kunit.py currently does not make it possible for users to specify module
parameters (/kernel arguments more generally) unless one directly tweaks
the kunit.py code itself.

This hasn't mattered much so far, but this would make it easier to port
existing tests that expose module parameters over to KUnit and/or let
current KUnit tests take advantage of them.

Tested using an kunit internal parameter:
$ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit \
    --kernel_args=kunit.filter_glob=kunit_status
...
Testing complete. 2 tests run. 0 failed. 0 crashed. 0 skipped.

Signed-off-by: Daniel Latypov <dlatypov@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
Documentation/dev-tools/kunit/running_tips.rst
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_tool_test.py

index d1626d5..30d2147 100644 (file)
@@ -80,6 +80,16 @@ file ``.kunitconfig``, you can just pass in the dir, e.g.
        automagically, but tests could theoretically depend on incompatible
        options, so handling that would be tricky.
 
+Setting kernel commandline parameters
+-------------------------------------
+
+You can use ``--kernel_args`` to pass arbitrary kernel arguments, e.g.
+
+.. code-block:: bash
+
+       $ ./tools/testing/kunit/kunit.py run --kernel_args=param=42 --kernel_args=param2=false
+
+
 Generating code coverage reports under UML
 ------------------------------------------
 
index 6276ce0..7174377 100755 (executable)
@@ -30,12 +30,13 @@ KunitBuildRequest = namedtuple('KunitBuildRequest',
                               ['jobs', 'build_dir', 'alltests',
                                'make_options'])
 KunitExecRequest = namedtuple('KunitExecRequest',
-                             ['timeout', 'build_dir', 'alltests', 'filter_glob'])
+                              ['timeout', 'build_dir', 'alltests',
+                               'filter_glob', 'kernel_args'])
 KunitParseRequest = namedtuple('KunitParseRequest',
                               ['raw_output', 'input_data', 'build_dir', 'json'])
 KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs',
                                           'build_dir', 'alltests', 'filter_glob',
-                                          'json', 'make_options'])
+                                          'kernel_args', 'json', 'make_options'])
 
 KernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0]
 
@@ -94,6 +95,7 @@ def exec_tests(linux: kunit_kernel.LinuxSourceTree,
        kunit_parser.print_with_timestamp('Starting KUnit Kernel ...')
        test_start = time.time()
        result = linux.run_kernel(
+               args=request.kernel_args,
                timeout=None if request.alltests else request.timeout,
                 filter_glob=request.filter_glob,
                build_dir=request.build_dir)
@@ -152,7 +154,8 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
                return build_result
 
        exec_request = KunitExecRequest(request.timeout, request.build_dir,
-                                       request.alltests, request.filter_glob)
+                                request.alltests, request.filter_glob,
+                                request.kernel_args)
        exec_result = exec_tests(linux, exec_request)
        if exec_result.status != KunitStatus.SUCCESS:
                return exec_result
@@ -238,6 +241,9 @@ def add_exec_opts(parser) -> None:
                            nargs='?',
                            default='',
                            metavar='filter_glob')
+       parser.add_argument('--kernel_args',
+                           help='Kernel command-line parameters. Maybe be repeated',
+                            action='append')
 
 def add_parse_opts(parser) -> None:
        parser.add_argument('--raw_output', help='don\'t format output from kernel',
@@ -309,6 +315,7 @@ def main(argv, linux=None):
                                       cli_args.build_dir,
                                       cli_args.alltests,
                                       cli_args.filter_glob,
+                                      cli_args.kernel_args,
                                       cli_args.json,
                                       cli_args.make_options)
                result = run_tests(linux, request)
@@ -363,7 +370,8 @@ def main(argv, linux=None):
                exec_request = KunitExecRequest(cli_args.timeout,
                                                cli_args.build_dir,
                                                cli_args.alltests,
-                                               cli_args.filter_glob)
+                                               cli_args.filter_glob,
+                                               cli_args.kernel_args)
                exec_result = exec_tests(linux, exec_request)
                parse_request = KunitParseRequest(cli_args.raw_output,
                                                  exec_result.result,
index 75045aa..628ab00 100755 (executable)
@@ -356,7 +356,7 @@ class KUnitMainTest(unittest.TestCase):
                self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 0)
                self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir='.kunit', filter_glob='', timeout=300)
+                       args=None, build_dir='.kunit', filter_glob='', timeout=300)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        def test_run_passes_args_pass(self):
@@ -364,7 +364,7 @@ class KUnitMainTest(unittest.TestCase):
                self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
                self.assertEqual(self.linux_source_mock.run_kernel.call_count, 1)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir='.kunit', filter_glob='', timeout=300)
+                       args=None, build_dir='.kunit', filter_glob='', timeout=300)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        def test_exec_passes_args_fail(self):
@@ -403,7 +403,7 @@ class KUnitMainTest(unittest.TestCase):
                timeout = 3453
                kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir='.kunit', filter_glob='', timeout=timeout)
+                       args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        def test_run_timeout(self):
@@ -411,7 +411,7 @@ class KUnitMainTest(unittest.TestCase):
                kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock)
                self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir='.kunit', filter_glob='', timeout=timeout)
+                       args=None, build_dir='.kunit', filter_glob='', timeout=timeout)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        def test_run_builddir(self):
@@ -419,7 +419,7 @@ class KUnitMainTest(unittest.TestCase):
                kunit.main(['run', '--build_dir=.kunit'], self.linux_source_mock)
                self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir=build_dir, filter_glob='', timeout=300)
+                       args=None, build_dir=build_dir, filter_glob='', timeout=300)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        def test_config_builddir(self):
@@ -436,7 +436,7 @@ class KUnitMainTest(unittest.TestCase):
                build_dir = '.kunit'
                kunit.main(['exec', '--build_dir', build_dir], self.linux_source_mock)
                self.linux_source_mock.run_kernel.assert_called_once_with(
-                       build_dir=build_dir, filter_glob='', timeout=300)
+                       args=None, build_dir=build_dir, filter_glob='', timeout=300)
                self.print_mock.assert_any_call(StrContains('Testing complete.'))
 
        @mock.patch.object(kunit_kernel, 'LinuxSourceTree')
@@ -461,5 +461,13 @@ class KUnitMainTest(unittest.TestCase):
                                                        cross_compile=None,
                                                        qemu_config_path=None)
 
+       def test_run_kernel_args(self):
+               kunit.main(['run', '--kernel_args=a=1', '--kernel_args=b=2'], self.linux_source_mock)
+               self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1)
+               self.linux_source_mock.run_kernel.assert_called_once_with(
+                     args=['a=1','b=2'], build_dir='.kunit', filter_glob='', timeout=300)
+               self.print_mock.assert_any_call(StrContains('Testing complete.'))
+
+
 if __name__ == '__main__':
        unittest.main()