1 | #![warn (rust_2018_idioms)] |
2 | #![cfg (feature = "full" )] |
3 | |
4 | use tokio::time::*; |
5 | |
6 | use std::sync::mpsc; |
7 | |
8 | #[cfg (all(feature = "rt-multi-thread" , not(target_os = "wasi" )))] // Wasi doesn't support threads |
9 | #[test] |
10 | fn timer_with_threaded_runtime() { |
11 | use tokio::runtime::Runtime; |
12 | |
13 | let rt = Runtime::new().unwrap(); |
14 | let (tx, rx) = mpsc::channel(); |
15 | |
16 | rt.spawn(async move { |
17 | let when = Instant::now() + Duration::from_millis(10); |
18 | |
19 | sleep_until(when).await; |
20 | assert!(Instant::now() >= when); |
21 | |
22 | tx.send(()).unwrap(); |
23 | }); |
24 | |
25 | rx.recv().unwrap(); |
26 | } |
27 | |
28 | #[test] |
29 | fn timer_with_current_thread_scheduler() { |
30 | use tokio::runtime::Builder; |
31 | |
32 | let rt = Builder::new_current_thread().enable_all().build().unwrap(); |
33 | let (tx, rx) = mpsc::channel(); |
34 | |
35 | rt.block_on(async move { |
36 | let when = Instant::now() + Duration::from_millis(10); |
37 | |
38 | sleep_until(when).await; |
39 | assert!(Instant::now() >= when); |
40 | |
41 | tx.send(()).unwrap(); |
42 | }); |
43 | |
44 | rx.recv().unwrap(); |
45 | } |
46 | |
47 | #[tokio::test ] |
48 | async fn starving() { |
49 | use std::future::Future; |
50 | use std::pin::Pin; |
51 | use std::task::{Context, Poll}; |
52 | |
53 | struct Starve<T: Future<Output = ()> + Unpin>(T, u64); |
54 | |
55 | impl<T: Future<Output = ()> + Unpin> Future for Starve<T> { |
56 | type Output = u64; |
57 | |
58 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<u64> { |
59 | if Pin::new(&mut self.0).poll(cx).is_ready() { |
60 | return Poll::Ready(self.1); |
61 | } |
62 | |
63 | self.1 += 1; |
64 | |
65 | cx.waker().wake_by_ref(); |
66 | |
67 | Poll::Pending |
68 | } |
69 | } |
70 | |
71 | let when = Instant::now() + Duration::from_millis(10); |
72 | let starve = Starve(Box::pin(sleep_until(when)), 0); |
73 | |
74 | starve.await; |
75 | assert!(Instant::now() >= when); |
76 | } |
77 | |
78 | #[tokio::test ] |
79 | async fn timeout_value() { |
80 | use tokio::sync::oneshot; |
81 | |
82 | let (_tx, rx) = oneshot::channel::<()>(); |
83 | |
84 | let now = Instant::now(); |
85 | let dur = Duration::from_millis(10); |
86 | |
87 | let res = timeout(dur, rx).await; |
88 | assert!(res.is_err()); |
89 | assert!(Instant::now() >= now + dur); |
90 | } |
91 | |