1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3 #![cfg(not(miri))] // Too slow on Miri.
4 
5 use std::future::Future;
6 use std::task::Context;
7 
8 use futures::task::noop_waker_ref;
9 
10 use tokio::time::{self, Duration, Instant};
11 use tokio_test::{assert_elapsed, assert_pending, assert_ready, task};
12 
13 #[tokio::test]
immediate_sleep()14 async fn immediate_sleep() {
15     time::pause();
16 
17     let now = Instant::now();
18 
19     // Ready!
20     time::sleep_until(now).await;
21     assert_elapsed!(now, ms(1));
22 }
23 
24 #[tokio::test]
is_elapsed()25 async fn is_elapsed() {
26     time::pause();
27 
28     let sleep = time::sleep(Duration::from_millis(10));
29 
30     tokio::pin!(sleep);
31 
32     assert!(!sleep.is_elapsed());
33 
34     assert!(futures::poll!(sleep.as_mut()).is_pending());
35 
36     assert!(!sleep.is_elapsed());
37 
38     sleep.as_mut().await;
39 
40     assert!(sleep.is_elapsed());
41 }
42 
43 #[tokio::test]
delayed_sleep_level_0()44 async fn delayed_sleep_level_0() {
45     time::pause();
46 
47     for &i in &[1, 10, 60] {
48         let now = Instant::now();
49         let dur = ms(i);
50 
51         time::sleep_until(now + dur).await;
52 
53         assert_elapsed!(now, dur);
54     }
55 }
56 
57 #[tokio::test]
sub_ms_delayed_sleep()58 async fn sub_ms_delayed_sleep() {
59     time::pause();
60 
61     for _ in 0..5 {
62         let now = Instant::now();
63         let deadline = now + ms(1) + Duration::new(0, 1);
64 
65         time::sleep_until(deadline).await;
66 
67         assert_elapsed!(now, ms(1));
68     }
69 }
70 
71 #[tokio::test]
delayed_sleep_wrapping_level_0()72 async fn delayed_sleep_wrapping_level_0() {
73     time::pause();
74 
75     time::sleep(ms(5)).await;
76 
77     let now = Instant::now();
78     time::sleep_until(now + ms(60)).await;
79 
80     assert_elapsed!(now, ms(60));
81 }
82 
83 #[tokio::test]
reset_future_sleep_before_fire()84 async fn reset_future_sleep_before_fire() {
85     time::pause();
86 
87     let now = Instant::now();
88 
89     let mut sleep = task::spawn(Box::pin(time::sleep_until(now + ms(100))));
90     assert_pending!(sleep.poll());
91 
92     let mut sleep = sleep.into_inner();
93 
94     sleep.as_mut().reset(Instant::now() + ms(200));
95     sleep.await;
96 
97     assert_elapsed!(now, ms(200));
98 }
99 
100 #[tokio::test]
reset_past_sleep_before_turn()101 async fn reset_past_sleep_before_turn() {
102     time::pause();
103 
104     let now = Instant::now();
105 
106     let mut sleep = task::spawn(Box::pin(time::sleep_until(now + ms(100))));
107     assert_pending!(sleep.poll());
108 
109     let mut sleep = sleep.into_inner();
110 
111     sleep.as_mut().reset(now + ms(80));
112     sleep.await;
113 
114     assert_elapsed!(now, ms(80));
115 }
116 
117 #[tokio::test]
reset_past_sleep_before_fire()118 async fn reset_past_sleep_before_fire() {
119     time::pause();
120 
121     let now = Instant::now();
122 
123     let mut sleep = task::spawn(Box::pin(time::sleep_until(now + ms(100))));
124     assert_pending!(sleep.poll());
125 
126     let mut sleep = sleep.into_inner();
127 
128     time::sleep(ms(10)).await;
129 
130     sleep.as_mut().reset(now + ms(80));
131     sleep.await;
132 
133     assert_elapsed!(now, ms(80));
134 }
135 
136 #[tokio::test]
reset_future_sleep_after_fire()137 async fn reset_future_sleep_after_fire() {
138     time::pause();
139 
140     let now = Instant::now();
141     let mut sleep = Box::pin(time::sleep_until(now + ms(100)));
142 
143     sleep.as_mut().await;
144     assert_elapsed!(now, ms(100));
145 
146     sleep.as_mut().reset(now + ms(110));
147     sleep.await;
148     assert_elapsed!(now, ms(110));
149 }
150 
151 #[tokio::test]
reset_sleep_to_past()152 async fn reset_sleep_to_past() {
153     time::pause();
154 
155     let now = Instant::now();
156 
157     let mut sleep = task::spawn(Box::pin(time::sleep_until(now + ms(100))));
158     assert_pending!(sleep.poll());
159 
160     time::sleep(ms(50)).await;
161 
162     assert!(!sleep.is_woken());
163 
164     sleep.as_mut().reset(now + ms(40));
165 
166     // TODO: is this required?
167     //assert!(sleep.is_woken());
168 
169     assert_ready!(sleep.poll());
170 }
171 
172 #[cfg(not(target_os = "wasi"))] // Wasi doesn't support panic recovery
173 #[test]
174 #[should_panic]
creating_sleep_outside_of_context()175 fn creating_sleep_outside_of_context() {
176     let now = Instant::now();
177 
178     // This creates a delay outside of the context of a mock timer. This tests
179     // that it will panic.
180     let _fut = time::sleep_until(now + ms(500));
181 }
182 
183 #[tokio::test]
greater_than_max()184 async fn greater_than_max() {
185     const YR_5: u64 = 5 * 365 * 24 * 60 * 60 * 1000;
186 
187     time::pause();
188     time::sleep_until(Instant::now() + ms(YR_5)).await;
189 }
190 
191 #[tokio::test]
short_sleeps()192 async fn short_sleeps() {
193     for _ in 0..1000 {
194         tokio::time::sleep(std::time::Duration::from_millis(0)).await;
195     }
196 }
197 
198 #[tokio::test]
multi_long_sleeps()199 async fn multi_long_sleeps() {
200     tokio::time::pause();
201 
202     for _ in 0..5u32 {
203         tokio::time::sleep(Duration::from_secs(
204             // about a year
205             365 * 24 * 3600,
206         ))
207         .await;
208     }
209 
210     let deadline = tokio::time::Instant::now()
211         + Duration::from_secs(
212             // about 10 years
213             10 * 365 * 24 * 3600,
214         );
215 
216     tokio::time::sleep_until(deadline).await;
217 
218     assert!(tokio::time::Instant::now() >= deadline);
219 }
220 
221 #[tokio::test]
long_sleeps()222 async fn long_sleeps() {
223     tokio::time::pause();
224 
225     let deadline = tokio::time::Instant::now()
226         + Duration::from_secs(
227             // about 10 years
228             10 * 365 * 24 * 3600,
229         );
230 
231     tokio::time::sleep_until(deadline).await;
232 
233     assert!(tokio::time::Instant::now() >= deadline);
234     assert!(tokio::time::Instant::now() <= deadline + Duration::from_millis(1));
235 }
236 
237 #[tokio::test]
reset_after_firing()238 async fn reset_after_firing() {
239     let timer = tokio::time::sleep(std::time::Duration::from_millis(1));
240     tokio::pin!(timer);
241 
242     let deadline = timer.deadline();
243 
244     timer.as_mut().await;
245     assert_ready!(timer
246         .as_mut()
247         .poll(&mut Context::from_waker(noop_waker_ref())));
248     timer
249         .as_mut()
250         .reset(tokio::time::Instant::now() + std::time::Duration::from_secs(600));
251 
252     assert_ne!(deadline, timer.deadline());
253 
254     assert_pending!(timer
255         .as_mut()
256         .poll(&mut Context::from_waker(noop_waker_ref())));
257     assert_pending!(timer
258         .as_mut()
259         .poll(&mut Context::from_waker(noop_waker_ref())));
260 }
261 
262 const NUM_LEVELS: usize = 6;
263 const MAX_DURATION: u64 = (1 << (6 * NUM_LEVELS)) - 1;
264 
265 #[tokio::test]
exactly_max()266 async fn exactly_max() {
267     time::pause();
268     time::sleep(ms(MAX_DURATION)).await;
269 }
270 
271 #[tokio::test]
issue_5183()272 async fn issue_5183() {
273     time::pause();
274 
275     let big = std::time::Duration::from_secs(u64::MAX / 10);
276     // This is a workaround since awaiting sleep(big) will never finish.
277     #[rustfmt::skip]
278     tokio::select! {
279 	biased;
280         _ = tokio::time::sleep(big) => {}
281         _ = tokio::time::sleep(std::time::Duration::from_nanos(1)) => {}
282     }
283 }
284 
285 #[tokio::test]
no_out_of_bounds_close_to_max()286 async fn no_out_of_bounds_close_to_max() {
287     time::pause();
288     time::sleep(ms(MAX_DURATION - 1)).await;
289 }
290 
ms(n: u64) -> Duration291 fn ms(n: u64) -> Duration {
292     Duration::from_millis(n)
293 }
294 
295 #[tokio::test]
drop_after_reschedule_at_new_scheduled_time()296 async fn drop_after_reschedule_at_new_scheduled_time() {
297     use futures::poll;
298 
299     tokio::time::pause();
300 
301     let start = tokio::time::Instant::now();
302 
303     let mut a = Box::pin(tokio::time::sleep(Duration::from_millis(5)));
304     let mut b = Box::pin(tokio::time::sleep(Duration::from_millis(5)));
305     let mut c = Box::pin(tokio::time::sleep(Duration::from_millis(10)));
306 
307     let _ = poll!(&mut a);
308     let _ = poll!(&mut b);
309     let _ = poll!(&mut c);
310 
311     b.as_mut().reset(start + Duration::from_millis(10));
312     a.await;
313 
314     drop(b);
315 }
316 
317 #[tokio::test]
drop_from_wake()318 async fn drop_from_wake() {
319     use std::future::Future;
320     use std::pin::Pin;
321     use std::sync::atomic::{AtomicBool, Ordering};
322     use std::sync::{Arc, Mutex};
323     use std::task::Context;
324 
325     let panicked = Arc::new(AtomicBool::new(false));
326     let list: Arc<Mutex<Vec<Pin<Box<tokio::time::Sleep>>>>> = Arc::new(Mutex::new(Vec::new()));
327 
328     let arc_wake = Arc::new(DropWaker(panicked.clone(), list.clone()));
329     let arc_wake = futures::task::waker(arc_wake);
330 
331     tokio::time::pause();
332 
333     {
334         let mut lock = list.lock().unwrap();
335 
336         for _ in 0..100 {
337             let mut timer = Box::pin(tokio::time::sleep(Duration::from_millis(10)));
338 
339             let _ = timer.as_mut().poll(&mut Context::from_waker(&arc_wake));
340 
341             lock.push(timer);
342         }
343     }
344 
345     tokio::time::sleep(Duration::from_millis(11)).await;
346 
347     assert!(
348         !panicked.load(Ordering::SeqCst),
349         "panicked when dropping timers"
350     );
351 
352     #[derive(Clone)]
353     struct DropWaker(
354         Arc<AtomicBool>,
355         Arc<Mutex<Vec<Pin<Box<tokio::time::Sleep>>>>>,
356     );
357 
358     impl futures::task::ArcWake for DropWaker {
359         fn wake_by_ref(arc_self: &Arc<Self>) {
360             let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
361                 *arc_self.1.lock().expect("panic in lock") = Vec::new()
362             }));
363 
364             if result.is_err() {
365                 arc_self.0.store(true, Ordering::SeqCst);
366             }
367         }
368     }
369 }
370