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