1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3 #![cfg(not(miri))] // Too slow on miri.
4 
5 use rand::SeedableRng;
6 use rand::{rngs::StdRng, Rng};
7 use tokio::time::{self, Duration, Instant, Sleep};
8 use tokio_test::{assert_elapsed, assert_pending, assert_ready, assert_ready_eq, task};
9 
10 #[cfg(not(target_os = "wasi"))]
11 use tokio_test::assert_err;
12 
13 use std::{
14     future::Future,
15     pin::Pin,
16     task::{Context, Poll},
17 };
18 
19 #[tokio::test]
pause_time_in_main()20 async fn pause_time_in_main() {
21     tokio::time::pause();
22 }
23 
24 #[tokio::test]
pause_time_in_task()25 async fn pause_time_in_task() {
26     let t = tokio::spawn(async {
27         tokio::time::pause();
28     });
29 
30     t.await.unwrap();
31 }
32 
33 #[cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support threads
34 #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
35 #[should_panic]
pause_time_in_main_threads()36 async fn pause_time_in_main_threads() {
37     tokio::time::pause();
38 }
39 
40 #[cfg_attr(panic = "abort", ignore)]
41 #[cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support threads
42 #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pause_time_in_spawn_threads()43 async fn pause_time_in_spawn_threads() {
44     let t = tokio::spawn(async {
45         tokio::time::pause();
46     });
47 
48     assert_err!(t.await);
49 }
50 
51 #[test]
paused_time_is_deterministic()52 fn paused_time_is_deterministic() {
53     let run_1 = paused_time_stress_run();
54     let run_2 = paused_time_stress_run();
55 
56     assert_eq!(run_1, run_2);
57 }
58 
59 #[tokio::main(flavor = "current_thread", start_paused = true)]
paused_time_stress_run() -> Vec<Duration>60 async fn paused_time_stress_run() -> Vec<Duration> {
61     let mut rng = StdRng::seed_from_u64(1);
62 
63     let mut times = vec![];
64     let start = Instant::now();
65     for _ in 0..10_000 {
66         let sleep = rng.gen_range(Duration::from_secs(0)..Duration::from_secs(1));
67         time::sleep(sleep).await;
68         times.push(start.elapsed());
69     }
70 
71     times
72 }
73 
74 #[tokio::test(start_paused = true)]
advance_after_poll()75 async fn advance_after_poll() {
76     time::sleep(ms(1)).await;
77 
78     let start = Instant::now();
79 
80     let mut sleep = task::spawn(time::sleep_until(start + ms(300)));
81 
82     assert_pending!(sleep.poll());
83 
84     let before = Instant::now();
85     time::advance(ms(100)).await;
86     assert_elapsed!(before, ms(100));
87 
88     assert_pending!(sleep.poll());
89 }
90 
91 #[tokio::test(start_paused = true)]
sleep_no_poll()92 async fn sleep_no_poll() {
93     let start = Instant::now();
94 
95     // TODO: Skip this
96     time::advance(ms(1)).await;
97 
98     let mut sleep = task::spawn(time::sleep_until(start + ms(300)));
99 
100     let before = Instant::now();
101     time::advance(ms(100)).await;
102     assert_elapsed!(before, ms(100));
103 
104     assert_pending!(sleep.poll());
105 }
106 
107 enum State {
108     Begin,
109     AwaitingAdvance(Pin<Box<dyn Future<Output = ()>>>),
110     AfterAdvance,
111 }
112 
113 struct Tester {
114     sleep: Pin<Box<Sleep>>,
115     state: State,
116     before: Option<Instant>,
117     poll: bool,
118 }
119 
120 impl Future for Tester {
121     type Output = ();
122 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>123     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
124         match &mut self.state {
125             State::Begin => {
126                 if self.poll {
127                     assert_pending!(self.sleep.as_mut().poll(cx));
128                 }
129                 self.before = Some(Instant::now());
130                 let advance_fut = Box::pin(time::advance(ms(100)));
131                 self.state = State::AwaitingAdvance(advance_fut);
132                 self.poll(cx)
133             }
134             State::AwaitingAdvance(ref mut advance_fut) => match advance_fut.as_mut().poll(cx) {
135                 Poll::Pending => Poll::Pending,
136                 Poll::Ready(()) => {
137                     self.state = State::AfterAdvance;
138                     self.poll(cx)
139                 }
140             },
141             State::AfterAdvance => {
142                 assert_elapsed!(self.before.unwrap(), ms(100));
143 
144                 assert_pending!(self.sleep.as_mut().poll(cx));
145 
146                 Poll::Ready(())
147             }
148         }
149     }
150 }
151 
152 #[tokio::test(start_paused = true)]
sleep_same_task()153 async fn sleep_same_task() {
154     let start = Instant::now();
155 
156     // TODO: Skip this
157     time::advance(ms(1)).await;
158 
159     let sleep = Box::pin(time::sleep_until(start + ms(300)));
160 
161     Tester {
162         sleep,
163         state: State::Begin,
164         before: None,
165         poll: true,
166     }
167     .await;
168 }
169 
170 #[tokio::test(start_paused = true)]
sleep_same_task_no_poll()171 async fn sleep_same_task_no_poll() {
172     let start = Instant::now();
173 
174     // TODO: Skip this
175     time::advance(ms(1)).await;
176 
177     let sleep = Box::pin(time::sleep_until(start + ms(300)));
178 
179     Tester {
180         sleep,
181         state: State::Begin,
182         before: None,
183         poll: false,
184     }
185     .await;
186 }
187 
188 #[tokio::test(start_paused = true)]
interval()189 async fn interval() {
190     let start = Instant::now();
191 
192     // TODO: Skip this
193     time::advance(ms(1)).await;
194 
195     let mut i = task::spawn(time::interval_at(start, ms(300)));
196 
197     assert_ready_eq!(poll_next(&mut i), start);
198     assert_pending!(poll_next(&mut i));
199 
200     let before = Instant::now();
201     time::advance(ms(100)).await;
202     assert_elapsed!(before, ms(100));
203     assert_pending!(poll_next(&mut i));
204 
205     let before = Instant::now();
206     time::advance(ms(200)).await;
207     assert_elapsed!(before, ms(200));
208     assert_ready_eq!(poll_next(&mut i), start + ms(300));
209     assert_pending!(poll_next(&mut i));
210 
211     let before = Instant::now();
212     time::advance(ms(400)).await;
213     assert_elapsed!(before, ms(400));
214     assert_ready_eq!(poll_next(&mut i), start + ms(600));
215     assert_pending!(poll_next(&mut i));
216 
217     let before = Instant::now();
218     time::advance(ms(500)).await;
219     assert_elapsed!(before, ms(500));
220     assert_ready_eq!(poll_next(&mut i), start + ms(900));
221     assert_ready_eq!(poll_next(&mut i), start + ms(1200));
222     assert_pending!(poll_next(&mut i));
223 }
224 
225 #[tokio::test(start_paused = true)]
test_time_advance_sub_ms()226 async fn test_time_advance_sub_ms() {
227     let now = Instant::now();
228 
229     let dur = Duration::from_micros(51_592);
230     time::advance(dur).await;
231 
232     assert_eq!(now.elapsed(), dur);
233 
234     let now = Instant::now();
235     let dur = Duration::from_micros(1);
236     time::advance(dur).await;
237 
238     assert_eq!(now.elapsed(), dur);
239 }
240 
241 #[tokio::test(start_paused = true)]
test_time_advance_3ms_and_change()242 async fn test_time_advance_3ms_and_change() {
243     let now = Instant::now();
244 
245     let dur = Duration::from_micros(3_141_592);
246     time::advance(dur).await;
247 
248     assert_eq!(now.elapsed(), dur);
249 
250     let now = Instant::now();
251     let dur = Duration::from_micros(3_123_456);
252     time::advance(dur).await;
253 
254     assert_eq!(now.elapsed(), dur);
255 }
256 
257 #[tokio::test(start_paused = true)]
regression_3710_with_submillis_advance()258 async fn regression_3710_with_submillis_advance() {
259     let start = Instant::now();
260 
261     time::advance(Duration::from_millis(1)).await;
262 
263     let mut sleep = task::spawn(time::sleep_until(start + Duration::from_secs(60)));
264 
265     assert_pending!(sleep.poll());
266 
267     let before = Instant::now();
268     let dur = Duration::from_micros(51_592);
269     time::advance(dur).await;
270     assert_eq!(before.elapsed(), dur);
271 
272     assert_pending!(sleep.poll());
273 }
274 
275 #[tokio::test(start_paused = true)]
exact_1ms_advance()276 async fn exact_1ms_advance() {
277     let now = Instant::now();
278 
279     let dur = Duration::from_millis(1);
280     time::advance(dur).await;
281 
282     assert_eq!(now.elapsed(), dur);
283 
284     let now = Instant::now();
285     let dur = Duration::from_millis(1);
286     time::advance(dur).await;
287 
288     assert_eq!(now.elapsed(), dur);
289 }
290 
291 #[tokio::test(start_paused = true)]
advance_once_with_timer()292 async fn advance_once_with_timer() {
293     let mut sleep = task::spawn(time::sleep(Duration::from_millis(1)));
294     assert_pending!(sleep.poll());
295 
296     time::advance(Duration::from_micros(250)).await;
297     assert_pending!(sleep.poll());
298 
299     time::advance(Duration::from_micros(1500)).await;
300 
301     assert!(sleep.is_woken());
302     assert_ready!(sleep.poll());
303 }
304 
305 #[tokio::test(start_paused = true)]
advance_multi_with_timer()306 async fn advance_multi_with_timer() {
307     // Round to the nearest ms
308     // time::sleep(Duration::from_millis(1)).await;
309 
310     let mut sleep = task::spawn(time::sleep(Duration::from_millis(1)));
311     assert_pending!(sleep.poll());
312 
313     time::advance(Duration::from_micros(250)).await;
314     assert_pending!(sleep.poll());
315 
316     time::advance(Duration::from_micros(250)).await;
317     assert_pending!(sleep.poll());
318 
319     time::advance(Duration::from_micros(250)).await;
320     assert_pending!(sleep.poll());
321 
322     time::advance(Duration::from_micros(250)).await;
323     assert!(sleep.is_woken());
324     assert_ready!(sleep.poll());
325 }
326 
poll_next(interval: &mut task::Spawn<time::Interval>) -> Poll<Instant>327 fn poll_next(interval: &mut task::Spawn<time::Interval>) -> Poll<Instant> {
328     interval.enter(|cx, mut interval| interval.poll_tick(cx))
329 }
330 
ms(n: u64) -> Duration331 fn ms(n: u64) -> Duration {
332     Duration::from_millis(n)
333 }
334