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 ] |
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 ] |
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 ] |
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 ] |
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 ] |
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 ] |
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 ] |
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 | |
136 | fn ms(n: u64) -> Duration { |
137 | Duration::from_millis(n) |
138 | } |
139 | |
140 | #[tokio::test ] |
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 | |