summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorJosé Expósito <jose.exposito89@gmail.com>2025-03-07 17:00:58 +0800
committerMiguel Ojeda <ojeda@kernel.org>2025-03-20 12:27:05 +0100
commit100af58c8d5822750ef9ba65f5d5ea3367c669de (patch)
treec593c1a68c9c193f5ac575260d8eb00006e02849 /rust
parentc0010452893e07e032427e88f6b7b4bf7ac42e95 (diff)
rust: kunit: allow to know if we are in a test
In some cases, we need to call test-only code from outside the test case, for example, to mock a function or a module. In order to check whether we are in a test or not, we need to test if `CONFIG_KUNIT` is set. Unfortunately, we cannot rely only on this condition because: - a test could be running in another thread, - some distros compile KUnit in production kernels, so checking at runtime that `current->kunit_test != NULL` is required. Forturately, KUnit provides an optimised check in `kunit_get_current_test()`, which checks CONFIG_KUNIT, a global static key, and then the current thread's running KUnit test. Add a safe wrapper function around this to know whether or not we are in a KUnit test and examples showing how to mock a function and a module. Signed-off-by: José Expósito <jose.exposito89@gmail.com> Co-developed-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Co-developed-by: David Gow <davidgow@google.com> Signed-off-by: David Gow <davidgow@google.com> Link: https://lore.kernel.org/r/20250307090103.918788-4-davidgow@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust')
-rw-r--r--rust/kernel/kunit.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs
index 50cd45912d6e..1604fb6a5b1b 100644
--- a/rust/kernel/kunit.rs
+++ b/rust/kernel/kunit.rs
@@ -288,11 +288,47 @@ macro_rules! kunit_unsafe_test_suite {
};
}
+/// Returns whether we are currently running a KUnit test.
+///
+/// In some cases, you need to call test-only code from outside the test case, for example, to
+/// create a function mock. This function allows to change behavior depending on whether we are
+/// currently running a KUnit test or not.
+///
+/// # Examples
+///
+/// This example shows how a function can be mocked to return a well-known value while testing:
+///
+/// ```
+/// # use kernel::kunit::in_kunit_test;
+/// fn fn_mock_example(n: i32) -> i32 {
+/// if in_kunit_test() {
+/// return 100;
+/// }
+///
+/// n + 1
+/// }
+///
+/// let mock_res = fn_mock_example(5);
+/// assert_eq!(mock_res, 100);
+/// ```
+pub fn in_kunit_test() -> bool {
+ // SAFETY: `kunit_get_current_test()` is always safe to call (it has fallbacks for
+ // when KUnit is not enabled).
+ !unsafe { bindings::kunit_get_current_test() }.is_null()
+}
+
#[kunit_tests(rust_kernel_kunit)]
mod tests {
+ use super::*;
+
#[test]
fn rust_test_kunit_example_test() {
#![expect(clippy::eq_op)]
assert_eq!(1 + 1, 2);
}
+
+ #[test]
+ fn rust_test_kunit_in_kunit_test() {
+ assert!(in_kunit_test());
+ }
}