[PATCH v1 1/2] rust: time: add example and KUnit test for Delta::as_millis_ceil()
FUJITA Tomonori <[email protected]>
| Newsgroups | org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
From: FUJITA Tomonori <[email protected]> Add an example showing that the value is rounded towards positive infinity, for both positive and negative spans. as_millis_ceil() uses the same idiom as as_micros_ceil(), which dropped the rounding bias near i64::MAX before commit ec90dfcf05f0 ("rust: time: fix as_micros_ceil() rounding near i64::MAX"), so add a KUnit test for the i64::MAX and i64::MIN extremes. Signed-off-by: FUJITA Tomonori <[email protected]> --- rust/kernel/Kconfig.test | 10 ++++++++++ rust/kernel/time.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/rust/kernel/Kconfig.test b/rust/kernel/Kconfig.test index e6a5c7a795f0..0087749995d2 100644 --- a/rust/kernel/Kconfig.test +++ b/rust/kernel/Kconfig.test @@ -83,4 +83,14 @@ config RUST_BITFIELD_KUNIT_TEST If unsure, say N. +config RUST_TIME_KUNIT_TEST + bool "KUnit tests for the Rust time API" if !KUNIT_ALL_TESTS + default KUNIT_ALL_TESTS + help + This option enables KUnit tests for the Rust time API. + These are only for development and testing, not for regular + kernel use cases. + + If unsure, say N. + endif diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs index 6c0a5e8090d0..b0b43ad3aa47 100644 --- a/rust/kernel/time.rs +++ b/rust/kernel/time.rs @@ -530,6 +530,21 @@ pub fn as_millis(self) -> i64 { /// Return the smallest number of milliseconds greater than or equal /// to the value in the [`Delta`]. + /// + /// # Examples + /// + /// ``` + /// use kernel::time::Delta; + /// + /// // Whole milliseconds are returned as-is. + /// assert_eq!(Delta::from_millis(2).as_millis_ceil(), 2); + /// assert_eq!(Delta::from_nanos(1_000_000).as_millis_ceil(), 1); + /// assert_eq!(Delta::from_nanos(-1_000_000).as_millis_ceil(), -1); + /// + /// // Anything else is rounded towards positive infinity. + /// assert_eq!(Delta::from_nanos(1_000_001).as_millis_ceil(), 2); + /// assert_eq!(Delta::from_nanos(-1_000_001).as_millis_ceil(), -1); + /// ``` #[inline] pub fn as_millis_ceil(self) -> i64 { // Only positive values need to be rounded up: truncating division already @@ -580,3 +595,30 @@ pub fn rem_nanos(self, dividend: i32) -> Self { } } } + +#[cfg(CONFIG_RUST_TIME_KUNIT_TEST)] +#[macros::kunit_tests(rust_kernel_time)] +mod tests { + use super::*; + + /// `i64::MAX` nanoseconds in milliseconds, rounded towards positive infinity. + const MAX_MILLIS_CEIL: i64 = 9_223_372_036_855; + + /// `i64::MIN` nanoseconds in milliseconds, rounded towards positive infinity. + const MIN_MILLIS_CEIL: i64 = -9_223_372_036_854; + + #[test] + fn as_millis_ceil_extremes() { + // The rounding bias must survive near `i64::MAX`. + assert_eq!( + Delta::from_nanos(i64::MAX).as_millis_ceil(), + MAX_MILLIS_CEIL + ); + + // No bias is applied to negative values, so `i64::MIN` cannot overflow. + assert_eq!( + Delta::from_nanos(i64::MIN).as_millis_ceil(), + MIN_MILLIS_CEIL + ); + } +} -- 2.43.0