1 use mio::{Events, Poll, PollOpt, Ready, Token};
2 use mio_extras::timer::{self, Timer};
3
4 use std::thread;
5 use std::time::Duration;
6
7 #[test]
test_basic_timer_without_poll()8 fn test_basic_timer_without_poll() {
9 let mut timer = Timer::default();
10
11 // Set the timeout
12 timer.set_timeout(Duration::from_millis(200), "hello");
13
14 // Nothing when polled immediately
15 assert!(timer.poll().is_none());
16
17 // Wait for the timeout
18 thread::sleep(Duration::from_millis(250));
19
20 assert_eq!(Some("hello"), timer.poll());
21 assert!(timer.poll().is_none());
22 }
23
24 #[test]
test_basic_timer_with_poll_edge_set_timeout_after_register()25 fn test_basic_timer_with_poll_edge_set_timeout_after_register() {
26 let poll = Poll::new().unwrap();
27 let mut events = Events::with_capacity(1024);
28 let mut timer = Timer::default();
29
30 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
31 .unwrap();
32 timer.set_timeout(Duration::from_millis(200), "hello");
33
34 let elapsed = elapsed(|| {
35 let num = poll.poll(&mut events, None).unwrap();
36
37 assert_eq!(num, 1);
38 let event = events.iter().next().unwrap();
39 assert_eq!(Token(0), event.token());
40 assert_eq!(Ready::readable(), event.readiness());
41 });
42
43 assert!(is_about(200, elapsed), "actual={:?}", elapsed);
44 assert_eq!("hello", timer.poll().unwrap());
45 assert_eq!(None, timer.poll());
46 }
47
48 #[test]
test_basic_timer_with_poll_edge_set_timeout_before_register()49 fn test_basic_timer_with_poll_edge_set_timeout_before_register() {
50 let poll = Poll::new().unwrap();
51 let mut events = Events::with_capacity(1024);
52 let mut timer = Timer::default();
53
54 timer.set_timeout(Duration::from_millis(200), "hello");
55 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
56 .unwrap();
57
58 let elapsed = elapsed(|| {
59 let num = poll.poll(&mut events, None).unwrap();
60
61 assert_eq!(num, 1);
62 let event = events.iter().next().unwrap();
63 assert_eq!(Token(0), event.token());
64 assert_eq!(Ready::readable(), event.readiness());
65 });
66
67 assert!(is_about(200, elapsed), "actual={:?}", elapsed);
68 assert_eq!("hello", timer.poll().unwrap());
69 assert_eq!(None, timer.poll());
70 }
71
72 #[test]
test_setting_later_timeout_then_earlier_one()73 fn test_setting_later_timeout_then_earlier_one() {
74 let poll = Poll::new().unwrap();
75 let mut events = Events::with_capacity(1024);
76 let mut timer = Timer::default();
77
78 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
79 .unwrap();
80
81 timer.set_timeout(Duration::from_millis(600), "hello");
82 timer.set_timeout(Duration::from_millis(200), "world");
83
84 let elapsed = elapsed(|| {
85 let num = poll.poll(&mut events, None).unwrap();
86
87 assert_eq!(num, 1);
88 let event = events.iter().next().unwrap();
89 assert_eq!(Token(0), event.token());
90 assert_eq!(Ready::readable(), event.readiness());
91 });
92
93 assert!(is_about(200, elapsed), "actual={:?}", elapsed);
94 assert_eq!("world", timer.poll().unwrap());
95 assert_eq!(None, timer.poll());
96
97 let elapsed = self::elapsed(|| {
98 let num = poll.poll(&mut events, None).unwrap();
99
100 assert_eq!(num, 1);
101 let event = events.iter().next().unwrap();
102 assert_eq!(Token(0), event.token());
103 assert_eq!(Ready::readable(), event.readiness());
104 });
105
106 assert!(is_about(400, elapsed), "actual={:?}", elapsed);
107 assert_eq!("hello", timer.poll().unwrap());
108 assert_eq!(None, timer.poll());
109 }
110
111 #[test]
test_timer_with_looping_wheel()112 fn test_timer_with_looping_wheel() {
113 let poll = Poll::new().unwrap();
114 let mut events = Events::with_capacity(1024);
115 let mut timer = timer::Builder::default().num_slots(2).build();
116
117 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
118 .unwrap();
119
120 const TOKENS: &[&str] = &["hello", "world", "some", "thing"];
121
122 for (i, msg) in TOKENS.iter().enumerate() {
123 timer.set_timeout(Duration::from_millis(500 * (i as u64 + 1)), msg);
124 }
125
126 for msg in TOKENS {
127 let elapsed = elapsed(|| {
128 let num = poll.poll(&mut events, None).unwrap();
129
130 assert_eq!(num, 1);
131 let event = events.iter().next().unwrap();
132 assert_eq!(Token(0), event.token());
133 assert_eq!(Ready::readable(), event.readiness());
134 });
135
136 assert!(
137 is_about(500, elapsed),
138 "actual={:?}; msg={:?}",
139 elapsed,
140 msg
141 );
142 assert_eq!(Some(msg), timer.poll());
143 assert_eq!(None, timer.poll());
144 }
145 }
146
147 #[test]
test_edge_without_polling()148 fn test_edge_without_polling() {
149 let poll = Poll::new().unwrap();
150 let mut events = Events::with_capacity(1024);
151 let mut timer = Timer::default();
152
153 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
154 .unwrap();
155
156 timer.set_timeout(Duration::from_millis(400), "hello");
157
158 let ms = elapsed(|| {
159 let num = poll.poll(&mut events, None).unwrap();
160 assert_eq!(num, 1);
161 let event = events.iter().next().unwrap();
162 assert_eq!(Token(0), event.token());
163 assert_eq!(Ready::readable(), event.readiness());
164 });
165
166 assert!(is_about(400, ms), "actual={:?}", ms);
167
168 let ms = elapsed(|| {
169 let num = poll.poll(&mut events, Some(Duration::from_millis(300)))
170 .unwrap();
171 assert_eq!(num, 0);
172 });
173
174 assert!(is_about(300, ms), "actual={:?}", ms);
175 }
176
177 #[test]
test_level_triggered()178 fn test_level_triggered() {
179 let poll = Poll::new().unwrap();
180 let mut events = Events::with_capacity(1024);
181 let mut timer = Timer::default();
182
183 poll.register(&timer, Token(0), Ready::readable(), PollOpt::level())
184 .unwrap();
185
186 timer.set_timeout(Duration::from_millis(400), "hello");
187
188 let ms = elapsed(|| {
189 let num = poll.poll(&mut events, None).unwrap();
190 assert_eq!(num, 1);
191 let event = events.iter().next().unwrap();
192 assert_eq!(Token(0), event.token());
193 assert_eq!(Ready::readable(), event.readiness());
194 });
195
196 assert!(is_about(400, ms), "actual={:?}", ms);
197
198 let ms = elapsed(|| {
199 let num = poll.poll(&mut events, None).unwrap();
200 assert_eq!(num, 1);
201 let event = events.iter().next().unwrap();
202 assert_eq!(Token(0), event.token());
203 assert_eq!(Ready::readable(), event.readiness());
204 });
205
206 assert!(is_about(0, ms), "actual={:?}", ms);
207 }
208
209 #[test]
test_edge_oneshot_triggered()210 fn test_edge_oneshot_triggered() {
211 let poll = Poll::new().unwrap();
212 let mut events = Events::with_capacity(1024);
213 let mut timer = Timer::default();
214
215 poll.register(
216 &timer,
217 Token(0),
218 Ready::readable(),
219 PollOpt::edge() | PollOpt::oneshot(),
220 ).unwrap();
221
222 timer.set_timeout(Duration::from_millis(200), "hello");
223
224 let ms = elapsed(|| {
225 let num = poll.poll(&mut events, None).unwrap();
226 assert_eq!(num, 1);
227 });
228
229 assert!(is_about(200, ms), "actual={:?}", ms);
230
231 let ms = elapsed(|| {
232 let num = poll.poll(&mut events, Some(Duration::from_millis(300)))
233 .unwrap();
234 assert_eq!(num, 0);
235 });
236
237 assert!(is_about(300, ms), "actual={:?}", ms);
238
239 poll.reregister(
240 &timer,
241 Token(0),
242 Ready::readable(),
243 PollOpt::edge() | PollOpt::oneshot(),
244 ).unwrap();
245
246 let ms = elapsed(|| {
247 let num = poll.poll(&mut events, None).unwrap();
248 assert_eq!(num, 1);
249 });
250
251 assert!(is_about(0, ms));
252 }
253
254 #[test]
test_cancel_timeout()255 fn test_cancel_timeout() {
256 use std::time::Instant;
257
258 let mut timer: Timer<u32> = Default::default();
259 let timeout = timer.set_timeout(Duration::from_millis(200), 1);
260 timer.cancel_timeout(&timeout);
261
262 let poll = Poll::new().unwrap();
263 poll.register(&timer, Token(0), Ready::readable(), PollOpt::edge())
264 .unwrap();
265
266 let mut events = Events::with_capacity(16);
267
268 let now = Instant::now();
269 let dur = Duration::from_millis(500);
270 let mut i = 0;
271
272 while Instant::now() - now < dur {
273 if i > 10 {
274 panic!("iterated too many times");
275 }
276
277 i += 1;
278
279 let elapsed = Instant::now() - now;
280
281 poll.poll(&mut events, Some(dur - elapsed)).unwrap();
282
283 while let Some(_) = timer.poll() {
284 panic!("did not expect to receive timeout");
285 }
286 }
287 }
288
elapsed<F: FnMut()>(mut f: F) -> u64289 fn elapsed<F: FnMut()>(mut f: F) -> u64 {
290 use std::time::Instant;
291
292 let now = Instant::now();
293
294 f();
295
296 let elapsed = now.elapsed();
297 elapsed.as_secs() * 1000 + u64::from(elapsed.subsec_nanos() / 1_000_000)
298 }
299
is_about(expect: u64, val: u64) -> bool300 fn is_about(expect: u64, val: u64) -> bool {
301 const WINDOW: i64 = 200;
302
303 ((expect as i64) - (val as i64)).abs() <= WINDOW
304 }
305