diff --git a/crates/ssh-console-mock-api-server/src/lib.rs b/crates/ssh-console-mock-api-server/src/lib.rs index 6291f45968..278243ba23 100644 --- a/crates/ssh-console-mock-api-server/src/lib.rs +++ b/crates/ssh-console-mock-api-server/src/lib.rs @@ -25,6 +25,7 @@ use std::sync::Arc; use api_test_helper::utils::LOCALHOST_CERTS; use tokio::net::TcpListener; use tokio::sync::oneshot; +use tonic::transport::server::TcpIncoming; use tonic::transport::{Identity, Server, ServerTlsConfig}; use uuid::Uuid; @@ -96,14 +97,14 @@ impl MockApiServer { }) .ok(); // if something else is already default, ignore. - let addr = { - // Pick an open port - let l = TcpListener::bind("127.0.0.1:0").await?; - l.local_addr()? - .to_socket_addrs()? - .next() - .expect("No socket available") - }; + // Serve on the listener we just bound, so its port is held continuously and no other + // concurrent test can claim it before the server starts accepting. + let listener = TcpListener::bind("127.0.0.1:0").await?; + let addr = listener + .local_addr()? + .to_socket_addrs()? + .next() + .expect("No socket available"); println!("Mock gRPC server listening on {addr}"); @@ -113,7 +114,7 @@ impl MockApiServer { Server::builder() .tls_config(tls)? .add_service(ForgeServer::new(self)) - .serve_with_shutdown(addr, async move { + .serve_with_incoming_shutdown(TcpIncoming::from(listener), async move { shutdown_rx.await.ok(); }), );