Skip to content

Commit e401c07

Browse files
alexcrichtonbongjunj
authored andcommitted
wasip3: Add a test cancelling TCP reads (bytecodealliance#11623)
* wasip3: Add a test cancelling TCP reads This commit adds a test where a stream of data is being sent over TCP and the read side reads as much as it can and then cancels any read that shows up pending. It then waits for readiness via a 0-length read and retries again. The test is intended to assert that the number of consecutive zero-length reads reported is capped at some small number (e.g. this shouldn't infinite loop). * Fix lint
1 parent 094f5e8 commit e401c07

File tree

4 files changed

+109
-10
lines changed

4 files changed

+109
-10
lines changed

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,8 @@ io-lifetimes = { version = "2.0.3", default-features = false }
325325
io-extras = "0.18.1"
326326
rustix = "1.0.3"
327327
# wit-bindgen:
328-
wit-bindgen = { version = "0.45.0", default-features = false }
329-
wit-bindgen-rust-macro = { version = "0.45.0", default-features = false }
328+
wit-bindgen = { version = "0.45.1", default-features = false }
329+
wit-bindgen-rust-macro = { version = "0.45.1", default-features = false }
330330

331331
# wasm-tools family:
332332
wasmparser = { version = "0.238.1", default-features = false, features = ['simd'] }

crates/test-programs/src/bin/p3_sockets_tcp_streams.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use futures::join;
2+
use std::pin::pin;
3+
use std::task::{Context, Poll, Waker};
24
use test_programs::p3::wasi::sockets::types::{
35
IpAddress, IpAddressFamily, IpSocketAddress, TcpSocket,
46
};
57
use test_programs::p3::wit_stream;
8+
use wit_bindgen::StreamResult;
69

710
struct Component;
811

@@ -109,6 +112,76 @@ async fn test_tcp_shutdown_should_not_lose_data(family: IpAddressFamily) {
109112
.await;
110113
}
111114

115+
/// Model a situation where there's a continuous stream of data coming into the
116+
/// guest from one side and the other side is reading in chunks but also
117+
/// cancelling reads occasionally. Should receive the complete stream of data
118+
/// into the result.
119+
async fn test_tcp_read_cancellation(family: IpAddressFamily) {
120+
// Send 2M of data in 256-byte chunks.
121+
const CHUNKS: usize = (2 << 20) / 256;
122+
let mut data = [0; 256];
123+
for (i, slot) in data.iter_mut().enumerate() {
124+
*slot = i as u8;
125+
}
126+
127+
setup(family, |server, client| async move {
128+
// Minimize the local send buffer:
129+
client.set_send_buffer_size(1024).unwrap();
130+
131+
let (mut client_tx, client_rx) = wit_stream::new();
132+
join!(
133+
async {
134+
client.send(client_rx).await.unwrap();
135+
},
136+
async {
137+
for _ in 0..CHUNKS {
138+
let ret = client_tx.write_all(data.to_vec()).await;
139+
assert!(ret.is_empty());
140+
}
141+
drop(client_tx);
142+
},
143+
async {
144+
let mut buf = Vec::with_capacity(1024);
145+
let (mut server_rx, server_fut) = server.receive();
146+
let mut i = 0_usize;
147+
let mut consecutive_zero_length_reads = 0;
148+
loop {
149+
assert!(buf.is_empty());
150+
let (status, b) = {
151+
let mut fut = pin!(server_rx.read(buf));
152+
let mut cx = Context::from_waker(Waker::noop());
153+
match fut.as_mut().poll(&mut cx) {
154+
Poll::Ready(pair) => pair,
155+
Poll::Pending => fut.cancel(),
156+
}
157+
};
158+
buf = b;
159+
match status {
160+
StreamResult::Complete(n) => {
161+
assert_eq!(buf.len(), n);
162+
for slot in buf.iter_mut() {
163+
assert_eq!(*slot, i as u8);
164+
i = i.wrapping_add(1);
165+
}
166+
buf.truncate(0);
167+
consecutive_zero_length_reads = 0;
168+
}
169+
StreamResult::Dropped => break,
170+
StreamResult::Cancelled => {
171+
assert!(consecutive_zero_length_reads < 10);
172+
consecutive_zero_length_reads += 1;
173+
server_rx.read(Vec::new()).await;
174+
}
175+
}
176+
}
177+
assert_eq!(i, CHUNKS * 256);
178+
server_fut.await.unwrap();
179+
},
180+
);
181+
})
182+
.await;
183+
}
184+
112185
impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
113186
async fn run() -> Result<(), ()> {
114187
test_tcp_input_stream_should_be_closed_by_remote_shutdown(IpAddressFamily::Ipv4).await;
@@ -122,6 +195,8 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
122195

123196
test_tcp_shutdown_should_not_lose_data(IpAddressFamily::Ipv4).await;
124197
test_tcp_shutdown_should_not_lose_data(IpAddressFamily::Ipv6).await;
198+
199+
test_tcp_read_cancellation(IpAddressFamily::Ipv4).await;
125200
Ok(())
126201
}
127202
}

supply-chain/audits.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4753,6 +4753,12 @@ criteria = "safe-to-deploy"
47534753
delta = "0.43.0 -> 0.45.0"
47544754
notes = "The Bytecode Alliance is the author of this crate"
47554755

4756+
[[audits.wit-bindgen]]
4757+
who = "Alex Crichton <[email protected]>"
4758+
criteria = "safe-to-deploy"
4759+
delta = "0.45.0 -> 0.45.1"
4760+
notes = "The Bytecode Alliance is the author of this crate"
4761+
47564762
[[audits.wit-bindgen-core]]
47574763
who = "Joel Dice <[email protected]>"
47584764
criteria = "safe-to-run"
@@ -4764,6 +4770,12 @@ criteria = "safe-to-deploy"
47644770
delta = "0.43.0 -> 0.45.0"
47654771
notes = "The Bytecode Alliance is the author of this crate"
47664772

4773+
[[audits.wit-bindgen-core]]
4774+
who = "Alex Crichton <[email protected]>"
4775+
criteria = "safe-to-deploy"
4776+
delta = "0.45.0 -> 0.45.1"
4777+
notes = "The Bytecode Alliance is the author of this crate"
4778+
47674779
[[audits.wit-bindgen-rt]]
47684780
who = "Joel Dice <[email protected]>"
47694781
criteria = "safe-to-run"
@@ -4780,6 +4792,12 @@ criteria = "safe-to-deploy"
47804792
delta = "0.43.0 -> 0.45.0"
47814793
notes = "The Bytecode Alliance is the author of this crate"
47824794

4795+
[[audits.wit-bindgen-rust]]
4796+
who = "Alex Crichton <[email protected]>"
4797+
criteria = "safe-to-deploy"
4798+
delta = "0.45.0 -> 0.45.1"
4799+
notes = "The Bytecode Alliance is the author of this crate"
4800+
47834801
[[audits.wit-bindgen-rust-macro]]
47844802
who = "Joel Dice <[email protected]>"
47854803
criteria = "safe-to-run"
@@ -4791,6 +4809,12 @@ criteria = "safe-to-deploy"
47914809
delta = "0.43.0 -> 0.45.0"
47924810
notes = "The Bytecode Alliance is the author of this crate"
47934811

4812+
[[audits.wit-bindgen-rust-macro]]
4813+
who = "Alex Crichton <[email protected]>"
4814+
criteria = "safe-to-deploy"
4815+
delta = "0.45.0 -> 0.45.1"
4816+
notes = "The Bytecode Alliance is the author of this crate"
4817+
47944818
[[audits.wit-component]]
47954819
who = "Alex Crichton <[email protected]>"
47964820
criteria = "safe-to-deploy"

0 commit comments

Comments
 (0)