diff --git a/examples/server.rs b/examples/server.rs index 52372b6..5cf16ec 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -56,10 +56,11 @@ async fn run_server() -> Result<(), Box> { let key = PrivateKeyDer::from_pem_file("examples/sample.rsa") .map_err(|e| error(format!("could not read private key file: {e}")))?; - println!("Starting to serve on https://{addr}"); - // Create a TCP listener via tokio. let incoming = TcpListener::bind(&addr).await?; + let addr = incoming.local_addr()?; + + println!("Starting to serve on https://{addr}"); // Build TLS configuration. let mut server_config = ServerConfig::builder() diff --git a/tests/tests.rs b/tests/tests.rs index 9e59038..fbd21f4 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,9 +1,8 @@ use std::env; -use std::net::TcpStream; +use std::io::{BufRead, BufReader}; +use std::net::SocketAddr; use std::path::PathBuf; -use std::process::Command; -use std::thread; -use std::time; +use std::process::{Child, Command, Stdio}; fn examples_dir() -> PathBuf { let target_dir: PathBuf = env::var("CARGO_TARGET_DIR") @@ -18,18 +17,37 @@ fn server_command() -> Command { Command::new(examples_dir().join("server")) } -fn client_command() -> Command { - Command::new(examples_dir().join("client")) +fn start_server() -> (Child, SocketAddr) { + let mut srv = server_command() + .arg("0") + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .expect("cannot run server example"); + + let stdout = srv + .stdout + .take() + .expect("failed to get stdout"); + + let mut reader = BufReader::new(stdout); + let mut line = String::new(); + reader + .read_line(&mut line) + .expect("failed to read line"); + + let addr = line + .trim() + .strip_prefix("Starting to serve on https://") + .expect("unexpected output") + .parse() + .expect("failed to parse socket address"); + + (srv, addr) } -fn wait_for_server(addr: &str) { - for i in 0..10 { - if TcpStream::connect(addr).is_ok() { - return; - } - thread::sleep(time::Duration::from_millis(i * 100)); - } - panic!("failed to connect to {addr:?} after 10 tries"); +fn client_command() -> Command { + Command::new(examples_dir().join("client")) } #[test] @@ -39,23 +57,21 @@ fn client() { .output() .expect("cannot run client example"); - assert!(rc.status.success()); + if !rc.status.success() { + assert_eq!(String::from_utf8_lossy(&rc.stdout), ""); + assert_eq!(String::from_utf8_lossy(&rc.stderr), ""); + panic!("test failed"); + } } #[test] fn server() { - let mut srv = server_command() - .arg("1337") - .spawn() - .expect("cannot run server example"); - - let addr = "localhost:1337"; - wait_for_server(addr); + let (mut srv, addr) = start_server(); let output = Command::new("curl") .arg("--insecure") .arg("--http1.0") - .arg(format!("https://{addr}")) + .arg(format!("https://localhost:{}", addr.port())) .output() .expect("cannot run curl"); @@ -78,16 +94,10 @@ fn server() { #[test] fn custom_ca_store() { - let mut srv = server_command() - .arg("1338") - .spawn() - .expect("cannot run server example"); - - let addr = "localhost:1338"; - wait_for_server(addr); + let (mut srv, addr) = start_server(); let rc = client_command() - .arg(format!("https://{addr}")) + .arg(format!("https://localhost:{}", addr.port())) .arg("examples/sample.pem") .output() .expect("cannot run client example"); @@ -98,5 +108,7 @@ fn custom_ca_store() { if !rc.status.success() { assert_eq!(String::from_utf8_lossy(&rc.stdout), ""); + assert_eq!(String::from_utf8_lossy(&rc.stderr), ""); + panic!("test failed"); } }