d]sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget /translations/zh_CN/rust/testingmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/zh_TW/rust/testingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/it_IT/rust/testingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/ja_JP/rust/testingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/ko_KR/rust/testingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget /translations/sp_SP/rust/testingmodnameN 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:spacepreserveuh1hhhhhh:/var/lib/git/docbuild/linux/Documentation/rust/testing.rsthKubhsection)}(hhh](htitle)}(hTestingh]hTesting}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hRThis document contains useful information how to test the Rust code in the kernel.h]hRThis document contains useful information how to test the Rust code in the kernel.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hThere are three sorts of tests:h]hThere are three sorts of tests:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh bullet_list)}(hhh](h list_item)}(hThe KUnit tests.h]h)}(hhh]hThe KUnit tests.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(hThe ``#[test]`` tests.h]h)}(hjh](hThe }(hj hhhNhNubhliteral)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh tests.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(hThe Kselftests. h]h)}(hThe Kselftests.h]hThe Kselftests.}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hj0ubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhK hhhhubh)}(hhh](h)}(hThe KUnit testsh]hThe KUnit tests}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjPhhhhhKubh)}(hqThese are the tests that come from the examples in the Rust documentation. They get transformed into KUnit tests.h]hqThese are the tests that come from the examples in the Rust documentation. They get transformed into KUnit tests.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubh)}(hhh](h)}(hUsageh]hUsage}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjohhhhhKubh)}(heThese tests can be run via KUnit. For example via ``kunit_tool`` (``kunit.py``) on the command line::h](h2These tests can be run via KUnit. For example via }(hjhhhNhNubj)}(h``kunit_tool``h]h kunit_tool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh (}(hjhhhNhNubj)}(h ``kunit.py``h]hkunit.py}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) on the command line:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjohhubh literal_block)}(hb./tools/testing/kunit/kunit.py run --make_options LLVM=1 --arch x86_64 --kconfig_add CONFIG_RUST=yh]hb./tools/testing/kunit/kunit.py run --make_options LLVM=1 --arch x86_64 --kconfig_add CONFIG_RUST=y}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjohhubh)}(hXAlternatively, KUnit can run them as kernel built-in at boot. Refer to Documentation/dev-tools/kunit/index.rst for the general KUnit documentation and Documentation/dev-tools/kunit/architecture.rst for the details of kernel built-in vs. command line testing.h]hXAlternatively, KUnit can run them as kernel built-in at boot. Refer to Documentation/dev-tools/kunit/index.rst for the general KUnit documentation and Documentation/dev-tools/kunit/architecture.rst for the details of kernel built-in vs. command line testing.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjohhubh)}(h Kernel Testing and Coverage -> KUnit - Enable support for unit tests CONFIG_RUST_KERNEL_DOCTESTS Kernel hacking -> Rust hacking -> Doctests for the `kernel` crateh]hCONFIG_KUNIT Kernel hacking -> Kernel Testing and Coverage -> KUnit - Enable support for unit tests CONFIG_RUST_KERNEL_DOCTESTS Kernel hacking -> Rust hacking -> Doctests for the `kernel` crate}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhK$hjohhubh)}(hin the kernel config system.h]hin the kernel config system.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hjohhubeh}(h]usageah ]h"]usageah$]h&]uh1hhjPhhhhhKubh)}(hhh](h)}(h#KUnit tests are documentation testsh]h#KUnit tests are documentation tests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK,ubh)}(hiThese documentation tests are typically examples of usage of any item (e.g. function, struct, module...).h]hiThese documentation tests are typically examples of usage of any item (e.g. function, struct, module...).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubh)}(haThey are very convenient because they are just written alongside the documentation. For instance:h]haThey are very convenient because they are just written alongside the documentation. For instance:}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK1hjhhubj)}(h}/// Sums two numbers. /// /// ``` /// assert_eq!(mymod::f(10, 20), 30); /// ``` pub fn f(a: i32, b: i32) -> i32 { a + b }h]h}/// Sums two numbers. /// /// ``` /// assert_eq!(mymod::f(10, 20), 30); /// ``` pub fn f(a: i32, b: i32) -> i32 { a + b }}hj/sbah}(h]h ]h"]h$]h&]hhforcelanguagerusthighlight_args}uh1jhhhK4hjhhubh)}(hX"In userspace, the tests are collected and run via ``rustdoc``. Using the tool as-is would be useful already, since it allows verifying that examples compile (thus enforcing they are kept in sync with the code they document) and as well as running those that do not depend on in-kernel APIs.h](h2In userspace, the tests are collected and run via }(hjBhhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjBubh. Using the tool as-is would be useful already, since it allows verifying that examples compile (thus enforcing they are kept in sync with the code they document) and as well as running those that do not depend on in-kernel APIs.}(hjBhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK?hjhhubh)}(hFor the kernel, however, these tests get transformed into KUnit test suites. This means that doctests get compiled as Rust kernel objects, allowing them to run against a built kernel.h]hFor the kernel, however, these tests get transformed into KUnit test suites. This means that doctests get compiled as Rust kernel objects, allowing them to run against a built kernel.}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjhhubh)}(hA benefit of this KUnit integration is that Rust doctests get to reuse existing testing facilities. For instance, the kernel log would look like::h]hA benefit of this KUnit integration is that Rust doctests get to reuse existing testing facilities. For instance, the kernel log would look like:}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjhhubj)}(hXKTAP version 1 1..1 KTAP version 1 # Subtest: rust_doctests_kernel 1..59 # rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13 ok 1 rust_doctest_kernel_build_assert_rs_0 # rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56 ok 2 rust_doctest_kernel_build_assert_rs_1 # rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122 ok 3 rust_doctest_kernel_init_rs_0 ... # rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150 ok 59 rust_doctest_kernel_types_rs_2 # rust_doctests_kernel: pass:59 fail:0 skip:0 total:59 # Totals: pass:59 fail:0 skip:0 total:59 ok 1 rust_doctests_kernelh]hXKTAP version 1 1..1 KTAP version 1 # Subtest: rust_doctests_kernel 1..59 # rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13 ok 1 rust_doctest_kernel_build_assert_rs_0 # rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56 ok 2 rust_doctest_kernel_build_assert_rs_1 # rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122 ok 3 rust_doctest_kernel_init_rs_0 ... # rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150 ok 59 rust_doctest_kernel_types_rs_2 # rust_doctests_kernel: pass:59 fail:0 skip:0 total:59 # Totals: pass:59 fail:0 skip:0 total:59 ok 1 rust_doctests_kernel}hj~sbah}(h]h ]h"]h$]h&]hhuh1jhhhKKhjhhubh)}(hTests using the `? `_ operator are also supported as usual, e.g.:h](hTests using the }(hjhhhNhNubh reference)}(hd`? `_h]h?}(hjhhhNhNubah}(h]h ]h"]h$]h&]name?refuri]https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operatoruh1jhjubhtarget)}(h` h]h}(h]id1ah ]h"]?ah$]h&]refurijuh1j referencedKhjubh, operator are also supported as usual, e.g.:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK]hjhhubj)}(h/// ``` /// # use kernel::{spawn_work_item, workqueue}; /// spawn_work_item!(workqueue::system(), || pr_info!("x\n"))?; /// # Ok::<(), Error>(()) /// ```h]h/// ``` /// # use kernel::{spawn_work_item, workqueue}; /// spawn_work_item!(workqueue::system(), || pr_info!("x\n"))?; /// # Ok::<(), Error>(()) /// ```}hjsbah}(h]h ]h"]h$]h&]hhj=j>rustj@}uh1jhhhK`hjhhubh)}(h|The tests are also compiled with Clippy under ``CLIPPY=1``, just like normal code, thus also benefitting from extra linting.h](h.The tests are also compiled with Clippy under }(hjhhhNhNubj)}(h ``CLIPPY=1``h]hCLIPPY=1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhB, just like normal code, thus also benefitting from extra linting.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhjhhubh)}(hIn order for developers to easily see which line of doctest code caused a failure, a KTAP diagnostic line is printed to the log. This contains the location (file and line) of the original test (i.e. instead of the location in the generated Rust file)::h]hIn order for developers to easily see which line of doctest code caused a failure, a KTAP diagnostic line is printed to the log. This contains the location (file and line) of the original test (i.e. instead of the location in the generated Rust file):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhjhhubj)}(hC# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150h]hC# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKphjhhubh)}(hXRust tests appear to assert using the usual ``assert!`` and ``assert_eq!`` macros from the Rust standard library (``core``). We provide a custom version that forwards the call to KUnit instead. Importantly, these macros do not require passing context, unlike those for KUnit testing (i.e. ``struct kunit *``). This makes them easier to use, and readers of the documentation do not need to care about which testing framework is used. In addition, it may allow us to test third-party code more easily in the future.h](h,Rust tests appear to assert using the usual }(hjhhhNhNubj)}(h ``assert!``h]hassert!}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h``assert_eq!``h]h assert_eq!}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh( macros from the Rust standard library (}(hjhhhNhNubj)}(h``core``h]hcore}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh). We provide a custom version that forwards the call to KUnit instead. Importantly, these macros do not require passing context, unlike those for KUnit testing (i.e. }(hjhhhNhNubj)}(h``struct kunit *``h]hstruct kunit *}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh). This makes them easier to use, and readers of the documentation do not need to care about which testing framework is used. In addition, it may allow us to test third-party code more easily in the future.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKrhjhhubh)}(hA current limitation is that KUnit does not support assertions in other tasks. Thus, we presently simply print an error to the kernel log if an assertion actually failed. Additionally, doctests are not run for nonpublic functions.h]hA current limitation is that KUnit does not support assertions in other tasks. Thus, we presently simply print an error to the kernel log if an assertion actually failed. Additionally, doctests are not run for nonpublic functions.}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhjhhubh)}(hSince these tests are examples, i.e. they are part of the documentation, they should generally be written like "real code". Thus, for example, instead of using ``unwrap()`` or ``expect()``, use the ``?`` operator. For more background, please see:h](hSince these tests are examples, i.e. they are part of the documentation, they should generally be written like “real code”. Thus, for example, instead of using }(hjrhhhNhNubj)}(h ``unwrap()``h]hunwrap()}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubh or }(hjrhhhNhNubj)}(h ``expect()``h]hexpect()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubh , use the }(hjrhhhNhNubj)}(h``?``h]h?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubh+ operator. For more background, please see:}(hjrhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK~hjhhubh block_quote)}(hUhttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust h]h)}(hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rusth]j)}(hjh]hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubeh}(h]#kunit-tests-are-documentation-testsah ]h"]#kunit tests are documentation testsah$]h&]uh1hhjPhhhhhK,ubeh}(h]the-kunit-testsah ]h"]the kunit testsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hThe ``#[test]`` testsh](hThe }(hjhhhNhNubj)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh tests}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hdAdditionally, there are the ``#[test]`` tests. These can be run using the ``rusttest`` Make target::h](hAdditionally, there are the }(hj hhhNhNubj)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh# tests. These can be run using the }(hj hhhNhNubj)}(h ``rusttest``h]hrusttest}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh Make target:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hmake LLVM=1 rusttesth]hmake LLVM=1 rusttest}hj?sbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hThis requires the kernel ``.config``. It runs the ``#[test]`` tests on the host (currently) and thus is fairly limited in what these tests can test.h](hThis requires the kernel }(hjMhhhNhNubj)}(h ``.config``h]h.config}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjMubh. It runs the }(hjMhhhNhNubj)}(h ``#[test]``h]h#[test]}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jhjMubhW tests on the host (currently) and thus is fairly limited in what these tests can test.}(hjMhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]the-test-testsah ]h"]the #[test] testsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hThe Kselftestsh]hThe Kselftests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hMKselftests are also available in the ``tools/testing/selftests/rust`` folder.h](h%Kselftests are also available in the }(hjhhhNhNubj)}(h ``tools/testing/selftests/rust``h]htools/testing/selftests/rust}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh folder.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hThe kernel config options required for the tests are listed in the ``tools/testing/selftests/rust/config`` file and can be included with the aid of the ``merge_config.sh`` script::h](hCThe kernel config options required for the tests are listed in the }(hjhhhNhNubj)}(h'``tools/testing/selftests/rust/config``h]h#tools/testing/selftests/rust/config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. file and can be included with the aid of the }(hjhhhNhNubj)}(h``merge_config.sh``h]hmerge_config.sh}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh script:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hM./scripts/kconfig/merge_config.sh .config tools/testing/selftests/rust/configh]hM./scripts/kconfig/merge_config.sh .config tools/testing/selftests/rust/config}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hThe kselftests are built within the kernel source tree and are intended to be executed on a system that is running the same kernel.h]hThe kselftests are built within the kernel source tree and are intended to be executed on a system that is running the same kernel.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hOnce a kernel matching the source tree has been installed and booted, the tests can be compiled and executed using the following command::h]hOnce a kernel matching the source tree has been installed and booted, the tests can be compiled and executed using the following command:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hmake TARGETS="rust" kselftesth]hmake TARGETS="rust" kselftest}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hWRefer to Documentation/dev-tools/kselftest.rst for the general Kselftest documentation.h]hWRefer to Documentation/dev-tools/kselftest.rst for the general Kselftest documentation.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]the-kselftestsah ]h"]the kselftestsah$]h&]uh1hhhhhhhhKubeh}(h]testingah ]h"]testingah$]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_handlerjcerror_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}refids}nameids}(j=j:jjjjjjjjjjj5j2u nametypes}(j=jjjjjj5uh}(j:hjjPjjojjjjjjj2ju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jqKsRparse_messages]transform_messages] transformerN include_log] decorationNhhub.