mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
synced 2025-09-26 18:38:20 +10:00
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>
This commit is contained in:
parent
c001045289
commit
100af58c8d
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user