diff --git a/examples/tcp_stream_client.rs b/examples/tcp_stream_client.rs new file mode 100644 index 0000000..2e93faf --- /dev/null +++ b/examples/tcp_stream_client.rs @@ -0,0 +1,25 @@ +use wstd::io::{self, AsyncRead, AsyncWrite}; +use wstd::net::TcpStream; + +#[wstd::main] +async fn main() -> io::Result<()> { + let mut args = std::env::args(); + + let _ = args.next(); + + let addr = args.next().ok_or_else(|| { + io::Error::new( + std::io::ErrorKind::InvalidInput, + "address argument required", + ) + })?; + + let mut stream = TcpStream::connect(addr).await?; + + stream.write_all(b"ping\n").await?; + + let mut reply = Vec::new(); + stream.read_to_end(&mut reply).await?; + + Ok(()) +} diff --git a/test-programs/tests/tcp_stream_client.rs b/test-programs/tests/tcp_stream_client.rs new file mode 100644 index 0000000..f3a87d6 --- /dev/null +++ b/test-programs/tests/tcp_stream_client.rs @@ -0,0 +1,53 @@ +use anyhow::{Context, Result}; +use std::net::{Shutdown, TcpListener}; +use std::process::{Command, Stdio}; + +#[test_log::test] +fn tcp_stream_client() -> Result<()> { + use std::io::{Read, Write}; + + let server = TcpListener::bind("127.0.0.1:8082").context("binding temporary test server")?; + let addr = server + .local_addr() + .context("getting local listener address")?; + + let child = Command::new("wasmtime") + .arg("run") + .arg("-Sinherit-network") + .arg(test_programs::TCP_STREAM_CLIENT) + .arg(addr.to_string()) + .stdout(Stdio::piped()) + .spawn() + .context("spawning wasmtime component")?; + + let (mut server_stream, _addr) = server + .accept() + .context("accepting TCP connection from component")?; + + let mut buf = [0u8; 5]; + server_stream + .read_exact(&mut buf) + .context("reading ping message")?; + assert_eq!(&buf, b"ping\n", "expected ping from component"); + + server_stream + .write_all(b"pong\n") + .context("writing reply")?; + server_stream.flush().context("flushing")?; + + server_stream + .shutdown(Shutdown::Both) + .context("shutting down connection")?; + + let output = child + .wait_with_output() + .context("waiting for component exit")?; + + assert!( + output.status.success(), + "\nComponent exited abnormally (stderr:\n{})", + String::from_utf8_lossy(&output.stderr) + ); + + Ok(()) +}