Refactor port number generation in tests for improved reliability

- Replaced the static port number generation with a method that binds a temporary TcpListener to an ephemeral port assigned by the OS, enhancing the reliability of port allocation during tests.
- Updated documentation to clarify the new approach for obtaining a free port, ensuring better understanding and maintainability of the test code.
This commit is contained in:
Joe 2026-02-06 12:24:50 -06:00
parent acb3b18fa1
commit 84771840e1

View file

@ -4,7 +4,6 @@ use std::{
io::Read as _, io::Read as _,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{Command, Stdio}, process::{Command, Stdio},
sync::atomic::{AtomicUsize, Ordering},
thread, thread,
time::Duration, time::Duration,
}; };
@ -319,16 +318,17 @@ fn deserialize_msgpack<'a, T: Deserialize<'a>>(
T::deserialize(&mut deserializer) T::deserialize(&mut deserializer)
} }
/// Probably-okay way to generate random enough port numbers for running the /// Obtain a free port by asking the OS to assign an ephemeral one.
/// Rojo live server.
/// ///
/// If this method ends up having problems, we should add an option for Rojo to /// Binds a temporary TcpListener to port 0 (the OS picks a free port),
/// use a random port chosen by the operating system and figure out a good way /// reads back the assigned port, then drops the listener. The brief
/// to get that port back to the test CLI. /// TOCTOU window before Rojo rebinds is negligible on localhost.
fn get_port_number() -> usize { fn get_port_number() -> usize {
static NEXT_PORT_NUMBER: AtomicUsize = AtomicUsize::new(35103); let listener = std::net::TcpListener::bind("127.0.0.1:0")
.expect("Failed to bind ephemeral port for test");
NEXT_PORT_NUMBER.fetch_add(1, Ordering::SeqCst) let port = listener.local_addr().unwrap().port() as usize;
drop(listener);
port
} }
/// Takes a SerializeResponse and creates an XML model out of the response. /// Takes a SerializeResponse and creates an XML model out of the response.