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