kunit: tool: add --kconfig_add to allow easily tweaking kunitconfigs
authorDaniel Latypov <dlatypov@google.com>
Sat, 6 Nov 2021 01:30:58 +0000 (18:30 -0700)
committerShuah Khan <skhan@linuxfoundation.org>
Mon, 13 Dec 2021 20:56:27 +0000 (13:56 -0700)
E.g. run tests but with KASAN
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kconfig_add=CONFIG_KASAN=y

This also works with --kunitconfig
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kunitconfig=fs/ext4 --kconfig_add=CONFIG_KASAN=y

This flag is inspired by TuxMake's --kconfig-add, see
https://gitlab.com/Linaro/tuxmake#examples.

Our version just uses "_" as the delimiter for consistency with
pre-existing flags like --build_dir, --make_options, --kernel_args, etc.

Note: this does make it easier to run into a pre-existing edge case:
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kconfig_add=CONFIG_KASAN=y
$ ./tools/testing/kunit/kunit.py run --arch=x86_64
This second invocation ^ still has KASAN enabled!

kunit.py won't call olddefconfig if our current .config is already a
superset of the provided kunitconfig.

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>
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_kernel.py
tools/testing/kunit/kunit_tool_test.py

index 68e6f461c75892fd94d6f93149cd1fb1452d6a42..be58f4c9380620a3d943f073af31d7d00ff42b09 100755 (executable)
@@ -280,6 +280,10 @@ def add_common_opts(parser) -> None:
                             ' If given a directory, (e.g. lib/kunit), "/.kunitconfig" '
                             'will get  automatically appended.',
                             metavar='kunitconfig')
+       parser.add_argument('--kconfig_add',
+                            help='Additional Kconfig options to append to the '
+                            '.kunitconfig, e.g. CONFIG_KASAN=y. Can be repeated.',
+                           action='append')
 
        parser.add_argument('--arch',
                            help=('Specifies the architecture to run tests under. '
@@ -398,6 +402,7 @@ def main(argv, linux=None):
                if not linux:
                        linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                        kunitconfig_path=cli_args.kunitconfig,
+                                       kconfig_add=cli_args.kconfig_add,
                                        arch=cli_args.arch,
                                        cross_compile=cli_args.cross_compile,
                                        qemu_config_path=cli_args.qemu_config)
@@ -423,6 +428,7 @@ def main(argv, linux=None):
                if not linux:
                        linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                        kunitconfig_path=cli_args.kunitconfig,
+                                       kconfig_add=cli_args.kconfig_add,
                                        arch=cli_args.arch,
                                        cross_compile=cli_args.cross_compile,
                                        qemu_config_path=cli_args.qemu_config)
@@ -439,6 +445,7 @@ def main(argv, linux=None):
                if not linux:
                        linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                        kunitconfig_path=cli_args.kunitconfig,
+                                       kconfig_add=cli_args.kconfig_add,
                                        arch=cli_args.arch,
                                        cross_compile=cli_args.cross_compile,
                                        qemu_config_path=cli_args.qemu_config)
@@ -457,6 +464,7 @@ def main(argv, linux=None):
                if not linux:
                        linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir,
                                        kunitconfig_path=cli_args.kunitconfig,
+                                       kconfig_add=cli_args.kconfig_add,
                                        arch=cli_args.arch,
                                        cross_compile=cli_args.cross_compile,
                                        qemu_config_path=cli_args.qemu_config)
index 51ee6e5dae91681cbeb9ec46461e7affe25974e2..7d459d6d6ff2e97bac2ace64c396f057b82fef9b 100644 (file)
@@ -224,6 +224,7 @@ class LinuxSourceTree(object):
              build_dir: str,
              load_config=True,
              kunitconfig_path='',
+             kconfig_add: Optional[List[str]]=None,
              arch=None,
              cross_compile=None,
              qemu_config_path=None) -> None:
@@ -249,6 +250,10 @@ class LinuxSourceTree(object):
                                shutil.copyfile(DEFAULT_KUNITCONFIG_PATH, kunitconfig_path)
 
                self._kconfig = kunit_config.parse_file(kunitconfig_path)
+               if kconfig_add:
+                       kconfig = kunit_config.parse_from_string('\n'.join(kconfig_add))
+                       self._kconfig.merge_in_entries(kconfig)
+
 
        def clean(self) -> bool:
                try:
index d125d2380b3834385c8e2c4eb8ab16baa0f4e79a..c1982ace312be2fba0bed7661cdb8146e59438a0 100755 (executable)
@@ -389,6 +389,10 @@ class LinuxSourceTreeTest(unittest.TestCase):
                                pass
                        kunit_kernel.LinuxSourceTree('', kunitconfig_path=dir)
 
+       def test_kconfig_add(self):
+               tree = kunit_kernel.LinuxSourceTree('', kconfig_add=['CONFIG_NOT_REAL=y'])
+               self.assertIn(kunit_config.KconfigEntry('NOT_REAL', 'y'), tree._kconfig.entries())
+
        def test_invalid_arch(self):
                with self.assertRaisesRegex(kunit_kernel.ConfigError, 'not a valid arch, options are.*x86_64'):
                        kunit_kernel.LinuxSourceTree('', arch='invalid')
@@ -601,6 +605,7 @@ class KUnitMainTest(unittest.TestCase):
                # Just verify that we parsed and initialized it correctly here.
                mock_linux_init.assert_called_once_with('.kunit',
                                                        kunitconfig_path='mykunitconfig',
+                                                       kconfig_add=None,
                                                        arch='um',
                                                        cross_compile=None,
                                                        qemu_config_path=None)
@@ -612,6 +617,19 @@ class KUnitMainTest(unittest.TestCase):
                # Just verify that we parsed and initialized it correctly here.
                mock_linux_init.assert_called_once_with('.kunit',
                                                        kunitconfig_path='mykunitconfig',
+                                                       kconfig_add=None,
+                                                       arch='um',
+                                                       cross_compile=None,
+                                                       qemu_config_path=None)
+
+       @mock.patch.object(kunit_kernel, 'LinuxSourceTree')
+       def test_run_kconfig_add(self, mock_linux_init):
+               mock_linux_init.return_value = self.linux_source_mock
+               kunit.main(['run', '--kconfig_add=CONFIG_KASAN=y', '--kconfig_add=CONFIG_KCSAN=y'])
+               # Just verify that we parsed and initialized it correctly here.
+               mock_linux_init.assert_called_once_with('.kunit',
+                                                       kunitconfig_path=None,
+                                                       kconfig_add=['CONFIG_KASAN=y', 'CONFIG_KCSAN=y'],
                                                        arch='um',
                                                        cross_compile=None,
                                                        qemu_config_path=None)