1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3
4 use tokio::sync::oneshot;
5 use tokio::time::{self, timeout, timeout_at, Instant};
6 use tokio_test::*;
7
8 use futures::future::pending;
9 use std::time::Duration;
10
11 #[tokio::test]
simultaneous_deadline_future_completion()12 async fn simultaneous_deadline_future_completion() {
13 // Create a future that is immediately ready
14 let mut fut = task::spawn(timeout_at(Instant::now(), async {}));
15
16 // Ready!
17 assert_ready_ok!(fut.poll());
18 }
19
20 #[cfg_attr(target_os = "wasi", ignore = "FIXME: `fut.poll()` panics on Wasi")]
21 #[tokio::test]
completed_future_past_deadline()22 async fn completed_future_past_deadline() {
23 // Wrap it with a deadline
24 let mut fut = task::spawn(timeout_at(Instant::now() - ms(1000), async {}));
25
26 // Ready!
27 assert_ready_ok!(fut.poll());
28 }
29
30 #[tokio::test]
future_and_deadline_in_future()31 async fn future_and_deadline_in_future() {
32 time::pause();
33
34 // Not yet complete
35 let (tx, rx) = oneshot::channel();
36
37 // Wrap it with a deadline
38 let mut fut = task::spawn(timeout_at(Instant::now() + ms(100), rx));
39
40 assert_pending!(fut.poll());
41
42 // Turn the timer, it runs for the elapsed time
43 time::advance(ms(90)).await;
44
45 assert_pending!(fut.poll());
46
47 // Complete the future
48 tx.send(()).unwrap();
49 assert!(fut.is_woken());
50
51 assert_ready_ok!(fut.poll()).unwrap();
52 }
53
54 #[tokio::test]
future_and_timeout_in_future()55 async fn future_and_timeout_in_future() {
56 time::pause();
57
58 // Not yet complete
59 let (tx, rx) = oneshot::channel();
60
61 // Wrap it with a deadline
62 let mut fut = task::spawn(timeout(ms(100), rx));
63
64 // Ready!
65 assert_pending!(fut.poll());
66
67 // Turn the timer, it runs for the elapsed time
68 time::advance(ms(90)).await;
69
70 assert_pending!(fut.poll());
71
72 // Complete the future
73 tx.send(()).unwrap();
74
75 assert_ready_ok!(fut.poll()).unwrap();
76 }
77
78 #[tokio::test]
very_large_timeout()79 async fn very_large_timeout() {
80 time::pause();
81
82 // Not yet complete
83 let (tx, rx) = oneshot::channel();
84
85 // copy-paste unstable `Duration::MAX`
86 let duration_max = Duration::from_secs(u64::MAX) + Duration::from_nanos(999_999_999);
87
88 // Wrap it with a deadline
89 let mut fut = task::spawn(timeout(duration_max, rx));
90
91 // Ready!
92 assert_pending!(fut.poll());
93
94 // Turn the timer, it runs for the elapsed time
95 time::advance(Duration::from_secs(86400 * 365 * 10)).await;
96
97 assert_pending!(fut.poll());
98
99 // Complete the future
100 tx.send(()).unwrap();
101
102 assert_ready_ok!(fut.poll()).unwrap();
103 }
104
105 #[tokio::test]
deadline_now_elapses()106 async fn deadline_now_elapses() {
107 use futures::future::pending;
108
109 time::pause();
110
111 // Wrap it with a deadline
112 let mut fut = task::spawn(timeout_at(Instant::now(), pending::<()>()));
113
114 // Factor in jitter
115 // TODO: don't require this
116 time::advance(ms(1)).await;
117
118 assert_ready_err!(fut.poll());
119 }
120
121 #[tokio::test]
deadline_future_elapses()122 async fn deadline_future_elapses() {
123 time::pause();
124
125 // Wrap it with a deadline
126 let mut fut = task::spawn(timeout_at(Instant::now() + ms(300), pending::<()>()));
127
128 assert_pending!(fut.poll());
129
130 time::advance(ms(301)).await;
131
132 assert!(fut.is_woken());
133 assert_ready_err!(fut.poll());
134 }
135
ms(n: u64) -> Duration136 fn ms(n: u64) -> Duration {
137 Duration::from_millis(n)
138 }
139
140 #[tokio::test]
timeout_is_not_exhausted_by_future()141 async fn timeout_is_not_exhausted_by_future() {
142 let fut = timeout(ms(1), async {
143 let mut buffer = [0u8; 1];
144 loop {
145 use tokio::io::AsyncReadExt;
146 let _ = tokio::io::empty().read(&mut buffer).await;
147 }
148 });
149
150 assert!(fut.await.is_err());
151 }
152