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