sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget /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_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhM/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/rust/testing.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(hDocumentation/rust/testing.rst h]h)}(hDocumentation/rust/testing.rsth]hDocumentation/rust/testing.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h$郭杰 Ben Guo h]h)}(h#郭杰 Ben Guo h](h郭杰 Ben Guo <}(hj hhhNhNubh reference)}(hbenx.guo@gmail.comh]hbenx.guo@gmail.com}(hj*hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:benx.guo@gmail.comuh1j(hj ubh>}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h测试h]h测试}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjXhhhhhK ubh)}(h6本文介绍了如何在内核中测试 Rust 代码。h]h6本文介绍了如何在内核中测试 Rust 代码。}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjXhhubh)}(h有三种测试类型:h]h有三种测试类型:}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjXhhubh bullet_list)}(hhh](h list_item)}(h KUnit 测试h]h)}(hjh]h KUnit 测试}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h``#[test]`` 测试h]h)}(hjh](hliteral)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 测试}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h Kselftests h]h)}(h Kselftestsh]h Kselftests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhjXhhubjW)}(hhh](j\)}(h KUnit 测试h]h KUnit 测试}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjhhhhhKubh)}(hR这些测试来自 Rust 文档中的示例。它们会被转换为 KUnit 测试。h]hR这些测试来自 Rust 文档中的示例。它们会被转换为 KUnit 测试。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjW)}(hhh](j\)}(h使用h]h使用}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hj hhhhhKubh)}(hl这些测试可以通过 KUnit 运行。例如,在命令行中使用 ``kunit_tool`` ( ``kunit.py`` )::h](hG这些测试可以通过 KUnit 运行。例如,在命令行中使用 }(hjhhhNhNubj)}(h``kunit_tool``h]h kunit_tool}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh ( }(hjhhhNhNubj)}(h ``kunit.py``h]hkunit.py}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh ):}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh 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}hjPsbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhj hhubh)}(hX或者,KUnit 也可以在内核启动时以内置方式运行。获取更多 KUnit 信息,请参阅 Documentation/dev-tools/kunit/index.rst。 关于内核内置与命令行测试的详细信息,请参阅 Documentation/dev-tools/kunit/architecture.rst。h]hX或者,KUnit 也可以在内核启动时以内置方式运行。获取更多 KUnit 信息,请参阅 Documentation/dev-tools/kunit/index.rst。 关于内核内置与命令行测试的详细信息,请参阅 Documentation/dev-tools/kunit/architecture.rst。}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hj hhubh)}(hQ要使用这些 KUnit 文档测试,需要在内核配置中启用以下选项::h]hP要使用这些 KUnit 文档测试,需要在内核配置中启用以下选项:}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hj hhubjO)}(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` 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}hjzsbah}(h]h ]h"]h$]h&]hhuh1jNhhhK'hj hhubeh}(h]id2ah ]h"]使用ah$]h&]uh1jVhjhhhhhKubjW)}(hhh](j\)}(hKUnit 测试即文档测试h]hKUnit 测试即文档测试}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjhhhhhK-ubh)}(h`文档测试( *doctests* )一般用于展示函数、结构体或模块等的使用方法。h](h文档测试( }(hjhhhNhNubhemphasis)}(h *doctests*h]hdoctests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhF )一般用于展示函数、结构体或模块等的使用方法。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK/hjhhubh)}(hB它们非常方便,因为它们就写在文档旁边。例如:h]hB它们非常方便,因为它们就写在文档旁边。例如:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK1hjhhubjO)}(h/// 求和两个数字。 /// /// ``` /// assert_eq!(mymod::f(10, 20), 30); /// ``` pub fn f(a: i32, b: i32) -> i32 { a + b }h]h/// 求和两个数字。 /// /// ``` /// assert_eq!(mymod::f(10, 20), 30); /// ``` pub fn f(a: i32, b: i32) -> i32 { a + b }}hjsbah}(h]h ]h"]h$]h&]hhforcelanguagerusthighlight_args}uh1jNhhhK3hjhhubh)}(hX在用户空间中,这些测试由 ``rustdoc`` 负责收集并运行。单独使用这个工具已经很有价值, 因为它可以验证示例能否成功编译(确保和代码保持同步), 同时还可以运行那些不依赖内核 API 的示例。h](h%在用户空间中,这些测试由 }(hjhhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 负责收集并运行。单独使用这个工具已经很有价值, 因为它可以验证示例能否成功编译(确保和代码保持同步), 同时还可以运行那些不依赖内核 API 的示例。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK>hjhhubh)}(h然而,在内核中,这些测试会转换成 KUnit 测试套件。 这意味着文档测试会被编译成 Rust 内核对象,从而可以在构建的内核环境中运行。h]h然而,在内核中,这些测试会转换成 KUnit 测试套件。 这意味着文档测试会被编译成 Rust 内核对象,从而可以在构建的内核环境中运行。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjhhubh)}(hx通过与 KUnit 集成,Rust 的文档测试可以复用内核现有的测试设施。 例如,内核日志会显示::h]hw通过与 KUnit 集成,Rust 的文档测试可以复用内核现有的测试设施。 例如,内核日志会显示:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjhhubjO)}(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&]hhuh1jNhhhKHhjhhubh)}(h文档测试中,也可以正常使用 `? `_ 运算符,例如:h](h(文档测试中,也可以正常使用 }(hj.hhhNhNubj))}(hd`? `_h]h?}(hj6hhhNhNubah}(h]h ]h"]h$]h&]name?refuri]https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operatoruh1j(hj.ubhtarget)}(h` h]h}(h]id4ah ]h"]?ah$]h&]refurijGuh1jH referencedKhj.ubh 运算符,例如:}(hj.hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKZhjhhubjO)}(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>(()) /// ```}hjbsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jNhhhK\hjhhubh)}(h这些测试和普通代码一样,也可以在 ``CLIPPY=1`` 条件下通过 Clippy 进行编译, 因此可以从额外的 lint 检查中获益。h](h1这些测试和普通代码一样,也可以在 }(hjrhhhNhNubj)}(h ``CLIPPY=1``h]hCLIPPY=1}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjrubhX 条件下通过 Clippy 进行编译, 因此可以从额外的 lint 检查中获益。}(hjrhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubh)}(h为了便于开发者定位文档测试出错的具体行号,日志会输出一条 KTAP 诊断信息。 其中标明了原始测试的文件和行号(不是 ``rustdoc`` 生成的临时 Rust 文件位置)::h](h为了便于开发者定位文档测试出错的具体行号,日志会输出一条 KTAP 诊断信息。 其中标明了原始测试的文件和行号(不是 }(hjhhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh& 生成的临时 Rust 文件位置):}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKghjhhubjO)}(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&]hhuh1jNhhhKjhjhhubh)}(hXRust 测试中常用的断言宏是来自 Rust 标准库( ``core`` )中的 ``assert!`` 和 ``assert_eq!`` 宏。 内核提供了一个定制版本,这些宏的调用会被转发到 KUnit。 和 KUnit 测试不同的是,这些宏不需要传递上下文参数( ``struct kunit *`` )。 这使得它们更易于使用,同时文档的读者无需关心底层用的是什么测试框架。 此外,这种方式未来也许可以让我们更容易测试第三方代码。h](h`_ 运算符。 更多背景信息,请参阅:h](hd作为文档中的测试示例,应当像 “实际代码” 一样编写。 例如:不要使用 }(hj$hhhNhNubj)}(h ``unwrap()``h]hunwrap()}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ubh 或 }(hj$hhhNhNubj)}(h ``expect()``h]hexpect()}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ubh ,请使用 }(hj$hhhNhNubj))}(hd`? `_h]h?}(hjPhhhNhNubah}(h]h ]h"]h$]h&]namejEjF]https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operatoruh1j(hj$ubjI)}(h` h]h}(h]id5ah ]h"]h$]?ah&]refurij_uh1jHjWKhj$ubh/ 运算符。 更多背景信息,请参阅:}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKvhjhhubh 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&]refurijuh1j(hj}ubah}(h]h ]h"]h$]h&]uh1hhhhKzhjyubah}(h]h ]h"]h$]h&]uh1jwhhhKzhjhhubeh}(h]id3ah ]h"]kunit 测试即文档测试ah$]h&]uh1jVhjhhhhhK-ubeh}(h]kunitah ]h"] kunit 测试ah$]h&]uh1jVhjXhhhhhKubjW)}(hhh](j\)}(h``#[test]`` 测试h](j)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 测试}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1j[hjhhhhhK}ubh)}(h此外,还有 ``#[test]`` 测试。与文档测试类似,这些测试与用户空间中的测试方式也非常相近,并且同样会映射到 KUnit。h](h此外,还有 }(hjhhhNhNubj)}(h ``#[test]``h]h#[test]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 测试。与文档测试类似,这些测试与用户空间中的测试方式也非常相近,并且同样会映射到 KUnit。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hb这些测试通过 ``kunit_tests`` 过程宏引入,该宏将测试套件的名称作为参数。h](h这些测试通过 }(hjhhhNhNubj)}(h``kunit_tests``h]h kunit_tests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@ 过程宏引入,该宏将测试套件的名称作为参数。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h例如,假设想要测试前面文档测试示例中的函数 ``f``,我们可以在定义该函数的同一文件中编写:h](h@例如,假设想要测试前面文档测试示例中的函数 }(hj hhhNhNubj)}(h``f``h]hf}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh<,我们可以在定义该函数的同一文件中编写:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(h#[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; #[test] fn test_f() { assert_eq!(f(10, 20), 30); } }h]h#[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; #[test] fn test_f() { assert_eq!(f(10, 20), 30); } }}hj*sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jNhhhKhjhhubh)}(h8如果我们执行这段代码,内核日志会显示::h]h7如果我们执行这段代码,内核日志会显示:}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(h KTAP version 1 # Subtest: rust_kernel_mymod # speed: normal 1..1 # test_f.speed: normal ok 1 test_f ok 1 rust_kernel_mymodh]h KTAP version 1 # Subtest: rust_kernel_mymod # speed: normal 1..1 # test_f.speed: normal ok 1 test_f ok 1 rust_kernel_mymod}hjHsbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhjhhubh)}(hXa与文档测试类似, ``assert!`` 和 ``assert_eq!`` 宏被映射回 KUnit 并且不会发生 panic。 同样,支持 `? `_ 运算符, 测试函数可以什么都不返回(单元类型 ``()``)或 ``Result`` (任何 ``Result``)。例如:h](h与文档测试类似, }(hjVhhhNhNubj)}(h ``assert!``h]hassert!}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubh 和 }(hjVhhhNhNubj)}(h``assert_eq!``h]h assert_eq!}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubhC 宏被映射回 KUnit 并且不会发生 panic。 同样,支持 }(hjVhhhNhNubj))}(hd`? `_h]h?}(hjhhhNhNubah}(h]h ]h"]h$]h&]namejEjF]https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operatoruh1j(hjVubjI)}(h` h]h}(h]id6ah ]h"]h$]?ah&]refurijuh1jHjWKhjVubhB 运算符, 测试函数可以什么都不返回(单元类型 }(hjVhhhNhNubj)}(h``()``h]h()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubh)或 }(hjVhhhNhNubj)}(h ``Result``h]hResult}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubh (任何 }(hjVhhhNhNubj)}(h``Result``h]h Result}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubh)。例如:}(hjVhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(h#[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; #[test] fn test_g() -> Result { let x = g()?; assert_eq!(x, 30); Ok(()) } }h]h#[kunit_tests(rust_kernel_mymod)] mod tests { use super::*; #[test] fn test_g() -> Result { let x = g()?; assert_eq!(x, 30); Ok(()) } }}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jNhhhKhjhhubh)}(hQ如果我们运行测试并且调用 ``g`` 失败,那么内核日志会显示::h](h%如果我们运行测试并且调用 }(hjhhhNhNubj)}(h``g``h]hg}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh& 失败,那么内核日志会显示:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(hX KTAP version 1 # Subtest: rust_kernel_mymod # speed: normal 1..1 # test_g: ASSERTION FAILED at rust/kernel/lib.rs:335 Expected is_test_result_ok(test_g()) to be true, but is false # test_g.speed: normal not ok 1 test_g not ok 1 rust_kernel_mymodh]hX KTAP version 1 # Subtest: rust_kernel_mymod # speed: normal 1..1 # test_g: ASSERTION FAILED at rust/kernel/lib.rs:335 Expected is_test_result_ok(test_g()) to be true, but is false # test_g.speed: normal not ok 1 test_g not ok 1 rust_kernel_mymod}hjsbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhjhhubh)}(h如果 ``#[test]`` 测试可以对用户起到示例作用,那就应该改用文档测试。 即使是 API 的边界情况,例如错误或边界问题,放在示例中展示也同样有价值。h](h如果 }(hjhhhNhNubj)}(h ``#[test]``h]h#[test]}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 测试可以对用户起到示例作用,那就应该改用文档测试。 即使是 API 的边界情况,例如错误或边界问题,放在示例中展示也同样有价值。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]testah ]h"]#[test] 测试ah$]h&]uh1jVhjXhhhhhK}ubjW)}(hhh](j\)}(h``rusttest`` 宿主机测试h](j)}(h ``rusttest``h]hrusttest}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubh 宿主机测试}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1j[hjEhhhhhKubh)}(hs这类测试运行在用户空间,可以通过 ``rusttest`` 目标在构建内核的宿主机中编译并运行::h](h1这类测试运行在用户空间,可以通过 }(hjdhhhNhNubj)}(h ``rusttest``h]hrusttest}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjdubh5 目标在构建内核的宿主机中编译并运行:}(hjdhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjEhhubjO)}(hmake LLVM=1 rusttesth]hmake LLVM=1 rusttest}hjsbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhjEhhubh)}(h'当前操作需要内核 ``.config``。h](h当前操作需要内核 }(hjhhhNhNubj)}(h ``.config``h]h.config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjEhhubh)}(h?目前,它们主要用于测试 ``macros`` crate 的示例。h](h"目前,它们主要用于测试 }(hjhhhNhNubj)}(h ``macros``h]hmacros}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh crate 的示例。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjEhhubeh}(h]rusttestah ]h"]rusttest 宿主机测试ah$]h&]uh1jVhjXhhhhhKubjW)}(hhh](j\)}(h Kselftestsh]h Kselftests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j[hjhhhhhKubh)}(hKKselftests 可以在 ``tools/testing/selftests/rust`` 文件夹中找到。h](hKselftests 可以在 }(hjhhhNhNubj)}(h ``tools/testing/selftests/rust``h]htools/testing/selftests/rust}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 文件夹中找到。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h测试所需的内核配置选项列在 ``tools/testing/selftests/rust/config`` 文件中, 可以借助 ``merge_config.sh`` 脚本合并到现有配置中::h](h(测试所需的内核配置选项列在 }(hj hhhNhNubj)}(h'``tools/testing/selftests/rust/config``h]h#tools/testing/selftests/rust/config}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 文件中, 可以借助 }(hj hhhNhNubj)}(h``merge_config.sh``h]hmerge_config.sh}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 脚本合并到现有配置中:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(hM./scripts/kconfig/merge_config.sh .config tools/testing/selftests/rust/configh]hM./scripts/kconfig/merge_config.sh .config tools/testing/selftests/rust/config}hj=sbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhjhhubh)}(hhKselftests 会在内核源码树中构建,以便在运行相同版本内核的系统上执行测试。h]hhKselftests 会在内核源码树中构建,以便在运行相同版本内核的系统上执行测试。}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(he一旦安装并启动了与源码树匹配的内核,测试即可通过以下命令编译并执行::h]hd一旦安装并启动了与源码树匹配的内核,测试即可通过以下命令编译并执行:}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjO)}(hmake TARGETS="rust" kselftesth]hmake TARGETS="rust" kselftest}hjgsbah}(h]h ]h"]h$]h&]hhuh1jNhhhKhjhhubh)}(hN请参阅 Documentation/dev-tools/kselftest.rst 文档以获取更多信息。h]hN请参阅 Documentation/dev-tools/kselftest.rst 文档以获取更多信息。}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h] kselftestsah ]h"] kselftestsah$]h&]uh1jVhjXhhhhhKubeh}(h]id1ah ]h"]测试ah$]h&]uh1jVhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(j[N 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_handlerjerror_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}(jjjjjjjjjSjPjBj?jjjju nametypes}(jjjjjSjBjjuh}(jjXjjjj jjjPjJjfj`j?jjjjjEjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages](hsystem_message)}(hhh]h)}(h$Duplicate explicit target name: "?".h]h(Duplicate explicit target name: “?”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]jfalevelKtypeINFOsourcehlineK uh1jhjhhhhhKxubj)}(hhh]h)}(h$Duplicate explicit target name: "?".h]h(Duplicate explicit target name: “?”.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6ubah}(h]h ]h"]h$]h&]jalevelKtypej3sourcehlineK uh1jhjhhhhhKubetransform_messages] transformerN include_log]1Documentation/translations/zh_CN/rust/testing.rst(NNNNta decorationNhhub.