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