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 #[tokio::test]
completed_future_past_deadline()21 async fn completed_future_past_deadline() {
22 // Wrap it with a deadline
23 let mut fut = task::spawn(timeout_at(Instant::now() - ms(1000), async {}));
24
25 // Ready!
26 assert_ready_ok!(fut.poll());
27 }
28
29 #[tokio::test]
future_and_deadline_in_future()30 async fn future_and_deadline_in_future() {
31 time::pause();
32
33 // Not yet complete
34 let (tx, rx) = oneshot::channel();
35
36 // Wrap it with a deadline
37 let mut fut = task::spawn(timeout_at(Instant::now() + ms(100), rx));
38
39 assert_pending!(fut.poll());
40
41 // Turn the timer, it runs for the elapsed time
42 time::advance(ms(90)).await;
43
44 assert_pending!(fut.poll());
45
46 // Complete the future
47 tx.send(()).unwrap();
48 assert!(fut.is_woken());
49
50 assert_ready_ok!(fut.poll()).unwrap();
51 }
52
53 #[tokio::test]
future_and_timeout_in_future()54 async fn future_and_timeout_in_future() {
55 time::pause();
56
57 // Not yet complete
58 let (tx, rx) = oneshot::channel();
59
60 // Wrap it with a deadline
61 let mut fut = task::spawn(timeout(ms(100), rx));
62
63 // Ready!
64 assert_pending!(fut.poll());
65
66 // Turn the timer, it runs for the elapsed time
67 time::advance(ms(90)).await;
68
69 assert_pending!(fut.poll());
70
71 // Complete the future
72 tx.send(()).unwrap();
73
74 assert_ready_ok!(fut.poll()).unwrap();
75 }
76
77 #[tokio::test]
very_large_timeout()78 async fn very_large_timeout() {
79 time::pause();
80
81 // Not yet complete
82 let (tx, rx) = oneshot::channel();
83
84 // copy-paste unstable `Duration::MAX`
85 let duration_max = Duration::from_secs(u64::MAX) + Duration::from_nanos(999_999_999);
86
87 // Wrap it with a deadline
88 let mut fut = task::spawn(timeout(duration_max, rx));
89
90 // Ready!
91 assert_pending!(fut.poll());
92
93 // Turn the timer, it runs for the elapsed time
94 time::advance(Duration::from_secs(86400 * 365 * 10)).await;
95
96 assert_pending!(fut.poll());
97
98 // Complete the future
99 tx.send(()).unwrap();
100
101 assert_ready_ok!(fut.poll()).unwrap();
102 }
103
104 #[tokio::test]
deadline_now_elapses()105 async fn deadline_now_elapses() {
106 use futures::future::pending;
107
108 time::pause();
109
110 // Wrap it with a deadline
111 let mut fut = task::spawn(timeout_at(Instant::now(), pending::<()>()));
112
113 // Factor in jitter
114 // TODO: don't require this
115 time::advance(ms(1)).await;
116
117 assert_ready_err!(fut.poll());
118 }
119
120 #[tokio::test]
deadline_future_elapses()121 async fn deadline_future_elapses() {
122 time::pause();
123
124 // Wrap it with a deadline
125 let mut fut = task::spawn(timeout_at(Instant::now() + ms(300), pending::<()>()));
126
127 assert_pending!(fut.poll());
128
129 time::advance(ms(301)).await;
130
131 assert!(fut.is_woken());
132 assert_ready_err!(fut.poll());
133 }
134
ms(n: u64) -> Duration135 fn ms(n: u64) -> Duration {
136 Duration::from_millis(n)
137 }
138