sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget0/translations/zh_CN/dev-tools/kunit/architecturemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/zh_TW/dev-tools/kunit/architecturemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/it_IT/dev-tools/kunit/architecturemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/ja_JP/dev-tools/kunit/architecturemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/ko_KR/dev-tools/kunit/architecturemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget0/translations/sp_SP/dev-tools/kunit/architecturemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhJ/var/lib/git/docbuild/linux/Documentation/dev-tools/kunit/architecture.rsthKubhsection)}(hhh](htitle)}(hKUnit Architectureh]hKUnit Architecture}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(h1The KUnit architecture is divided into two parts:h]h1The KUnit architecture is divided into two parts:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh bullet_list)}(hhh](h list_item)}(h`In-Kernel Testing Framework`_h]h)}(hhh]h reference)}(hhh]hIn-Kernel Testing Framework}(hhhhhNhNubah}(h]h ]h"]h$]h&]nameIn-Kernel Testing Frameworkrefidin-kernel-testing-frameworkuh1hhhresolvedKubah}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(h*`kunit_tool (Command-line Test Harness)`_ h]h)}(h)`kunit_tool (Command-line Test Harness)`_h]h)}(hj h]h&kunit_tool (Command-line Test Harness)}(hjhhhNhNubah}(h]h ]h"]h$]h&]name&kunit_tool (Command-line Test Harness)h$kunit-tool-command-line-test-harnessuh1hhj hKubah}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhK hhhhubh)}(hhh](h)}(hIn-Kernel Testing Frameworkh]hIn-Kernel Testing Framework}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj3hhhhhK ubh)}(hThe kernel testing library supports KUnit tests written in C using KUnit. These KUnit tests are kernel code. KUnit performs the following tasks:h]hThe kernel testing library supports KUnit tests written in C using KUnit. These KUnit tests are kernel code. KUnit performs the following tasks:}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj3hhubh)}(hhh](h)}(hOrganizes testsh]h)}(hjWh]hOrganizes tests}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjUubah}(h]h ]h"]h$]h&]uh1hhjRhhhhhNubh)}(hReports test resultsh]h)}(hjnh]hReports test results}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjlubah}(h]h ]h"]h$]h&]uh1hhjRhhhhhNubh)}(hProvides test utilities h]h)}(hProvides test utilitiesh]hProvides test utilities}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjRhhhhhNubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhKhj3hhubh)}(hhh](h)}(h Test Casesh]h Test Cases}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hThe test case is the fundamental unit in KUnit. KUnit test cases are organised into suites. A KUnit test case is a function with type signature ``void (*)(struct kunit *test)``. These test case functions are wrapped in a struct called struct kunit_case.h](hThe test case is the fundamental unit in KUnit. KUnit test cases are organised into suites. A KUnit test case is a function with type signature }(hjhhhNhNubhliteral)}(h ``void (*)(struct kunit *test)``h]hvoid (*)(struct kunit *test)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhM. These test case functions are wrapped in a struct called struct kunit_case.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hBnote: ``generate_params`` is optional for non-parameterized tests.h]hBnote: ``generate_params`` is optional for non-parameterized tests.}hjsbah}(h]h ]h"]h$]h&]hhuh1hhjhhhhhK!ubh)}(hEach KUnit test case receives a ``struct kunit`` context object that tracks a running test. The KUnit assertion macros and other KUnit utilities use the ``struct kunit`` context object. As an exception, there are two fields:h](h Each KUnit test case receives a }(hjhhhNhNubj)}(h``struct kunit``h]h struct kunit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhi context object that tracks a running test. The KUnit assertion macros and other KUnit utilities use the }(hjhhhNhNubj)}(h``struct kunit``h]h struct kunit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh7 context object. As an exception, there are two fields:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK"hjhhubh)}(hhh](h)}(hN``->priv``: The setup functions can use it to store arbitrary test user data. h]h)}(hM``->priv``: The setup functions can use it to store arbitrary test user data.h](j)}(h ``->priv``h]h->priv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhC: The setup functions can use it to store arbitrary test user data.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK&hjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(hf``->param_value``: It contains the parameter value which can be retrieved in the parameterized tests. h]h)}(he``->param_value``: It contains the parameter value which can be retrieved in the parameterized tests.h](j)}(h``->param_value``h]h ->param_value}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjAubhT: It contains the parameter value which can be retrieved in the parameterized tests.}(hjAhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK)hj=ubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhK&hjhhubeh}(h] test-casesah ]h"] test casesah$]h&]uh1hhj3hhhhhKubh)}(hhh](h)}(h Test Suitesh]h Test Suites}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhjqhhhhhK-ubh)}(hA KUnit suite includes a collection of test cases. The KUnit suites are represented by the ``struct kunit_suite``. For example:h](h[A KUnit suite includes a collection of test cases. The KUnit suites are represented by the }(hjhhhNhNubj)}(h``struct kunit_suite``h]hstruct kunit_suite}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. For example:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK/hjqhhubh literal_block)}(hXstatic struct kunit_case example_test_cases[] = { KUNIT_CASE(example_test_foo), KUNIT_CASE(example_test_bar), KUNIT_CASE(example_test_baz), {} }; static struct kunit_suite example_test_suite = { .name = "example", .init = example_test_init, .exit = example_test_exit, .test_cases = example_test_cases, }; kunit_test_suite(example_test_suite);h]hXstatic struct kunit_case example_test_cases[] = { KUNIT_CASE(example_test_foo), KUNIT_CASE(example_test_bar), KUNIT_CASE(example_test_baz), {} }; static struct kunit_suite example_test_suite = { .name = "example", .init = example_test_init, .exit = example_test_exit, .test_cases = example_test_cases, }; kunit_test_suite(example_test_suite);}hjsbah}(h]h ]h"]h$]h&]hhforcelanguagechighlight_args}uh1jhhhK2hjqhhubh)}(hXuIn the above example, the test suite ``example_test_suite``, runs the test cases ``example_test_foo``, ``example_test_bar``, and ``example_test_baz``. Before running the test, the ``example_test_init`` is called and after running the test, ``example_test_exit`` is called. The ``kunit_test_suite(example_test_suite)`` registers the test suite with the KUnit test framework.h](h%In the above example, the test suite }(hjhhhNhNubj)}(h``example_test_suite``h]hexample_test_suite}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, runs the test cases }(hjhhhNhNubj)}(h``example_test_foo``h]hexample_test_foo}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``example_test_bar``h]hexample_test_bar}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, and }(hjhhhNhNubj)}(h``example_test_baz``h]hexample_test_baz}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Before running the test, the }(hjhhhNhNubj)}(h``example_test_init``h]hexample_test_init}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh' is called and after running the test, }(hjhhhNhNubj)}(h``example_test_exit``h]hexample_test_exit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is called. The }(hjhhhNhNubj)}(h(``kunit_test_suite(example_test_suite)``h]h$kunit_test_suite(example_test_suite)}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh8 registers the test suite with the KUnit test framework.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKChjqhhubeh}(h] test-suitesah ]h"] test suitesah$]h&]uh1hhj3hhhhhK-ubh)}(hhh](h)}(hExecutorh]hExecutor}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjKhhhhhKKubh)}(hXfThe KUnit executor can list and run built-in KUnit tests on boot. The Test suites are stored in a linker section called ``.kunit_test_suites``. For the code, see ``KUNIT_TABLE()`` macro definition in `include/asm-generic/vmlinux.lds.h `_. The linker section consists of an array of pointers to ``struct kunit_suite``, and is populated by the ``kunit_test_suites()`` macro. The KUnit executor iterates over the linker section array in order to run all the tests that are compiled into the kernel.h](hxThe KUnit executor can list and run built-in KUnit tests on boot. The Test suites are stored in a linker section called }(hj\hhhNhNubj)}(h``.kunit_test_suites``h]h.kunit_test_suites}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh. For the code, see }(hj\hhhNhNubj)}(h``KUNIT_TABLE()``h]h KUNIT_TABLE()}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh macro definition in }(hj\hhhNhNubh)}(h`include/asm-generic/vmlinux.lds.h `_h]h!include/asm-generic/vmlinux.lds.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]name!include/asm-generic/vmlinux.lds.hrefuriuhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/vmlinux.lds.h?h=v6.0#n950uh1hhj\ubhtarget)}(hx h]h}(h]!include-asm-generic-vmlinux-lds-hah ]h"]!include/asm-generic/vmlinux.lds.hah$]h&]refurijuh1j referencedKhj\ubh9. The linker section consists of an array of pointers to }(hj\hhhNhNubj)}(h``struct kunit_suite``h]hstruct kunit_suite}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh, and is populated by the }(hj\hhhNhNubj)}(h``kunit_test_suites()``h]hkunit_test_suites()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh macro. The KUnit executor iterates over the linker section array in order to run all the tests that are compiled into the kernel.}(hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKMhjKhhubkfigure kernel_figure)}(hhh]hfigure)}(hhh](himage)}(hw.. kernel-figure:: kunit_suitememorydiagram.svg :alt: KUnit Suite Memory KUnit Suite Memory Diagram h]h}(h]h ]h"]h$]h&]altKUnit Suite Memoryuri,dev-tools/kunit/kunit_suitememorydiagram.svg candidates}*jsuh1jhjhhhKubhcaption)}(hKUnit Suite Memory Diagramh]hKUnit Suite Memory Diagram}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKZhjubeh}(h]id1ah ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjKhhhhhNubh)}(hXOn the kernel boot, the KUnit executor uses the start and end addresses of this section to iterate over and run all tests. For the implementation of the executor, see `lib/kunit/executor.c `_. When built as a module, the ``kunit_test_suites()`` macro defines a ``module_init()`` function, which runs all the tests in the compilation unit instead of utilizing the executor.h](hOn the kernel boot, the KUnit executor uses the start and end addresses of this section to iterate over and run all tests. For the implementation of the executor, see }(hjhhhNhNubh)}(hv`lib/kunit/executor.c `_h]hlib/kunit/executor.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]namelib/kunit/executor.cj\https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kunit/executor.cuh1hhjubj)}(h_ h]h}(h]lib-kunit-executor-cah ]h"]lib/kunit/executor.cah$]h&]refurij+uh1jjKhjubh. When built as a module, the }(hjhhhNhNubj)}(h``kunit_test_suites()``h]hkunit_test_suites()}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh macro defines a }(hjhhhNhNubj)}(h``module_init()``h]h module_init()}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh^ function, which runs all the tests in the compilation unit instead of utilizing the executor.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK\hjKhhubh)}(hX?In KUnit tests, some error classes do not affect other tests or parts of the kernel, each KUnit case executes in a separate thread context. See the ``kunit_try_catch_run()`` function in `lib/kunit/try-catch.c `_.h](hIn KUnit tests, some error classes do not affect other tests or parts of the kernel, each KUnit case executes in a separate thread context. See the }(hjghhhNhNubj)}(h``kunit_try_catch_run()``h]hkunit_try_catch_run()}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jhjgubh function in }(hjghhhNhNubh)}(h`lib/kunit/try-catch.c `_h]hlib/kunit/try-catch.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]namelib/kunit/try-catch.cjihttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kunit/try-catch.c?h=v5.15#n58uh1hhjgubj)}(hl h]h}(h]lib-kunit-try-catch-cah ]h"]lib/kunit/try-catch.cah$]h&]refurijuh1jjKhjgubh.}(hjghhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKdhjKhhubeh}(h]executorah ]h"]executorah$]h&]uh1hhj3hhhhhKKubh)}(hhh](h)}(hAssertion Macrosh]hAssertion Macros}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKjubh)}(hKUnit tests verify state using expectations/assertions. All expectations/assertions are formatted as: ``KUNIT_{EXPECT|ASSERT}_[_MSG](kunit, property[, message])``h](hfKUnit tests verify state using expectations/assertions. All expectations/assertions are formatted as: }(hjhhhNhNubj)}(h@``KUNIT_{EXPECT|ASSERT}_[_MSG](kunit, property[, message])``h]h[_MSG](kunit, property[, message])}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubh)}(hhh](h)}(hX0``{EXPECT|ASSERT}`` determines whether the check is an assertion or an expectation. In the event of a failure, the testing flow differs as follows: - For expectations, the test is marked as failed and the failure is logged. - Failing assertions, on the other hand, result in the test case being terminated immediately. - Assertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``. - ``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``. - ``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context. h](h)}(h``{EXPECT|ASSERT}`` determines whether the check is an assertion or an expectation. In the event of a failure, the testing flow differs as follows:h](j)}(h``{EXPECT|ASSERT}``h]h{EXPECT|ASSERT}}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh determines whether the check is an assertion or an expectation. In the event of a failure, the testing flow differs as follows:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKphjubh block_quote)}(hX_- For expectations, the test is marked as failed and the failure is logged. - Failing assertions, on the other hand, result in the test case being terminated immediately. - Assertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``. - ``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``. - ``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context. h]h)}(hhh](h)}(hJFor expectations, the test is marked as failed and the failure is logged. h]h)}(hIFor expectations, the test is marked as failed and the failure is logged.h]hIFor expectations, the test is marked as failed and the failure is logged.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKthj ubah}(h]h ]h"]h$]h&]uh1hhjubh)}(hXFailing assertions, on the other hand, result in the test case being terminated immediately. - Assertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``. - ``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``. - ``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context. h](h)}(h\Failing assertions, on the other hand, result in the test case being terminated immediately.h]h\Failing assertions, on the other hand, result in the test case being terminated immediately.}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKvhj"ubj)}(hXx- Assertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``. - ``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``. - ``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context. h]h)}(hhh](h)}(hQAssertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``. h]h)}(hPAssertions call the function: ``void __noreturn __kunit_abort(struct kunit *)``.h](hAssertions call the function: }(hj?hhhNhNubj)}(h1``void __noreturn __kunit_abort(struct kunit *)``h]h-void __noreturn __kunit_abort(struct kunit *)}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh.}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKyhj;ubah}(h]h ]h"]h$]h&]uh1hhj8ubh)}(ht``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``. h]h)}(hs``__kunit_abort`` calls the function: ``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``.h](j)}(h``__kunit_abort``h]h __kunit_abort}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjiubh calls the function: }(hjihhhNhNubj)}(hL``void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)``h]hHvoid __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjiubh.}(hjihhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK|hjeubah}(h]h ]h"]h$]h&]uh1hhj8ubh)}(h``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context. h]h)}(h``kunit_try_catch_throw`` calls the function: ``void kthread_complete_and_exit(struct completion *, long) __noreturn;`` and terminates the special thread context.h](j)}(h``kunit_try_catch_throw``h]hkunit_try_catch_throw}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh calls the function: }(hjhhhNhNubj)}(hI``void kthread_complete_and_exit(struct completion *, long) __noreturn;``h]hEvoid kthread_complete_and_exit(struct completion *, long) __noreturn;}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ and terminates the special thread context.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj8ubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhKyhj4ubah}(h]h ]h"]h$]h&]uh1jhhhKyhj"ubeh}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhKthjubah}(h]h ]h"]h$]h&]uh1jhhhKthjubeh}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h```` denotes a check with options: ``TRUE`` (supplied property has the boolean value "true"), ``EQ`` (two supplied properties are equal), ``NOT_ERR_OR_NULL`` (supplied pointer is not null and does not contain an "err" value). h]h)}(h```` denotes a check with options: ``TRUE`` (supplied property has the boolean value "true"), ``EQ`` (two supplied properties are equal), ``NOT_ERR_OR_NULL`` (supplied pointer is not null and does not contain an "err" value).h](j)}(h````h]h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh denotes a check with options: }(hjhhhNhNubj)}(h``TRUE``h]hTRUE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh7 (supplied property has the boolean value “true”), }(hjhhhNhNubj)}(h``EQ``h]hEQ}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh& (two supplied properties are equal), }(hjhhhNhNubj)}(h``NOT_ERR_OR_NULL``h]hNOT_ERR_OR_NULL}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhH (supplied pointer is not null and does not contain an “err” value).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h/``[_MSG]`` prints a custom message on failure. h]h)}(h.``[_MSG]`` prints a custom message on failure.h](j)}(h ``[_MSG]``h]h[_MSG]}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjYubh$ prints a custom message on failure.}(hjYhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjUubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhKphjhhubeh}(h]assertion-macrosah ]h"]assertion macrosah$]h&]uh1hhj3hhhhhKjubh)}(hhh](h)}(hTest Result Reportingh]hTest Result Reporting}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hKUnit prints the test results in KTAP format. KTAP is based on TAP14, see Documentation/dev-tools/ktap.rst. KTAP works with KUnit and Kselftest. The KUnit executor prints KTAP results to dmesg, and debugfs (if configured).h]hKUnit prints the test results in KTAP format. KTAP is based on TAP14, see Documentation/dev-tools/ktap.rst. KTAP works with KUnit and Kselftest. The KUnit executor prints KTAP results to dmesg, and debugfs (if configured).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]test-result-reportingah ]h"]test result reportingah$]h&]uh1hhj3hhhhhKubh)}(hhh](h)}(hParameterized Testsh]hParameterized Tests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXEach KUnit parameterized test is associated with a collection of parameters. The test is invoked multiple times, once for each parameter value and the parameter is stored in the ``param_value`` field. The test case includes a KUNIT_CASE_PARAM() macro that accepts a generator function. The generator function is passed the previous parameter and returns the next parameter. It also includes a macro for generating array-based common-case generators.h](hEach KUnit parameterized test is associated with a collection of parameters. The test is invoked multiple times, once for each parameter value and the parameter is stored in the }(hjhhhNhNubj)}(h``param_value``h]h param_value}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX field. The test case includes a KUNIT_CASE_PARAM() macro that accepts a generator function. The generator function is passed the previous parameter and returns the next parameter. It also includes a macro for generating array-based common-case generators.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]parameterized-testsah ]h"]parameterized testsah$]h&]uh1hhj3hhhhhKubeh}(h]hah ]h"]in-kernel testing frameworkah$]h&]uh1hhhhhhhhK jKubh)}(hhh](h)}(h&kunit_tool (Command-line Test Harness)h]h&kunit_tool (Command-line Test Harness)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hX``kunit_tool`` is a Python script, found in ``tools/testing/kunit/kunit.py``. It is used to configure, build, execute, parse test results and run all of the previous commands in correct order (i.e., configure, build, execute and parse). You have two options for running KUnit tests: either build the kernel with KUnit enabled and manually parse the results (see Documentation/dev-tools/kunit/run_manual.rst) or use ``kunit_tool`` (see Documentation/dev-tools/kunit/run_wrapper.rst).h](j)}(h``kunit_tool``h]h kunit_tool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is a Python script, found in }(hjhhhNhNubj)}(h ``tools/testing/kunit/kunit.py``h]htools/testing/kunit/kunit.py}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXS. It is used to configure, build, execute, parse test results and run all of the previous commands in correct order (i.e., configure, build, execute and parse). You have two options for running KUnit tests: either build the kernel with KUnit enabled and manually parse the results (see Documentation/dev-tools/kunit/run_manual.rst) or use }(hjhhhNhNubj)}(h``kunit_tool``h]h kunit_tool}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 (see Documentation/dev-tools/kunit/run_wrapper.rst).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hhh](h)}(hX``configure`` command generates the kernel ``.config`` from a ``.kunitconfig`` file (and any architecture-specific options). The Python scripts available in ``qemu_configs`` folder (for example, ``tools/testing/kunit/qemu configs/powerpc.py``) contains additional configuration options for specific architectures. It parses both the existing ``.config`` and the ``.kunitconfig`` files to ensure that ``.config`` is a superset of ``.kunitconfig``. If not, it will combine the two and run ``make olddefconfig`` to regenerate the ``.config`` file. It then checks to see if ``.config`` has become a superset. This verifies that all the Kconfig dependencies are correctly specified in the file ``.kunitconfig``. The ``kunit_config.py`` script contains the code for parsing Kconfigs. The code which runs ``make olddefconfig`` is part of the ``kunit_kernel.py`` script. You can invoke this command through: ``./tools/testing/kunit/kunit.py config`` and generate a ``.config`` file.h]h)}(hX``configure`` command generates the kernel ``.config`` from a ``.kunitconfig`` file (and any architecture-specific options). The Python scripts available in ``qemu_configs`` folder (for example, ``tools/testing/kunit/qemu configs/powerpc.py``) contains additional configuration options for specific architectures. It parses both the existing ``.config`` and the ``.kunitconfig`` files to ensure that ``.config`` is a superset of ``.kunitconfig``. If not, it will combine the two and run ``make olddefconfig`` to regenerate the ``.config`` file. It then checks to see if ``.config`` has become a superset. This verifies that all the Kconfig dependencies are correctly specified in the file ``.kunitconfig``. The ``kunit_config.py`` script contains the code for parsing Kconfigs. The code which runs ``make olddefconfig`` is part of the ``kunit_kernel.py`` script. You can invoke this command through: ``./tools/testing/kunit/kunit.py config`` and generate a ``.config`` file.h](j)}(h ``configure``h]h configure}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh command generates the kernel }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh from a }(hjHhhhNhNubj)}(h``.kunitconfig``h]h .kunitconfig}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhO file (and any architecture-specific options). The Python scripts available in }(hjHhhhNhNubj)}(h``qemu_configs``h]h qemu_configs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh folder (for example, }(hjHhhhNhNubj)}(h/``tools/testing/kunit/qemu configs/powerpc.py``h]h+tools/testing/kunit/qemu configs/powerpc.py}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhd) contains additional configuration options for specific architectures. It parses both the existing }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh and the }(hjHhhhNhNubj)}(h``.kunitconfig``h]h .kunitconfig}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh files to ensure that }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh is a superset of }(hjHhhhNhNubj)}(h``.kunitconfig``h]h .kunitconfig}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh*. If not, it will combine the two and run }(hjHhhhNhNubj)}(h``make olddefconfig``h]hmake olddefconfig}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh to regenerate the }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh file. It then checks to see if }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhl has become a superset. This verifies that all the Kconfig dependencies are correctly specified in the file }(hjHhhhNhNubj)}(h``.kunitconfig``h]h .kunitconfig}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh. The }(hjHhhhNhNubj)}(h``kunit_config.py``h]hkunit_config.py}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhD script contains the code for parsing Kconfigs. The code which runs }(hjHhhhNhNubj)}(h``make olddefconfig``h]hmake olddefconfig}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh is part of the }(hjHhhhNhNubj)}(h``kunit_kernel.py``h]hkunit_kernel.py}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh. script. You can invoke this command through: }(hjHhhhNhNubj)}(h)``./tools/testing/kunit/kunit.py config``h]h%./tools/testing/kunit/kunit.py config}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh and generate a }(hjHhhhNhNubj)}(h ``.config``h]h.config}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh file.}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjDubah}(h]h ]h"]h$]h&]uh1hhjAhhhhhNubh)}(hX#``build`` runs ``make`` on the kernel tree with required options (depends on the architecture and some options, for example: build_dir) and reports any errors. To build a KUnit kernel from the current ``.config``, you can use the ``build`` argument: ``./tools/testing/kunit/kunit.py build``.h]h)}(hX#``build`` runs ``make`` on the kernel tree with required options (depends on the architecture and some options, for example: build_dir) and reports any errors. To build a KUnit kernel from the current ``.config``, you can use the ``build`` argument: ``./tools/testing/kunit/kunit.py build``.h](j)}(h ``build``h]hbuild}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh runs }(hjhhhNhNubj)}(h``make``h]hmake}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh on the kernel tree with required options (depends on the architecture and some options, for example: build_dir) and reports any errors. To build a KUnit kernel from the current }(hjhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, you can use the }(hjhhhNhNubj)}(h ``build``h]hbuild}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh argument: }(hjhhhNhNubj)}(h(``./tools/testing/kunit/kunit.py build``h]h$./tools/testing/kunit/kunit.py build}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjAhhhhhNubh)}(hX``exec`` command executes kernel results either directly (using User-mode Linux configuration), or through an emulator such as QEMU. It reads results from the log using standard output (stdout), and passes them to ``parse`` to be parsed. If you already have built a kernel with built-in KUnit tests, you can run the kernel and display the test results with the ``exec`` argument: ``./tools/testing/kunit/kunit.py exec``.h]h)}(hX``exec`` command executes kernel results either directly (using User-mode Linux configuration), or through an emulator such as QEMU. It reads results from the log using standard output (stdout), and passes them to ``parse`` to be parsed. If you already have built a kernel with built-in KUnit tests, you can run the kernel and display the test results with the ``exec`` argument: ``./tools/testing/kunit/kunit.py exec``.h](j)}(h``exec``h]hexec}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh command executes kernel results either directly (using User-mode Linux configuration), or through an emulator such as QEMU. It reads results from the log using standard output (stdout), and passes them to }(hj hhhNhNubj)}(h ``parse``h]hparse}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh to be parsed. If you already have built a kernel with built-in KUnit tests, you can run the kernel and display the test results with the }(hj hhhNhNubj)}(h``exec``h]hexec}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh argument: }(hj hhhNhNubj)}(h'``./tools/testing/kunit/kunit.py exec``h]h#./tools/testing/kunit/kunit.py exec}(hjH hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhjAhhhhhNubh)}(h``parse`` extracts the KTAP output from a kernel log, parses the test results, and prints a summary. For failed tests, any diagnostic output will be included.h]h)}(h``parse`` extracts the KTAP output from a kernel log, parses the test results, and prints a summary. For failed tests, any diagnostic output will be included.h](j)}(h ``parse``h]hparse}(hjn hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjj ubh extracts the KTAP output from a kernel log, parses the test results, and prints a summary. For failed tests, any diagnostic output will be included.}(hjj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjf ubah}(h]h ]h"]h$]h&]uh1hhjAhhhhhNubeh}(h]h ]h"]h$]h&]j1j2uh1hhhhKhjhhubeh}(h]jah ]h"]&kunit_tool (command-line test harness)ah$]h&]uh1hhhhhhhhKjKubeh}(h]kunit-architectureah ]h"]kunit architectureah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}(in-kernel testing framework]ha&kunit_tool (command-line test harness)]jaurefids}nameids}(j j jhjnjkjHjEjjjjj5j2jjjjjjjjj ju nametypes}(j jjnjHjjj5jjjjj uh}(j hhj3jkjjEjqjjKjjj2j,jjjjjjjjjjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j KsRparse_messages]transform_messages] transformerN include_log] decorationNhhub.