1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3 
4 use tokio::time::{self, Duration, Instant};
5 use tokio_test::{assert_pending, assert_ready, task};
6 
7 macro_rules! assert_elapsed {
8     ($now:expr, $ms:expr) => {{
9         let elapsed = $now.elapsed();
10         let lower = ms($ms);
11 
12         // Handles ms rounding
13         assert!(
14             elapsed >= lower && elapsed <= lower + ms(1),
15             "actual = {:?}, expected = {:?}",
16             elapsed,
17             lower
18         );
19     }};
20 }
21 
22 #[tokio::test]
immediate_delay()23 async fn immediate_delay() {
24     time::pause();
25 
26     let now = Instant::now();
27 
28     // Ready!
29     time::delay_until(now).await;
30     assert_elapsed!(now, 0);
31 }
32 
33 #[tokio::test]
delayed_delay_level_0()34 async fn delayed_delay_level_0() {
35     time::pause();
36 
37     for &i in &[1, 10, 60] {
38         let now = Instant::now();
39 
40         time::delay_until(now + ms(i)).await;
41 
42         assert_elapsed!(now, i);
43     }
44 }
45 
46 #[tokio::test]
sub_ms_delayed_delay()47 async fn sub_ms_delayed_delay() {
48     time::pause();
49 
50     for _ in 0..5 {
51         let now = Instant::now();
52         let deadline = now + ms(1) + Duration::new(0, 1);
53 
54         time::delay_until(deadline).await;
55 
56         assert_elapsed!(now, 1);
57     }
58 }
59 
60 #[tokio::test]
delayed_delay_wrapping_level_0()61 async fn delayed_delay_wrapping_level_0() {
62     time::pause();
63 
64     time::delay_for(ms(5)).await;
65 
66     let now = Instant::now();
67     time::delay_until(now + ms(60)).await;
68 
69     assert_elapsed!(now, 60);
70 }
71 
72 #[tokio::test]
reset_future_delay_before_fire()73 async fn reset_future_delay_before_fire() {
74     time::pause();
75 
76     let now = Instant::now();
77 
78     let mut delay = task::spawn(time::delay_until(now + ms(100)));
79     assert_pending!(delay.poll());
80 
81     let mut delay = delay.into_inner();
82 
83     delay.reset(Instant::now() + ms(200));
84     delay.await;
85 
86     assert_elapsed!(now, 200);
87 }
88 
89 #[tokio::test]
reset_past_delay_before_turn()90 async fn reset_past_delay_before_turn() {
91     time::pause();
92 
93     let now = Instant::now();
94 
95     let mut delay = task::spawn(time::delay_until(now + ms(100)));
96     assert_pending!(delay.poll());
97 
98     let mut delay = delay.into_inner();
99 
100     delay.reset(now + ms(80));
101     delay.await;
102 
103     assert_elapsed!(now, 80);
104 }
105 
106 #[tokio::test]
reset_past_delay_before_fire()107 async fn reset_past_delay_before_fire() {
108     time::pause();
109 
110     let now = Instant::now();
111 
112     let mut delay = task::spawn(time::delay_until(now + ms(100)));
113     assert_pending!(delay.poll());
114 
115     let mut delay = delay.into_inner();
116 
117     time::delay_for(ms(10)).await;
118 
119     delay.reset(now + ms(80));
120     delay.await;
121 
122     assert_elapsed!(now, 80);
123 }
124 
125 #[tokio::test]
reset_future_delay_after_fire()126 async fn reset_future_delay_after_fire() {
127     time::pause();
128 
129     let now = Instant::now();
130     let mut delay = time::delay_until(now + ms(100));
131 
132     (&mut delay).await;
133     assert_elapsed!(now, 100);
134 
135     delay.reset(now + ms(110));
136     delay.await;
137     assert_elapsed!(now, 110);
138 }
139 
140 #[tokio::test]
reset_delay_to_past()141 async fn reset_delay_to_past() {
142     time::pause();
143 
144     let now = Instant::now();
145 
146     let mut delay = task::spawn(time::delay_until(now + ms(100)));
147     assert_pending!(delay.poll());
148 
149     time::delay_for(ms(50)).await;
150 
151     assert!(!delay.is_woken());
152 
153     delay.reset(now + ms(40));
154 
155     assert!(delay.is_woken());
156 
157     assert_ready!(delay.poll());
158 }
159 
160 #[test]
161 #[should_panic]
creating_delay_outside_of_context()162 fn creating_delay_outside_of_context() {
163     let now = Instant::now();
164 
165     // This creates a delay outside of the context of a mock timer. This tests
166     // that it will panic.
167     let _fut = time::delay_until(now + ms(500));
168 }
169 
170 #[should_panic]
171 #[tokio::test]
greater_than_max()172 async fn greater_than_max() {
173     const YR_5: u64 = 5 * 365 * 24 * 60 * 60 * 1000;
174 
175     time::delay_until(Instant::now() + ms(YR_5)).await;
176 }
177 
178 const NUM_LEVELS: usize = 6;
179 const MAX_DURATION: u64 = (1 << (6 * NUM_LEVELS)) - 1;
180 
181 #[should_panic]
182 #[tokio::test]
exactly_max()183 async fn exactly_max() {
184     // TODO: this should not panic but `time::ms()` is acting up
185     time::delay_for(ms(MAX_DURATION)).await;
186 }
187 
188 #[tokio::test]
no_out_of_bounds_close_to_max()189 async fn no_out_of_bounds_close_to_max() {
190     time::pause();
191     time::delay_for(ms(MAX_DURATION - 1)).await;
192 }
193 
ms(n: u64) -> Duration194 fn ms(n: u64) -> Duration {
195     Duration::from_millis(n)
196 }
197