1#![warn(rust_2018_idioms)]
2#![cfg(feature = "full")]
3
4use tokio::sync::oneshot;
5use tokio::time::{self, timeout, timeout_at, Instant};
6use tokio_test::*;
7
8use futures::future::pending;
9use std::time::Duration;
10
11#[tokio::test]
12async 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]
22async 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]
31async 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]
55async 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]
79async 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]
106async 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]
122async 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
136fn ms(n: u64) -> Duration {
137 Duration::from_millis(n)
138}
139
140#[tokio::test]
141async 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