Add SystemClock
(#8239)
This PR adds a `SystemClock` trait for abstracting away the system clock. This allows us to swap out the real system clock with a `FakeSystemClock` in the tests, thus allowing the fake passage of time. We're using this in `Telemetry` to better mock the clock for testing purposes. Release Notes: - N/A
This commit is contained in:
parent
cc8e3c2286
commit
0de8672044
16 changed files with 213 additions and 55 deletions
59
crates/clock/src/system_clock.rs
Normal file
59
crates/clock/src/system_clock.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
|
||||
pub trait SystemClock: Send + Sync {
|
||||
/// Returns the current date and time in UTC.
|
||||
fn utc_now(&self) -> DateTime<Utc>;
|
||||
}
|
||||
|
||||
pub struct RealSystemClock;
|
||||
|
||||
impl SystemClock for RealSystemClock {
|
||||
fn utc_now(&self) -> DateTime<Utc> {
|
||||
Utc::now()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub struct FakeSystemClockState {
|
||||
now: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub struct FakeSystemClock {
|
||||
// Use an unfair lock to ensure tests are deterministic.
|
||||
state: parking_lot::Mutex<FakeSystemClockState>,
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl Default for FakeSystemClock {
|
||||
fn default() -> Self {
|
||||
Self::new(Utc::now())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl FakeSystemClock {
|
||||
pub fn new(now: DateTime<Utc>) -> Self {
|
||||
let state = FakeSystemClockState { now };
|
||||
|
||||
Self {
|
||||
state: parking_lot::Mutex::new(state),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_now(&self, now: DateTime<Utc>) {
|
||||
self.state.lock().now = now;
|
||||
}
|
||||
|
||||
/// Advances the [`FakeSystemClock`] by the specified [`Duration`](chrono::Duration).
|
||||
pub fn advance(&self, duration: chrono::Duration) {
|
||||
self.state.lock().now += duration;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl SystemClock for FakeSystemClock {
|
||||
fn utc_now(&self) -> DateTime<Utc> {
|
||||
self.state.lock().now
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue