From a15cfa39e8cf9bb20d755978c2f25a9c427bf7b2 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Wed, 10 Aug 2022 16:02:58 -0700 Subject: [PATCH 01/18] kunit: tool: make --raw_output=kunit (aka --raw_output) preserve leading spaces With $ kunit.py run --raw_output=all ... you get the raw output from the kernel, e.g. something like > TAP version 14 > 1..26 > # Subtest: time_test_cases > 1..1 > ok 1 - time64_to_tm_test_date_range > ok 1 - time_test_cases But --raw_output=kunit or equivalently --raw_output, you get > TAP version 14 > 1..26 > # Subtest: time_test_cases > 1..1 > ok 1 - time64_to_tm_test_date_range > ok 1 - time_test_cases It looks less readable in my opinion, and it also isn't "raw output." This is due to sharing code with kunit_parser.py, which wants to strip leading whitespace since it uses anchored regexes. We could update the kunit_parser.py code to tolerate leaading spaces, but this patch takes the easier way out and adds a bool flag. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 2 +- tools/testing/kunit/kunit_parser.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index e132b0654029..161a3b1b0217 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -206,7 +206,7 @@ def parse_tests(request: KunitParseRequest, metadata: kunit_json.Metadata, input if request.raw_output == 'all': pass elif request.raw_output == 'kunit': - output = kunit_parser.extract_tap_lines(output) + output = kunit_parser.extract_tap_lines(output, lstrip=False) for line in output: print(line.rstrip()) diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index 12d3ec77f427..1ae873e3e341 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -218,7 +218,7 @@ TAP_START = re.compile(r'TAP version ([0-9]+)$') KTAP_END = re.compile('(List of all partitions:|' 'Kernel panic - not syncing: VFS:|reboot: System halted)') -def extract_tap_lines(kernel_output: Iterable[str]) -> LineStream: +def extract_tap_lines(kernel_output: Iterable[str], lstrip=True) -> LineStream: """Extracts KTAP lines from the kernel output.""" def isolate_ktap_output(kernel_output: Iterable[str]) \ -> Iterator[Tuple[int, str]]: @@ -244,9 +244,11 @@ def extract_tap_lines(kernel_output: Iterable[str]) -> LineStream: # stop extracting KTAP lines break elif started: - # remove prefix and any indention and yield - # line with line number - line = line[prefix_len:].lstrip() + # remove the prefix and optionally any leading + # whitespace. Our parsing logic relies on this. + line = line[prefix_len:] + if lstrip: + line = line.lstrip() yield line_num, line return LineStream(lines=isolate_ktap_output(kernel_output)) From d20a6ba5e3be5f8d9002c6c5a5d4dfecc5dc48f9 Mon Sep 17 00:00:00 2001 From: Joe Fradley Date: Tue, 23 Aug 2022 07:24:54 -0700 Subject: [PATCH 02/18] kunit: add kunit.enable to enable/disable KUnit test This patch adds the kunit.enable module parameter that will need to be set to true in addition to KUNIT being enabled for KUnit tests to run. The default value is true giving backwards compatibility. However, for the production+testing use case the new config option KUNIT_DEFAULT_ENABLED can be set to N requiring the tester to opt-in by passing kunit.enable=1 to the kernel. Signed-off-by: Joe Fradley Reviewed-by: David Gow Signed-off-by: Shuah Khan --- .../admin-guide/kernel-parameters.txt | 6 +++++ include/kunit/test.h | 2 ++ lib/kunit/Kconfig | 11 +++++++++ lib/kunit/executor.c | 4 ++++ lib/kunit/test.c | 24 +++++++++++++++++++ tools/testing/kunit/kunit_kernel.py | 1 + 6 files changed, 48 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 426fa892d311..9f15ee63c4f4 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2436,6 +2436,12 @@ 0: force disabled 1: force enabled + kunit.enable= [KUNIT] Enable executing KUnit tests. Requires + CONFIG_KUNIT to be set to be fully enabled. The + default value can be overridden via + KUNIT_DEFAULT_ENABLED. + Default is 1 (enabled) + kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs. Default is 0 (don't ignore, but inject #GP) diff --git a/include/kunit/test.h b/include/kunit/test.h index 840a2c375065..a6d6892b7957 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -228,6 +228,8 @@ static inline void kunit_set_failure(struct kunit *test) WRITE_ONCE(test->status, KUNIT_FAILURE); } +bool kunit_enabled(void); + void kunit_init_test(struct kunit *test, const char *name, char *log); int kunit_run_tests(struct kunit_suite *suite); diff --git a/lib/kunit/Kconfig b/lib/kunit/Kconfig index 0b5dfb001bac..626719b95bad 100644 --- a/lib/kunit/Kconfig +++ b/lib/kunit/Kconfig @@ -59,4 +59,15 @@ config KUNIT_ALL_TESTS If unsure, say N. +config KUNIT_DEFAULT_ENABLED + bool "Default value of kunit.enable" + default y + help + Sets the default value of kunit.enable. If set to N then KUnit + tests will not execute unless kunit.enable=1 is passed to the + kernel command line. + + In most cases this should be left as Y. Only if additional opt-in + behavior is needed should this be set to N. + endif # KUNIT diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 5e223327196a..9bbc422c284b 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -190,6 +190,10 @@ int kunit_run_all_tests(void) { struct suite_set suite_set = {__kunit_suites_start, __kunit_suites_end}; int err = 0; + if (!kunit_enabled()) { + pr_info("kunit: disabled\n"); + goto out; + } if (filter_glob_param) { suite_set = kunit_filter_suites(&suite_set, filter_glob_param, &err); diff --git a/lib/kunit/test.c b/lib/kunit/test.c index b73d5bb5c473..1e54373309a4 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -54,6 +54,17 @@ void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...) EXPORT_SYMBOL_GPL(__kunit_fail_current_test); #endif +/* + * Enable KUnit tests to run. + */ +#ifdef CONFIG_KUNIT_DEFAULT_ENABLED +static bool enable_param = true; +#else +static bool enable_param; +#endif +module_param_named(enable, enable_param, bool, 0); +MODULE_PARM_DESC(enable, "Enable KUnit tests"); + /* * KUnit statistic mode: * 0 - disabled @@ -586,10 +597,20 @@ static void kunit_init_suite(struct kunit_suite *suite) suite->suite_init_err = 0; } +bool kunit_enabled(void) +{ + return enable_param; +} + int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites) { unsigned int i; + if (!kunit_enabled() && num_suites > 0) { + pr_info("kunit: disabled\n"); + return 0; + } + for (i = 0; i < num_suites; i++) { kunit_init_suite(suites[i]); kunit_run_tests(suites[i]); @@ -607,6 +628,9 @@ void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites) { unsigned int i; + if (!kunit_enabled()) + return; + for (i = 0; i < num_suites; i++) kunit_exit_suite(suites[i]); diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index f5c26ea89714..ef794da420d7 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -359,6 +359,7 @@ class LinuxSourceTree: args = [] if filter_glob: args.append('kunit.filter_glob='+filter_glob) + args.append('kunit.enable=1') process = self._ops.start(args, build_dir) assert process.stdout is not None # tell mypy it's set From 7d97635b72813d80f909ad24d7a64b2fe9a29c0b Mon Sep 17 00:00:00 2001 From: Joe Fradley Date: Tue, 23 Aug 2022 07:24:55 -0700 Subject: [PATCH 03/18] kunit: no longer call module_info(test, "Y") for kunit modules Because KUnit test execution is not a guarantee with the kunit.enable parameter we want to be careful to only taint the kernel when actual tests run. Calling module_info(test, "Y") for every KUnit module automatically causes the kernel to be tainted upon module load. Therefore, we're removing this call and relying on the KUnit framework to taint the kernel or not. Signed-off-by: Joe Fradley Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index a6d6892b7957..20cc4770cb3f 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -253,7 +253,6 @@ static inline int kunit_run_all_tests(void) #endif /* IS_BUILTIN(CONFIG_KUNIT) */ #define __kunit_test_suites(unique_array, ...) \ - MODULE_INFO(test, "Y"); \ static struct kunit_suite *unique_array[] \ __aligned(sizeof(struct kunit_suite *)) \ __used __section(".kunit_test_suites") = { __VA_ARGS__ } From 7e2d619411cbcb5ee6c6e97a53dcba605d276f44 Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sat, 13 Aug 2022 01:20:52 -0300 Subject: [PATCH 04/18] Documentation: kunit: fix trivial typo Missing closing block-quote Signed-off-by: Tales Aparecida Reviewed-by: David Gow Reviewed-by: Sadiya Kazi Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/run_wrapper.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/dev-tools/kunit/run_wrapper.rst index cce203138fb7..db1e867820e7 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -30,7 +30,7 @@ We may want to use the following options: .. code-block:: - ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all + ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all` - ``--timeout`` sets a maximum amount of time for tests to run. - ``--jobs`` sets the number of threads to build the kernel. From 8ae4826363cedc84b6b4e18952a49793586fa92b Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sat, 13 Aug 2022 01:20:53 -0300 Subject: [PATCH 05/18] Documentation: Kunit: Fix inconsistent titles Use the same wording when citing and describing Kunit parts. Signed-off-by: Tales Aparecida Reviewed-by: David Gow Reviewed-by: Sadiya Kazi Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/architecture.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/dev-tools/kunit/architecture.rst b/Documentation/dev-tools/kunit/architecture.rst index cf9e6e3eeae4..8efe792bdcb9 100644 --- a/Documentation/dev-tools/kunit/architecture.rst +++ b/Documentation/dev-tools/kunit/architecture.rst @@ -6,8 +6,8 @@ KUnit Architecture The KUnit architecture can be divided into two parts: -- Kernel testing library -- kunit_tool (Command line test harness) +- `In-Kernel Testing Framework`_ +- `kunit_tool (Command Line Test Harness)`_ In-Kernel Testing Framework =========================== From 43ca52a910d15026b474160c2b625db5be687f51 Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sat, 13 Aug 2022 01:20:54 -0300 Subject: [PATCH 06/18] Documentation: KUnit: Fix non-uml anchor The section was rewritten but its anchor got left behind. Fix the anchor and add some references to running on QEMU. Signed-off-by: Tales Aparecida Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/faq.rst | 6 +++--- Documentation/dev-tools/kunit/run_wrapper.rst | 2 ++ Documentation/dev-tools/kunit/usage.rst | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Documentation/dev-tools/kunit/faq.rst b/Documentation/dev-tools/kunit/faq.rst index 172e239791a8..f1b4cef68ced 100644 --- a/Documentation/dev-tools/kunit/faq.rst +++ b/Documentation/dev-tools/kunit/faq.rst @@ -31,7 +31,8 @@ For the most part, the KUnit core framework (what we use to write the tests) can compile to any architecture. It compiles like just another part of the kernel and runs when the kernel boots, or when built as a module, when the module is loaded. However, there is infrastructure, like the KUnit Wrapper -(``tools/testing/kunit/kunit.py``) that does not support other architectures. +(``tools/testing/kunit/kunit.py``) that might not support some architectures +(see :ref:`kunit-on-qemu`). In short, yes, you can run KUnit on other architectures, but it might require more work than using KUnit on UML. @@ -95,8 +96,7 @@ things to try. seeing. When tests are built-in, they will execute when the kernel boots, and modules will automatically execute associated tests when loaded. Test results can be collected from ``/sys/kernel/debug/kunit//results``, and - can be parsed with ``kunit.py parse``. For more details, see "KUnit on - non-UML architectures" in Documentation/dev-tools/kunit/usage.rst. + can be parsed with ``kunit.py parse``. For more details, see :ref:`kunit-on-qemu`. If none of the above tricks help, you are always welcome to email any issues to kunit-dev@googlegroups.com. diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/dev-tools/kunit/run_wrapper.rst index db1e867820e7..a1070def284f 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -165,6 +165,8 @@ example: if we only want to run KUnit resource tests, use: This uses the standard glob format with wildcard characters. +.. _kunit-on-qemu: + Run Tests on qemu ================= diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst index 44158eecb51e..2737863ef365 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -165,6 +165,8 @@ built as a module). For more information, see Documentation/dev-tools/kunit/api/test.rst. +.. _kunit-on-non-uml: + Writing Tests For Other Architectures ------------------------------------- @@ -544,8 +546,6 @@ By reusing the same ``cases`` array from above, we can write the test as a {} }; -.. _kunit-on-non-uml: - Exiting Early on Failed Expectations ------------------------------------ From 3920c725cbff5c6db69d7077716987a93b0e6a9a Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sat, 13 Aug 2022 01:20:55 -0300 Subject: [PATCH 07/18] Documentation: Kunit: Add ref for other kinds of tests Add an organic link to the "other kinds of tests" in the index page Signed-off-by: Tales Aparecida Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/faq.rst | 2 ++ Documentation/dev-tools/kunit/index.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/dev-tools/kunit/faq.rst b/Documentation/dev-tools/kunit/faq.rst index f1b4cef68ced..fae426f2634a 100644 --- a/Documentation/dev-tools/kunit/faq.rst +++ b/Documentation/dev-tools/kunit/faq.rst @@ -39,6 +39,8 @@ more work than using KUnit on UML. For more information, see :ref:`kunit-on-non-uml`. +.. _kinds-of-tests: + What is the difference between a unit test and other kinds of tests? ==================================================================== Most existing tests for the Linux kernel would be categorized as an integration diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst index 595205348d2d..bc91ad7b8961 100644 --- a/Documentation/dev-tools/kunit/index.rst +++ b/Documentation/dev-tools/kunit/index.rst @@ -95,6 +95,8 @@ Unit Testing Advantages - Improves code quality. - Encourages writing testable code. +Read also :ref:`kinds-of-tests`. + How do I use it? ================ From 2327f7e956bab3e25f472e8c9d0aa6380970a91a Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:39 -0300 Subject: [PATCH 08/18] Documentation: KUnit: remove duplicated docs for kunit_tool Delete "kunit-tool.rst" to remove repeated info from KUnit docs. "What is kunit_tool?" was integrated into index.rst, the remaining sections were moved into run_wrapper.rst and renamed as follows: "What is a .kunitconfig?" -> "Creating a ``.kunitconfig`` file" "Getting Started with kunit_tool" -> "Running tests with kunit_tool" "Configuring, Building, and Running Tests" -> "Configuring, building, and running tests" "Running Tests on QEMU" -> "Running tests on QEMU" "Parsing Test Results" -> "Parsing test results" "Filtering Tests" -> "Filtering tests" "Other Useful Options" -> "Running command-line arguments" Signed-off-by: Tales Aparecida Reviewed-by: Sadiya Kazi Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/index.rst | 3 - Documentation/dev-tools/kunit/kunit-tool.rst | 232 ------------------ Documentation/dev-tools/kunit/run_wrapper.rst | 32 +-- Documentation/dev-tools/kunit/start.rst | 2 - 4 files changed, 16 insertions(+), 253 deletions(-) delete mode 100644 Documentation/dev-tools/kunit/kunit-tool.rst diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst index bc91ad7b8961..d7187282ba28 100644 --- a/Documentation/dev-tools/kunit/index.rst +++ b/Documentation/dev-tools/kunit/index.rst @@ -13,7 +13,6 @@ KUnit - Linux Kernel Unit Testing run_wrapper run_manual usage - kunit-tool api/index style faq @@ -109,7 +108,5 @@ How do I use it? examples. * Documentation/dev-tools/kunit/api/index.rst - KUnit APIs used for testing. -* Documentation/dev-tools/kunit/kunit-tool.rst - kunit_tool helper - script. * Documentation/dev-tools/kunit/faq.rst - KUnit common questions and answers. diff --git a/Documentation/dev-tools/kunit/kunit-tool.rst b/Documentation/dev-tools/kunit/kunit-tool.rst deleted file mode 100644 index ae52e0f489f9..000000000000 --- a/Documentation/dev-tools/kunit/kunit-tool.rst +++ /dev/null @@ -1,232 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -================= -kunit_tool How-To -================= - -What is kunit_tool? -=================== - -kunit_tool is a script (``tools/testing/kunit/kunit.py``) that aids in building -the Linux kernel as UML (`User Mode Linux -`_), running KUnit tests, parsing -the test results and displaying them in a user friendly manner. - -kunit_tool addresses the problem of being able to run tests without needing a -virtual machine or actual hardware with User Mode Linux. User Mode Linux is a -Linux architecture, like ARM or x86; however, unlike other architectures it -compiles the kernel as a standalone Linux executable that can be run like any -other program directly inside of a host operating system. To be clear, it does -not require any virtualization support: it is just a regular program. - -What is a .kunitconfig? -======================= - -It's just a defconfig that kunit_tool looks for in the build directory -(``.kunit`` by default). kunit_tool uses it to generate a .config as you might -expect. In addition, it verifies that the generated .config contains the CONFIG -options in the .kunitconfig; the reason it does this is so that it is easy to -be sure that a CONFIG that enables a test actually ends up in the .config. - -It's also possible to pass a separate .kunitconfig fragment to kunit_tool, -which is useful if you have several different groups of tests you wish -to run independently, or if you want to use pre-defined test configs for -certain subsystems. - -Getting Started with kunit_tool -=============================== - -If a kunitconfig is present at the root directory, all you have to do is: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run - -However, you most likely want to use it with the following options: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all` - -- ``--timeout`` sets a maximum amount of time to allow tests to run. -- ``--jobs`` sets the number of threads to use to build the kernel. - -.. note:: - This command will work even without a .kunitconfig file: if no - .kunitconfig is present, a default one will be used instead. - -If you wish to use a different .kunitconfig file (such as one provided for -testing a particular subsystem), you can pass it as an option. - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run --kunitconfig=fs/ext4/.kunitconfig - -For a list of all the flags supported by kunit_tool, you can run: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run --help - -Configuring, Building, and Running Tests -======================================== - -It's also possible to run just parts of the KUnit build process independently, -which is useful if you want to make manual changes to part of the process. - -A .config can be generated from a .kunitconfig by using the ``config`` argument -when running kunit_tool: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py config - -Similarly, if you just want to build a KUnit kernel from the current .config, -you can use the ``build`` argument: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py build - -And, if you already have a built UML kernel with built-in KUnit tests, you can -run the kernel and display the test results with the ``exec`` argument: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py exec - -The ``run`` command which is discussed above is equivalent to running all three -of these in sequence. - -All of these commands accept a number of optional command-line arguments. The -``--help`` flag will give a complete list of these, or keep reading this page -for a guide to some of the more useful ones. - -Parsing Test Results -==================== - -KUnit tests output their results in TAP (Test Anything Protocol) format. -kunit_tool will, when running tests, parse this output and print a summary -which is much more pleasant to read. If you wish to look at the raw test -results in TAP format, you can pass the ``--raw_output`` argument. - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run --raw_output - -The raw output from test runs may contain other, non-KUnit kernel log -lines. You can see just KUnit output with ``--raw_output=kunit``: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run --raw_output=kunit - -If you have KUnit results in their raw TAP format, you can parse them and print -the human-readable summary with the ``parse`` command for kunit_tool. This -accepts a filename for an argument, or will read from standard input. - -.. code-block:: bash - - # Reading from a file - ./tools/testing/kunit/kunit.py parse /var/log/dmesg - # Reading from stdin - dmesg | ./tools/testing/kunit/kunit.py parse - -This is very useful if you wish to run tests in a configuration not supported -by kunit_tool (such as on real hardware, or an unsupported architecture). - -Filtering Tests -=============== - -It's possible to run only a subset of the tests built into a kernel by passing -a filter to the ``exec`` or ``run`` commands. For example, if you only wanted -to run KUnit resource tests, you could use: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run 'kunit-resource*' - -This uses the standard glob format for wildcards. - -Running Tests on QEMU -===================== - -kunit_tool supports running tests on QEMU as well as via UML (as mentioned -elsewhere). The default way of running tests on QEMU requires two flags: - -``--arch`` - Selects a collection of configs (Kconfig as well as QEMU configs - options, etc) that allow KUnit tests to be run on the specified - architecture in a minimal way; this is usually not much slower than - using UML. The architecture argument is the same as the name of the - option passed to the ``ARCH`` variable used by Kbuild. Not all - architectures are currently supported by this flag, but can be handled - by the ``--qemu_config`` discussed later. If ``um`` is passed (or this - this flag is ignored) the tests will run via UML. Non-UML architectures, - e.g. i386, x86_64, arm, um, etc. Non-UML run on QEMU. - -``--cross_compile`` - Specifies the use of a toolchain by Kbuild. The argument passed here is - the same passed to the ``CROSS_COMPILE`` variable used by Kbuild. As a - reminder this will be the prefix for the toolchain binaries such as gcc - for example ``sparc64-linux-gnu-`` if you have the sparc toolchain - installed on your system, or - ``$HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-linux-`` - if you have downloaded the microblaze toolchain from the 0-day website - to a directory in your home directory called ``toolchains``. - -In many cases it is likely that you may want to run an architecture which is -not supported by the ``--arch`` flag, or you may want to just run KUnit tests -on QEMU using a non-default configuration. For this use case, you can write -your own QemuConfig. These QemuConfigs are written in Python. They must have an -import line ``from ..qemu_config import QemuArchParams`` at the top of the file -and the file must contain a variable called ``QEMU_ARCH`` that has an instance -of ``QemuArchParams`` assigned to it. An example can be seen in -``tools/testing/kunit/qemu_configs/x86_64.py``. - -Once you have a QemuConfig you can pass it into kunit_tool using the -``--qemu_config`` flag; when used this flag replaces the ``--arch`` flag. If we -were to do this with the ``x86_64.py`` example from above, the invocation would -look something like this: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run \ - --timeout=60 \ - --jobs=12 \ - --qemu_config=./tools/testing/kunit/qemu_configs/x86_64.py - -Other Useful Options -==================== - -kunit_tool has a number of other command-line arguments which can be useful -when adapting it to fit your environment or needs. - -Some of the more useful ones are: - -``--help`` - Lists all of the available options. Note that different commands - (``config``, ``build``, ``run``, etc) will have different supported - options. Place ``--help`` before the command to list common options, - and after the command for options specific to that command. - -``--build_dir`` - Specifies the build directory that kunit_tool will use. This is where - the .kunitconfig file is located, as well as where the .config and - compiled kernel will be placed. Defaults to ``.kunit``. - -``--make_options`` - Specifies additional options to pass to ``make`` when compiling a - kernel (with the ``build`` or ``run`` commands). For example, to enable - compiler warnings, you can pass ``--make_options W=1``. - -``--alltests`` - Builds a UML kernel with all config options enabled using ``make - allyesconfig``. This allows you to run as many tests as is possible, - but is very slow and prone to breakage as new options are added or - modified. In most cases, enabling all tests which have satisfied - dependencies by adding ``CONFIG_KUNIT_ALL_TESTS=1`` to your - .kunitconfig is preferable. - -There are several other options (and new ones are often added), so do check -``--help`` if you're looking for something not mentioned here. diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/dev-tools/kunit/run_wrapper.rst index a1070def284f..518cf87ea732 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0 -========================= -Run Tests with kunit_tool -========================= +============================= +Running tests with kunit_tool +============================= We can either run KUnit tests using kunit_tool or can run tests manually, and then use kunit_tool to parse the results. To run tests @@ -58,8 +58,8 @@ To view kunit_tool flags (optional command-line arguments), run: ./tools/testing/kunit/kunit.py run --help -Create a ``.kunitconfig`` File -=============================== +Creating a ``.kunitconfig`` file +================================ If we want to run a specific set of tests (rather than those listed in the KUnit ``defconfig``), we can provide Kconfig options in the @@ -98,8 +98,8 @@ have not included the options dependencies. The build dir needs to be set for ``make menuconfig`` to work, therefore by default use ``make O=.kunit menuconfig``. -Configure, Build, and Run Tests -=============================== +Configuring, building, and running tests +======================================== If we want to make manual changes to the KUnit build process, we can run part of the KUnit build process independently. @@ -125,11 +125,11 @@ argument: ./tools/testing/kunit/kunit.py exec -The ``run`` command discussed in section: **Run Tests with kunit_tool**, +The ``run`` command discussed in section: **Running tests with kunit_tool**, is equivalent to running the above three commands in sequence. -Parse Test Results -================== +Parsing test results +==================== KUnit tests output displays results in TAP (Test Anything Protocol) format. When running tests, kunit_tool parses this output and prints @@ -152,8 +152,8 @@ standard input. # Reading from stdin dmesg | ./tools/testing/kunit/kunit.py parse -Run Selected Test Suites -======================== +Filtering tests +=============== By passing a bash style glob filter to the ``exec`` or ``run`` commands, we can run a subset of the tests built into a kernel . For @@ -167,8 +167,8 @@ This uses the standard glob format with wildcard characters. .. _kunit-on-qemu: -Run Tests on qemu -================= +Running tests on QEMU +===================== kunit_tool supports running tests on qemu as well as via UML. To run tests on qemu, by default it requires two flags: @@ -231,8 +231,8 @@ as --jobs=12 \ --qemu_config=./tools/testing/kunit/qemu_configs/x86_64.py -Command-Line Arguments -====================== +Running command-line arguments +============================== kunit_tool has a number of other command-line arguments which can be useful for our test environment. Below are the most commonly used diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 867a4bba6bf6..e730df1f468e 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -254,7 +254,5 @@ Next Steps examples. * Documentation/dev-tools/kunit/api/index.rst - KUnit APIs used for testing. -* Documentation/dev-tools/kunit/kunit-tool.rst - kunit_tool helper - script. * Documentation/dev-tools/kunit/faq.rst - KUnit common questions and answers. From 5ceb9a2558593658276854770f0d4e84fbcddf14 Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:40 -0300 Subject: [PATCH 09/18] Documentation: KUnit: avoid repeating "kunit.py run" in start.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Combine two sections mentioning "kunit.py run" to streamline the getting-started guide. Update "kunit.py run" expected output in the guide and run_wrapper. Signed-off-by: Tales Aparecida Reviewed-by: Maíra Canal Reviewed-by: Sadiya Kazi Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/run_wrapper.rst | 2 +- Documentation/dev-tools/kunit/start.rst | 38 ++++++++----------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Documentation/dev-tools/kunit/run_wrapper.rst b/Documentation/dev-tools/kunit/run_wrapper.rst index 518cf87ea732..6b33caf6c8ab 100644 --- a/Documentation/dev-tools/kunit/run_wrapper.rst +++ b/Documentation/dev-tools/kunit/run_wrapper.rst @@ -22,7 +22,7 @@ We should see the following: .. code-block:: - Generating .config... + Configuring KUnit Kernel ... Building KUnit kernel... Starting KUnit kernel... diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index e730df1f468e..2e31350a85e1 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -19,7 +19,21 @@ can run kunit_tool: ./tools/testing/kunit/kunit.py run -For more information on this wrapper, see: +If everything worked correctly, you should see the following: + +.. code-block:: + + Configuring KUnit Kernel ... + Building KUnit Kernel ... + Starting KUnit Kernel ... + +The tests will pass or fail. + +.. note :: + Because it is building a lot of sources for the first time, + the ``Building KUnit Kernel`` step may take a while. + +For detailed information on this wrapper, see: Documentation/dev-tools/kunit/run_wrapper.rst. Creating a ``.kunitconfig`` @@ -74,28 +88,6 @@ you if you have not included dependencies for the options used. tools like ``make menuconfig O=.kunit``. As long as its a superset of ``.kunitconfig``, kunit.py won't overwrite your changes. -Running Tests (KUnit Wrapper) ------------------------------ -1. To make sure that everything is set up correctly, invoke the Python - wrapper from your kernel repository: - -.. code-block:: bash - - ./tools/testing/kunit/kunit.py run - -If everything worked correctly, you should see the following: - -.. code-block:: - - Generating .config ... - Building KUnit Kernel ... - Starting KUnit Kernel ... - -The tests will pass or fail. - -.. note :: - Because it is building a lot of sources for the first time, the - ``Building KUnit kernel`` may take a while. Running Tests without the KUnit Wrapper ======================================= From c5b6c4ecbd95c8e56ef1350ab091e57e401b01fe Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:41 -0300 Subject: [PATCH 10/18] Documentation: KUnit: add note about mrproper in start.rst The "Getting Started" guide should be beginner-friendly, therefore add a note about the requirement of a clean source tree when running kunit_tool for the first time, and its related error. Signed-off-by: Tales Aparecida Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/start.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 2e31350a85e1..9beec7d6ac4b 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -19,6 +19,22 @@ can run kunit_tool: ./tools/testing/kunit/kunit.py run +.. note :: + You may see the following error: + "The source tree is not clean, please run 'make ARCH=um mrproper'" + + This happens because internally kunit.py specifies ``.kunit`` + (default option) as the build directory in the command ``make O=output/dir`` + through the argument ``--build_dir``. Hence, before starting an + out-of-tree build, the source tree must be clean. + + There is also the same caveat mentioned in the "Build directory for + the kernel" section of the :doc:`admin-guide `, + that is, its use, it must be used for all invocations of ``make``. + The good news is that it can indeed be solved by running + ``make ARCH=um mrproper``, just be aware that this will delete the + current configuration and all generated files. + If everything worked correctly, you should see the following: .. code-block:: From 7a79b7df4e5122ae3b5b5f2bd5b52ecb1295398a Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:42 -0300 Subject: [PATCH 11/18] Documentation: KUnit: Reword start guide for selecting tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reword "Creating a ``.kunitconfig``" into "Selecting which tests to run" covering the current alternatives for editing configs and glob-filtering Signed-off-by: Tales Aparecida Reviewed-by: Maíra Canal Reviewed-by:Sadiya Kazi Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/start.rst | 96 +++++++++++++++++-------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 9beec7d6ac4b..adf782507999 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -52,27 +52,20 @@ The tests will pass or fail. For detailed information on this wrapper, see: Documentation/dev-tools/kunit/run_wrapper.rst. -Creating a ``.kunitconfig`` ---------------------------- +Selecting which tests to run +---------------------------- -By default, kunit_tool runs a selection of tests. However, you can specify which -unit tests to run by creating a ``.kunitconfig`` file with kernel config options -that enable only a specific set of tests and their dependencies. -The ``.kunitconfig`` file contains a list of kconfig options which are required -to run the desired targets. The ``.kunitconfig`` also contains any other test -specific config options, such as test dependencies. For example: the -``FAT_FS`` tests - ``FAT_KUNIT_TEST``, depends on -``FAT_FS``. ``FAT_FS`` can be enabled by selecting either ``MSDOS_FS`` -or ``VFAT_FS``. To run ``FAT_KUNIT_TEST``, the ``.kunitconfig`` has: +By default, kunit_tool runs all tests reachable with minimal configuration, +that is, using default values for most of the kconfig options. However, +you can select which tests to run by: -.. code-block:: none +- `Customizing Kconfig`_ used to compile the kernel, or +- `Filtering tests by name`_ to select specifically which compiled tests to run. - CONFIG_KUNIT=y - CONFIG_MSDOS_FS=y - CONFIG_FAT_KUNIT_TEST=y - -1. A good starting point for the ``.kunitconfig`` is the KUnit default config. - You can generate it by running: +Customizing Kconfig +~~~~~~~~~~~~~~~~~~~ +A good starting point for the ``.kunitconfig`` is the KUnit default config. +If you didn't run ``kunit.py run`` yet, you can generate it by running: .. code-block:: bash @@ -84,27 +77,70 @@ or ``VFAT_FS``. To run ``FAT_KUNIT_TEST``, the ``.kunitconfig`` has: ``.kunitconfig`` lives in the ``--build_dir`` used by kunit.py, which is ``.kunit`` by default. -.. note :: - You may want to remove CONFIG_KUNIT_ALL_TESTS from the ``.kunitconfig`` as - it will enable a number of additional tests that you may not want. - -2. You can then add any other Kconfig options, for example: - -.. code-block:: none - - CONFIG_LIST_KUNIT_TEST=y - Before running the tests, kunit_tool ensures that all config options set in ``.kunitconfig`` are set in the kernel ``.config``. It will warn you if you have not included dependencies for the options used. -.. note :: - If you change the ``.kunitconfig``, kunit.py will trigger a rebuild of the +There are many ways to customize the configurations: + +a. Edit ``.kunit/.kunitconfig``. The file should contain the list of kconfig + options required to run the desired tests, including their dependencies. + You may want to remove CONFIG_KUNIT_ALL_TESTS from the ``.kunitconfig`` as + it will enable a number of additional tests that you may not want. + If you need to run on an architecture other than UML see :ref:`kunit-on-qemu`. + +b. Enable additional kconfig options on top of ``.kunit/.kunitconfig``. + For example, to include the kernel's linked-list test you can run:: + + ./tools/testing/kunit/kunit.py run \ + --kconfig_add CONFIG_LIST_KUNIT_TEST=y + +c. Provide the path of one or more .kunitconfig files from the tree. + For example, to run only ``FAT_FS`` and ``EXT4`` tests you can run:: + + ./tools/testing/kunit/kunit.py run \ + --kunitconfig ./fs/fat/.kunitconfig \ + --kunitconfig ./fs/ext4/.kunitconfig + +d. If you change the ``.kunitconfig``, kunit.py will trigger a rebuild of the ``.config`` file. But you can edit the ``.config`` file directly or with tools like ``make menuconfig O=.kunit``. As long as its a superset of ``.kunitconfig``, kunit.py won't overwrite your changes. +.. note :: + + To save a .kunitconfig after finding a satisfactory configuration:: + + make savedefconfig O=.kunit + cp .kunit/defconfig .kunit/.kunitconfig + +Filtering tests by name +~~~~~~~~~~~~~~~~~~~~~~~ +If you want to be more specific than Kconfig can provide, it is also possible +to select which tests to execute at boot-time by passing a glob filter +(read instructions regarding the pattern in the manpage :manpage:`glob(7)`). +If there is a ``"."`` (period) in the filter, it will be interpreted as a +separator between the name of the test suite and the test case, +otherwise, it will be interpreted as the name of the test suite. +For example, let's assume we are using the default config: + +a. inform the name of a test suite, like ``"kunit_executor_test"``, + to run every test case it contains:: + + ./tools/testing/kunit/kunit.py run "kunit_executor_test" + +b. inform the name of a test case prefixed by its test suite, + like ``"example.example_simple_test"``, to run specifically that test case:: + + ./tools/testing/kunit/kunit.py run "example.example_simple_test" + +c. use wildcard characters (``*?[``) to run any test case that matches the pattern, + like ``"*.*64*"`` to run test cases containing ``"64"`` in the name inside + any test suite:: + + ./tools/testing/kunit/kunit.py run "*.*64*" + Running Tests without the KUnit Wrapper ======================================= If you do not want to use the KUnit Wrapper (for example: you want code From deff8d2955aa045d7053a7770cdae9874af6f474 Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:43 -0300 Subject: [PATCH 12/18] Documentation: KUnit: add intro to the getting-started page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the objective of the Getting Started page, which should be a brief and beginner-friendly walkthrough for running and writing tests, showing the reader where to find detailed instructions in other pages. Signed-off-by: Tales Aparecida Reviewed-by: Maíra Canal Reviewed-by:Sadiya Kazi Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/start.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index adf782507999..75fd05286396 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -4,6 +4,10 @@ Getting Started =============== +This page contains an overview of the kunit_tool and KUnit framework, +teaching how to run existing tests and then how to write a simple test case, +and covers common problems users face when using KUnit for the first time. + Installing Dependencies ======================= KUnit has the same dependencies as the Linux kernel. As long as you can From 79c18e37c4e645560f3952bf177a10b43e94bf88 Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:44 -0300 Subject: [PATCH 13/18] Documentation: KUnit: update links in the index page Replace out-of-date external links with references to the kernel documentation, replacing TAP webpage for the more appropriate KTAP documentation and the UML webpage by its documentation. Signed-off-by: Tales Aparecida Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/index.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst index d7187282ba28..f5d13f1d37be 100644 --- a/Documentation/dev-tools/kunit/index.rst +++ b/Documentation/dev-tools/kunit/index.rst @@ -28,10 +28,10 @@ KUnit (Kernel unit testing framework) provides a common framework for unit tests within the Linux kernel. Using KUnit, you can define groups of test cases called test suites. The tests either run on kernel boot if built-in, or load as a module. KUnit automatically flags and reports -failed test cases in the kernel log. The test results appear in `TAP -(Test Anything Protocol) format `_. It is inspired by -JUnit, Python’s unittest.mock, and GoogleTest/GoogleMock (C++ unit testing -framework). +failed test cases in the kernel log. The test results appear in +:doc:`KTAP (Kernel - Test Anything Protocol) format`. +It is inspired by JUnit, Python’s unittest.mock, and GoogleTest/GoogleMock +(C++ unit testing framework). KUnit tests are part of the kernel, written in the C (programming) language, and test parts of the Kernel implementation (example: a C @@ -45,8 +45,9 @@ internal system functionality. KUnit runs in kernel space and is not restricted to things exposed to user-space. In addition, KUnit has kunit_tool, a script (``tools/testing/kunit/kunit.py``) -that configures the Linux kernel, runs KUnit tests under QEMU or UML (`User Mode -Linux `_), parses the test results and +that configures the Linux kernel, runs KUnit tests under QEMU or UML +(:doc:`User Mode Linux `), +parses the test results and displays them in a user friendly manner. Features From 0f3f1123ac6e14a2c0a32f7a43163e6704beb74f Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:45 -0300 Subject: [PATCH 14/18] lib: overflow: update reference to kunit-tool Replace URL with an updated path to the full Documentation page Signed-off-by: Tales Aparecida Reviewed-by: Kees Cook Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/overflow_kunit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c index 7e3e43679b73..78075106c0df 100644 --- a/lib/overflow_kunit.c +++ b/lib/overflow_kunit.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR MIT /* * Test cases for arithmetic overflow checks. See: - * https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html#configuring-building-and-running-tests + * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst * ./tools/testing/kunit/kunit.py run overflow [--raw_output] */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt From 4bba2a04ef98b92f21eddb492d7602d6ded026cd Mon Sep 17 00:00:00 2001 From: Tales Aparecida Date: Sun, 21 Aug 2022 23:26:46 -0300 Subject: [PATCH 15/18] lib: stackinit: update reference to kunit-tool Replace URL with an updated path to the full Documentation page Signed-off-by: Tales Aparecida Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/stackinit_kunit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stackinit_kunit.c b/lib/stackinit_kunit.c index 35c69aa425b2..4591d6cf5e01 100644 --- a/lib/stackinit_kunit.c +++ b/lib/stackinit_kunit.c @@ -3,7 +3,7 @@ * Test cases for compiler-based stack variable zeroing via * -ftrivial-auto-var-init={zero,pattern} or CONFIG_GCC_PLUGIN_STRUCTLEAK*. * For example, see: - * https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html#configuring-building-and-running-tests + * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst * ./tools/testing/kunit/kunit.py run stackinit [--raw_output] \ * --make_option LLVM=1 \ * --kconfig_add CONFIG_INIT_STACK_ALL_ZERO=y From cb8a7d5340a3b1ad3f9099f9fbd7fa4e2309e83b Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Fri, 2 Sep 2022 13:22:47 -0700 Subject: [PATCH 16/18] kunit: tool: remove UML specific options from all_tests_uml.config Commit 6fc3a8636a7b ("kunit: tool: Enable virtio/PCI by default on UML") made it so we enable these options by default for UML. Specifying them here is now redundant. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Signed-off-by: Shuah Khan --- tools/testing/kunit/configs/all_tests_uml.config | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/testing/kunit/configs/all_tests_uml.config b/tools/testing/kunit/configs/all_tests_uml.config index bdee36bef4a3..f990cbb73250 100644 --- a/tools/testing/kunit/configs/all_tests_uml.config +++ b/tools/testing/kunit/configs/all_tests_uml.config @@ -16,8 +16,6 @@ CONFIG_EXT4_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y -CONFIG_VIRTIO_UML=y -CONFIG_UML_PCI_OVER_VIRTIO=y CONFIG_PCI=y CONFIG_USB4=y From 980ac3ad051215150b637e26f3f46873687909a9 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Fri, 2 Sep 2022 13:22:48 -0700 Subject: [PATCH 17/18] kunit: tool: rename all_test_uml.config, use it for --alltests Context: 1. all_tests_uml.config used to be UML specific back when users to manually specify CONFIG_VIRTIO_UML=y to enable CONFIG_PCI=y. 2. --alltests used allyesconfig along with a curated list of options to disable. It's only ever worked for brief periods of time and has perennially been broken due to compile issues. Now all_tests_uml.config should work across ~all architectures. Let's instead use this to implement --alltests. Note: if anyone was using all_tests_uml.config, this change breaks them. I think that's unlikely since it was added in 5.19 and was a lot to type: --kunitconfig=tools/testing/kunit/configs/all_tests_uml.config. We could make it a symlink to the new name, but I don't think the caution is warranted here. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Signed-off-by: Shuah Khan --- ...{all_tests_uml.config => all_tests.config} | 0 .../kunit/configs/broken_on_uml.config | 44 ------------------- tools/testing/kunit/kunit.py | 24 +++++----- tools/testing/kunit/kunit_kernel.py | 29 +----------- tools/testing/kunit/kunit_tool_test.py | 26 ++++++++--- 5 files changed, 33 insertions(+), 90 deletions(-) rename tools/testing/kunit/configs/{all_tests_uml.config => all_tests.config} (100%) delete mode 100644 tools/testing/kunit/configs/broken_on_uml.config diff --git a/tools/testing/kunit/configs/all_tests_uml.config b/tools/testing/kunit/configs/all_tests.config similarity index 100% rename from tools/testing/kunit/configs/all_tests_uml.config rename to tools/testing/kunit/configs/all_tests.config diff --git a/tools/testing/kunit/configs/broken_on_uml.config b/tools/testing/kunit/configs/broken_on_uml.config deleted file mode 100644 index 690870043ac0..000000000000 --- a/tools/testing/kunit/configs/broken_on_uml.config +++ /dev/null @@ -1,44 +0,0 @@ -# These are currently broken on UML and prevent allyesconfig from building -# CONFIG_STATIC_LINK is not set -# CONFIG_UML_NET_VECTOR is not set -# CONFIG_UML_NET_VDE is not set -# CONFIG_UML_NET_PCAP is not set -# CONFIG_NET_PTP_CLASSIFY is not set -# CONFIG_IP_VS is not set -# CONFIG_BRIDGE_EBT_BROUTE is not set -# CONFIG_BRIDGE_EBT_T_FILTER is not set -# CONFIG_BRIDGE_EBT_T_NAT is not set -# CONFIG_MTD_NAND_CADENCE is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_BLK_DEV_NULL_BLK is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_NET_VENDOR_XILINX is not set -# CONFIG_NULL_TTY is not set -# CONFIG_PTP_1588_CLOCK is not set -# CONFIG_PINCTRL_EQUILIBRIUM is not set -# CONFIG_DMABUF_SELFTESTS is not set -# CONFIG_COMEDI is not set -# CONFIG_XIL_AXIS_FIFO is not set -# CONFIG_EXFAT_FS is not set -# CONFIG_STM_DUMMY is not set -# CONFIG_FSI_MASTER_ASPEED is not set -# CONFIG_JFS_FS is not set -# CONFIG_UBIFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_CRYPTO_DEV_SAFEXCEL is not set -# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set -# CONFIG_KCOV is not set -# CONFIG_LKDTM is not set -# CONFIG_REED_SOLOMON_TEST is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_MEMINIT is not set -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_DEBUG_INFO_BTF is not set -# CONFIG_PTP_1588_CLOCK_INES is not set -# CONFIG_QCOM_CPR is not set -# CONFIG_RESET_BRCMSTB_RESCAL is not set -# CONFIG_RESET_INTEL_GW is not set -# CONFIG_ADI_AXI_ADC is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_PAGE_POISONING is not set diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 161a3b1b0217..4d4663fb578b 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -44,7 +44,6 @@ class KunitConfigRequest: @dataclass class KunitBuildRequest(KunitConfigRequest): jobs: int - alltests: bool @dataclass class KunitParseRequest: @@ -55,7 +54,6 @@ class KunitParseRequest: class KunitExecRequest(KunitParseRequest): build_dir: str timeout: int - alltests: bool filter_glob: str kernel_args: Optional[List[str]] run_isolated: Optional[str] @@ -90,8 +88,7 @@ def build_tests(linux: kunit_kernel.LinuxSourceTree, stdout.print_with_timestamp('Building KUnit Kernel ...') build_start = time.time() - success = linux.build_kernel(request.alltests, - request.jobs, + success = linux.build_kernel(request.jobs, request.build_dir, request.make_options) build_end = time.time() @@ -118,7 +115,7 @@ def _list_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) args.extend(request.kernel_args) output = linux.run_kernel(args=args, - timeout=None if request.alltests else request.timeout, + timeout=request.timeout, filter_glob=request.filter_glob, build_dir=request.build_dir) lines = kunit_parser.extract_tap_lines(output) @@ -165,7 +162,7 @@ def exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) - test_start = time.time() run_result = linux.run_kernel( args=request.kernel_args, - timeout=None if request.alltests else request.timeout, + timeout=request.timeout, filter_glob=filter_glob, build_dir=request.build_dir) @@ -288,7 +285,7 @@ def add_common_opts(parser) -> None: help='X=Y make option, can be repeated.', action='append', metavar='X=Y') parser.add_argument('--alltests', - help='Run all KUnit tests through allyesconfig', + help='Run all KUnit tests via tools/testing/kunit/configs/all_tests.config', action='store_true') parser.add_argument('--kunitconfig', help='Path to Kconfig fragment that enables KUnit tests.' @@ -381,8 +378,14 @@ def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree for arg in cli_args.qemu_args: qemu_args.extend(shlex.split(arg)) + kunitconfigs = cli_args.kunitconfig if cli_args.kunitconfig else [] + if cli_args.alltests: + # Prepend so user-specified options take prio if we ever allow + # --kunitconfig options to have differing options. + kunitconfigs = [kunit_kernel.ALL_TESTS_CONFIG_PATH] + kunitconfigs + return kunit_kernel.LinuxSourceTree(cli_args.build_dir, - kunitconfig_paths=cli_args.kunitconfig, + kunitconfig_paths=kunitconfigs, kconfig_add=cli_args.kconfig_add, arch=cli_args.arch, cross_compile=cli_args.cross_compile, @@ -441,7 +444,6 @@ def main(argv): request = KunitRequest(build_dir=cli_args.build_dir, make_options=cli_args.make_options, jobs=cli_args.jobs, - alltests=cli_args.alltests, raw_output=cli_args.raw_output, json=cli_args.json, timeout=cli_args.timeout, @@ -469,8 +471,7 @@ def main(argv): linux = tree_from_args(cli_args) request = KunitBuildRequest(build_dir=cli_args.build_dir, make_options=cli_args.make_options, - jobs=cli_args.jobs, - alltests=cli_args.alltests) + jobs=cli_args.jobs) result = config_and_build_tests(linux, request) stdout.print_with_timestamp(( 'Elapsed time: %.3fs\n') % ( @@ -483,7 +484,6 @@ def main(argv): build_dir=cli_args.build_dir, json=cli_args.json, timeout=cli_args.timeout, - alltests=cli_args.alltests, filter_glob=cli_args.filter_glob, kernel_args=cli_args.kernel_args, run_isolated=cli_args.run_isolated) diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index ef794da420d7..53e90c335834 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -25,7 +25,7 @@ KCONFIG_PATH = '.config' KUNITCONFIG_PATH = '.kunitconfig' OLD_KUNITCONFIG_PATH = 'last_used_kunitconfig' DEFAULT_KUNITCONFIG_PATH = 'tools/testing/kunit/configs/default.config' -BROKEN_ALLCONFIG_PATH = 'tools/testing/kunit/configs/broken_on_uml.config' +ALL_TESTS_CONFIG_PATH = 'tools/testing/kunit/configs/all_tests.config' UML_KCONFIG_PATH = 'tools/testing/kunit/configs/arch_uml.config' OUTFILE_PATH = 'test.log' ABS_TOOL_PATH = os.path.abspath(os.path.dirname(__file__)) @@ -57,9 +57,6 @@ class LinuxSourceTreeOperations: def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig: return base_kunitconfig - def make_allyesconfig(self, build_dir: str, make_options) -> None: - raise ConfigError('Only the "um" arch is supported for alltests') - def make_olddefconfig(self, build_dir: str, make_options) -> None: command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, 'olddefconfig'] if self._cross_compile: @@ -144,26 +141,6 @@ class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations): kconfig.merge_in_entries(base_kunitconfig) return kconfig - def make_allyesconfig(self, build_dir: str, make_options) -> None: - stdout.print_with_timestamp( - 'Enabling all CONFIGs for UML...') - command = ['make', 'ARCH=um', 'O=' + build_dir, 'allyesconfig'] - if make_options: - command.extend(make_options) - process = subprocess.Popen( - command, - stdout=subprocess.DEVNULL, - stderr=subprocess.STDOUT) - process.wait() - stdout.print_with_timestamp( - 'Disabling broken configs to run KUnit tests...') - - with open(get_kconfig_path(build_dir), 'a') as config: - with open(BROKEN_ALLCONFIG_PATH, 'r') as disable: - config.write(disable.read()) - stdout.print_with_timestamp( - 'Starting Kernel with all configs takes a few minutes...') - def start(self, params: List[str], build_dir: str) -> subprocess.Popen: """Runs the Linux UML binary. Must be named 'linux'.""" linux_bin = os.path.join(build_dir, 'linux') @@ -343,10 +320,8 @@ class LinuxSourceTree: os.remove(kconfig_path) return self.build_config(build_dir, make_options) - def build_kernel(self, alltests, jobs, build_dir: str, make_options) -> bool: + def build_kernel(self, jobs, build_dir: str, make_options) -> bool: try: - if alltests: - self._ops.make_allyesconfig(build_dir, make_options) self._ops.make_olddefconfig(build_dir, make_options) self._ops.make(jobs, build_dir, make_options) except (ConfigError, BuildError) as e: diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py index 446ac432d9a4..e2cd2cc2e98f 100755 --- a/tools/testing/kunit/kunit_tool_test.py +++ b/tools/testing/kunit/kunit_tool_test.py @@ -549,7 +549,7 @@ class KUnitMainTest(unittest.TestCase): def test_build_passes_args_pass(self): kunit.main(['build']) self.assertEqual(self.linux_source_mock.build_reconfig.call_count, 1) - self.linux_source_mock.build_kernel.assert_called_once_with(False, kunit.get_default_jobs(), '.kunit', None) + self.linux_source_mock.build_kernel.assert_called_once_with(kunit.get_default_jobs(), '.kunit', None) self.assertEqual(self.linux_source_mock.run_kernel.call_count, 0) def test_exec_passes_args_pass(self): @@ -664,7 +664,7 @@ class KUnitMainTest(unittest.TestCase): build_dir = '.kunit' jobs = kunit.get_default_jobs() kunit.main(['build', '--build_dir', build_dir]) - self.linux_source_mock.build_kernel.assert_called_once_with(False, jobs, build_dir, None) + self.linux_source_mock.build_kernel.assert_called_once_with(jobs, build_dir, None) def test_exec_builddir(self): build_dir = '.kunit' @@ -695,6 +695,18 @@ class KUnitMainTest(unittest.TestCase): qemu_config_path=None, extra_qemu_args=[]) + def test_config_alltests(self): + kunit.main(['config', '--kunitconfig=mykunitconfig', '--alltests']) + # Just verify that we parsed and initialized it correctly here. + self.mock_linux_init.assert_called_once_with('.kunit', + kunitconfig_paths=[kunit_kernel.ALL_TESTS_CONFIG_PATH, 'mykunitconfig'], + kconfig_add=None, + arch='um', + cross_compile=None, + qemu_config_path=None, + extra_qemu_args=[]) + + @mock.patch.object(kunit_kernel, 'LinuxSourceTree') def test_run_multiple_kunitconfig(self, mock_linux_init): mock_linux_init.return_value = self.linux_source_mock @@ -712,7 +724,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run', '--kconfig_add=CONFIG_KASAN=y', '--kconfig_add=CONFIG_KCSAN=y']) # Just verify that we parsed and initialized it correctly here. self.mock_linux_init.assert_called_once_with('.kunit', - kunitconfig_paths=None, + kunitconfig_paths=[], kconfig_add=['CONFIG_KASAN=y', 'CONFIG_KCSAN=y'], arch='um', cross_compile=None, @@ -723,7 +735,7 @@ class KUnitMainTest(unittest.TestCase): kunit.main(['run', '--arch=x86_64', '--qemu_args', '-m 2048']) # Just verify that we parsed and initialized it correctly here. self.mock_linux_init.assert_called_once_with('.kunit', - kunitconfig_paths=None, + kunitconfig_paths=[], kconfig_add=None, arch='x86_64', cross_compile=None, @@ -742,7 +754,7 @@ class KUnitMainTest(unittest.TestCase): self.linux_source_mock.run_kernel.return_value = ['TAP version 14', 'init: random output'] + want got = kunit._list_tests(self.linux_source_mock, - kunit.KunitExecRequest(None, None, '.kunit', 300, False, 'suite*', None, 'suite')) + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'suite')) self.assertEqual(got, want) # Should respect the user's filter glob when listing tests. @@ -757,7 +769,7 @@ class KUnitMainTest(unittest.TestCase): # Should respect the user's filter glob when listing tests. mock_tests.assert_called_once_with(mock.ANY, - kunit.KunitExecRequest(None, None, '.kunit', 300, False, 'suite*.test*', None, 'suite')) + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*.test*', None, 'suite')) self.linux_source_mock.run_kernel.assert_has_calls([ mock.call(args=None, build_dir='.kunit', filter_glob='suite.test*', timeout=300), mock.call(args=None, build_dir='.kunit', filter_glob='suite2.test*', timeout=300), @@ -770,7 +782,7 @@ class KUnitMainTest(unittest.TestCase): # Should respect the user's filter glob when listing tests. mock_tests.assert_called_once_with(mock.ANY, - kunit.KunitExecRequest(None, None, '.kunit', 300, False, 'suite*', None, 'test')) + kunit.KunitExecRequest(None, None, '.kunit', 300, 'suite*', None, 'test')) self.linux_source_mock.run_kernel.assert_has_calls([ mock.call(args=None, build_dir='.kunit', filter_glob='suite.test1', timeout=300), mock.call(args=None, build_dir='.kunit', filter_glob='suite.test2', timeout=300), From 4e37057387cca749b7fbc8c77e3d86605117fffd Mon Sep 17 00:00:00 2001 From: Khalid Masum Date: Wed, 28 Sep 2022 10:00:58 +0600 Subject: [PATCH 18/18] Documentation: Kunit: Use full path to .kunitconfig The numbered list contains full path to every files that need to be modified or created in order to implement misc-example kunit test. Except for .kunitconfig. Which might make a newcommer confused about where the file exists. Since there are multiple .kunitconfig files. Fix this by using the full path to .kunitconfig. Signed-off-by: Khalid Masum Reviewed-by: David Gow Signed-off-by: Shuah Khan --- Documentation/dev-tools/kunit/start.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/dev-tools/kunit/start.rst b/Documentation/dev-tools/kunit/start.rst index 75fd05286396..f4f504f1fb15 100644 --- a/Documentation/dev-tools/kunit/start.rst +++ b/Documentation/dev-tools/kunit/start.rst @@ -265,7 +265,7 @@ Now we are ready to write the test cases. obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o -4. Add the following lines to ``.kunitconfig``: +4. Add the following lines to ``.kunit/.kunitconfig``: .. code-block:: none