Skip to content

Commit ee1d20c

Browse files
committed
Add tests
1 parent e125a92 commit ee1d20c

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

tests/block_on.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
use async_io::block_on;
2+
use std::{
3+
future::Future,
4+
pin::Pin,
5+
task::{Context, Poll, Waker},
6+
time::{Duration, Instant},
7+
};
8+
9+
#[test]
10+
fn doesnt_poll_after_ready() {
11+
#[derive(Default)]
12+
struct Bomb {
13+
returned_ready: bool,
14+
}
15+
impl Future for Bomb {
16+
type Output = ();
17+
18+
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
19+
if self.returned_ready {
20+
panic!("Future was polled again after returning Poll::Ready");
21+
} else {
22+
self.returned_ready = true;
23+
Poll::Ready(())
24+
}
25+
}
26+
}
27+
28+
block_on(Bomb::default())
29+
}
30+
31+
#[test]
32+
fn recursive_wakers_are_different() {
33+
struct Outer;
34+
impl Future for Outer {
35+
type Output = ();
36+
37+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
38+
let outer_waker = cx.waker();
39+
block_on(Inner { outer_waker });
40+
Poll::Ready(())
41+
}
42+
}
43+
44+
struct Inner<'a> {
45+
pub outer_waker: &'a Waker,
46+
}
47+
impl Future for Inner<'_> {
48+
type Output = ();
49+
50+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
51+
let inner_waker = cx.waker();
52+
assert!(!inner_waker.will_wake(self.outer_waker));
53+
Poll::Ready(())
54+
}
55+
}
56+
57+
block_on(Outer);
58+
}
59+
60+
#[test]
61+
fn inner_cannot_wake_outer() {
62+
#[derive(Default)]
63+
struct Outer {
64+
elapsed: Option<Instant>,
65+
}
66+
impl Future for Outer {
67+
type Output = ();
68+
69+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
70+
if let Some(elapsed) = self.elapsed {
71+
assert!(elapsed.elapsed() >= Duration::from_secs(1));
72+
Poll::Ready(())
73+
} else {
74+
let outer_waker = cx.waker().clone();
75+
block_on(Inner);
76+
std::thread::spawn(|| {
77+
std::thread::sleep(Duration::from_secs(1));
78+
outer_waker.wake();
79+
});
80+
self.elapsed = Some(Instant::now());
81+
Poll::Pending
82+
}
83+
}
84+
}
85+
86+
struct Inner;
87+
impl Future for Inner {
88+
type Output = ();
89+
90+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
91+
let inner_waker = cx.waker();
92+
inner_waker.wake_by_ref();
93+
Poll::Ready(())
94+
}
95+
}
96+
97+
block_on(Outer::default());
98+
}
99+
100+
#[test]
101+
fn outer_cannot_wake_inner() {
102+
struct Outer;
103+
impl Future for Outer {
104+
type Output = ();
105+
106+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
107+
let outer_waker = cx.waker();
108+
outer_waker.wake_by_ref();
109+
block_on(Inner::default());
110+
Poll::Ready(())
111+
}
112+
}
113+
114+
#[derive(Default)]
115+
struct Inner {
116+
elapsed: Option<Instant>,
117+
}
118+
impl Future for Inner {
119+
type Output = ();
120+
121+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
122+
if let Some(elapsed) = self.elapsed {
123+
assert!(elapsed.elapsed() >= Duration::from_secs(1));
124+
Poll::Ready(())
125+
} else {
126+
let inner_waker = cx.waker().clone();
127+
std::thread::spawn(|| {
128+
std::thread::sleep(Duration::from_secs(1));
129+
inner_waker.wake();
130+
});
131+
self.elapsed = Some(Instant::now());
132+
Poll::Pending
133+
}
134+
}
135+
}
136+
137+
block_on(Outer);
138+
}
139+
140+
#[test]
141+
fn first_cannot_wake_second() {
142+
struct First;
143+
impl Future for First {
144+
type Output = ();
145+
146+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
147+
let first_waker = cx.waker();
148+
first_waker.wake_by_ref();
149+
Poll::Ready(())
150+
}
151+
}
152+
153+
#[derive(Default)]
154+
struct Second {
155+
elapsed: Option<Instant>,
156+
}
157+
impl Future for Second {
158+
type Output = ();
159+
160+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
161+
if let Some(elapsed) = self.elapsed {
162+
assert!(elapsed.elapsed() >= Duration::from_secs(1));
163+
Poll::Ready(())
164+
} else {
165+
let second_waker = cx.waker().clone();
166+
std::thread::spawn(|| {
167+
std::thread::sleep(Duration::from_secs(1));
168+
second_waker.wake();
169+
});
170+
self.elapsed = Some(Instant::now());
171+
Poll::Pending
172+
}
173+
}
174+
}
175+
176+
block_on(First);
177+
block_on(Second::default());
178+
}

0 commit comments

Comments
 (0)