aws_smithy_async/test_util/
instant_sleep.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use crate::time::{SharedTimeSource, TimeSource};
7use crate::{
8    rt::sleep::{AsyncSleep, Sleep},
9    test_util::ManualTimeSource,
10};
11use std::sync::{Arc, Mutex};
12use std::time::{Duration, SystemTime};
13
14/// A sleep implementation where calls to [`AsyncSleep::sleep`] will complete instantly.
15///
16/// Create a [`InstantSleep`] with [`instant_time_and_sleep`]
17#[derive(Debug, Clone)]
18pub struct InstantSleep {
19    log: Arc<Mutex<Vec<Duration>>>,
20}
21
22impl AsyncSleep for InstantSleep {
23    fn sleep(&self, duration: Duration) -> Sleep {
24        let log = self.log.clone();
25        Sleep::new(async move {
26            log.lock().unwrap().push(duration);
27        })
28    }
29}
30
31impl InstantSleep {
32    /// Given a shared log for sleep durations, create a new `InstantSleep`.
33    pub fn new(log: Arc<Mutex<Vec<Duration>>>) -> Self {
34        Self { log }
35    }
36
37    /// Create an `InstantSleep` without passing in a shared log.
38    pub fn unlogged() -> Self {
39        Self {
40            log: Default::default(),
41        }
42    }
43
44    /// Return the sleep durations that were logged by this `InstantSleep`.
45    pub fn logs(&self) -> Vec<Duration> {
46        self.log.lock().unwrap().iter().cloned().collect()
47    }
48
49    /// Return the total sleep duration that was logged by this `InstantSleep`.
50    pub fn total_duration(&self) -> Duration {
51        self.log.lock().unwrap().iter().sum()
52    }
53}
54
55/// Returns a duo of tools to test interactions with time. Sleeps will end instantly, but the
56/// desired length of the sleeps will be recorded for later verification.
57pub fn instant_time_and_sleep(start_time: SystemTime) -> (ManualTimeSource, InstantSleep) {
58    let log = Arc::new(Mutex::new(vec![]));
59    let sleep = InstantSleep::new(log.clone());
60    (ManualTimeSource { start_time, log }, sleep)
61}
62
63impl TimeSource for SystemTime {
64    fn now(&self) -> SystemTime {
65        *self
66    }
67}
68
69impl From<SystemTime> for SharedTimeSource {
70    fn from(value: SystemTime) -> Self {
71        SharedTimeSource::new(value)
72    }
73}
74
75impl From<ManualTimeSource> for SharedTimeSource {
76    fn from(value: ManualTimeSource) -> Self {
77        SharedTimeSource::new(value)
78    }
79}