use std::future::Future;
use std::pin::Pin;
use std::time::Duration;
use microvms_app::clock::Clock;
#[derive(Debug)]
pub struct TokioClock {
base: tokio::time::Instant,
}
impl TokioClock {
pub fn new() -> Self {
Self {
base: tokio::time::Instant::now(),
}
}
}
impl Default for TokioClock {
fn default() -> Self {
Self::new()
}
}
impl Clock for TokioClock {
fn elapsed(&self) -> Duration {
self.base.elapsed()
}
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
Box::pin(tokio::time::sleep(duration))
}
fn unix_now(&self) -> Duration {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
}
}
pub use TokioClock as SystemClock;
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test(start_paused = true)]
async fn the_production_clock_measures_tokio_time() {
let clock = TokioClock::new();
clock.sleep(Duration::from_secs(1800)).await;
assert_eq!(clock.elapsed(), Duration::from_secs(1800));
let system = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("the host clock is after 1970");
assert!(clock.unix_now().abs_diff(system) < Duration::from_secs(60));
}
}