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