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]
timer_with_threaded_runtime()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]
timer_with_current_thread_scheduler()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]
starving()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]
timeout_value()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