Fake Clock for Deterministic Tests
Inject a manually advanced clock into token expiry logic so tests never sleep and boundary conditions stay reproducible.
Code
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Duration;
#[derive(Clone)]
struct FakeClock {
millis: Arc<AtomicU64>,
}
impl FakeClock {
fn new() -> Self {
Self {
millis: Arc::new(AtomicU64::new(0)),
}
}
fn now(&self) -> Duration {
Duration::from_millis(self.millis.load(Ordering::SeqCst))
}
fn advance(&self, delta: Duration) {
self.millis
.fetch_add(delta.as_millis() as u64, Ordering::SeqCst);
}
}
struct Token {
expires_at: Duration,
}
impl Token {
fn issue(clock: &FakeClock, ttl: Duration) -> Self {
Self {
expires_at: clock.now() + ttl,
}
}
fn expired(&self, clock: &FakeClock) -> bool {
clock.now() >= self.expires_at
}
}
fn main() {
let clock = FakeClock::new();
let token = Token::issue(&clock, Duration::from_secs(60));
clock.advance(Duration::from_secs(59));
println!("expired at 59s: {}", token.expired(&clock));
clock.advance(Duration::from_secs(1));
println!("expired at 60s: {}", token.expired(&clock));
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.