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