158 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. SPDX-License-Identifier: GPL-2.0
 | |
| 
 | |
| Testing
 | |
| =======
 | |
| 
 | |
| This document contains useful information how to test the Rust code in the
 | |
| kernel.
 | |
| 
 | |
| There are three sorts of tests:
 | |
| 
 | |
| - The KUnit tests.
 | |
| - The ``#[test]`` tests.
 | |
| - The Kselftests.
 | |
| 
 | |
| The KUnit tests
 | |
| ---------------
 | |
| 
 | |
| These are the tests that come from the examples in the Rust documentation. They
 | |
| get transformed into KUnit tests.
 | |
| 
 | |
| Usage
 | |
| *****
 | |
| 
 | |
| These tests can be run via KUnit. For example via ``kunit_tool`` (``kunit.py``)
 | |
| on the command line::
 | |
| 
 | |
| 	./tools/testing/kunit/kunit.py run --make_options LLVM=1 --arch x86_64 --kconfig_add CONFIG_RUST=y
 | |
| 
 | |
| Alternatively, 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.
 | |
| 
 | |
| To use these KUnit doctests, the following must be enabled::
 | |
| 
 | |
| 	CONFIG_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
 | |
| 
 | |
| in the kernel config system.
 | |
| 
 | |
| KUnit tests are documentation tests
 | |
| ***********************************
 | |
| 
 | |
| These documentation tests are typically examples of usage of any item (e.g.
 | |
| function, struct, module...).
 | |
| 
 | |
| They are very convenient because they are just written alongside the
 | |
| documentation. For instance:
 | |
| 
 | |
| .. code-block:: rust
 | |
| 
 | |
| 	/// Sums two numbers.
 | |
| 	///
 | |
| 	/// ```
 | |
| 	/// assert_eq!(mymod::f(10, 20), 30);
 | |
| 	/// ```
 | |
| 	pub fn f(a: i32, b: i32) -> i32 {
 | |
| 	    a + b
 | |
| 	}
 | |
| 
 | |
| 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.
 | |
| 
 | |
| For 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.
 | |
| 
 | |
| A benefit of this KUnit integration is that Rust doctests get to reuse existing
 | |
| testing facilities. For instance, the kernel log would look like::
 | |
| 
 | |
| 	KTAP 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
 | |
| 
 | |
| Tests using the `? <https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator>`_
 | |
| operator are also supported as usual, e.g.:
 | |
| 
 | |
| .. code-block:: rust
 | |
| 
 | |
| 	/// ```
 | |
| 	/// # use kernel::{spawn_work_item, workqueue};
 | |
| 	/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
 | |
| 	/// # Ok::<(), Error>(())
 | |
| 	/// ```
 | |
| 
 | |
| The tests are also compiled with Clippy under ``CLIPPY=1``, just like normal
 | |
| code, thus also benefitting from extra linting.
 | |
| 
 | |
| In 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)::
 | |
| 
 | |
| 	# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
 | |
| 
 | |
| Rust 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.
 | |
| 
 | |
| A 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.
 | |
| 
 | |
| The ``#[test]`` tests
 | |
| ---------------------
 | |
| 
 | |
| Additionally, there are the ``#[test]`` tests. These can be run using the
 | |
| ``rusttest`` Make target::
 | |
| 
 | |
| 	make LLVM=1 rusttest
 | |
| 
 | |
| This requires the kernel ``.config``. It runs the ``#[test]`` tests on the host
 | |
| (currently) and thus is fairly limited in what these tests can test.
 | |
| 
 | |
| The Kselftests
 | |
| --------------
 | |
| 
 | |
| Kselftests are also available in the ``tools/testing/selftests/rust`` folder.
 | |
| 
 | |
| The 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::
 | |
| 
 | |
| 	./scripts/kconfig/merge_config.sh .config tools/testing/selftests/rust/config
 | |
| 
 | |
| The kselftests are built within the kernel source tree and are intended to
 | |
| be executed on a system that is running the same kernel.
 | |
| 
 | |
| Once a kernel matching the source tree has been installed and booted, the
 | |
| tests can be compiled and executed using the following command::
 | |
| 
 | |
| 	make TARGETS="rust" kselftest
 | |
| 
 | |
| Refer to Documentation/dev-tools/kselftest.rst for the general Kselftest
 | |
| documentation.
 |