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