Skip to content

Commit b068c07

Browse files
committed
Use deterministic port allocation in integration tests
Replace the bind-to-port-0-then-drop pattern in test port allocation with an atomic counter starting at port 20000. The previous approach had a TOCTOU race: the OS-assigned port was released when the probe socket was dropped, allowing another test's node to grab it before Node::start() could re-bind, causing sporadic InvalidSocketAddress failures in CI. An atomic counter guarantees unique ports across all parallel tests within the process and is stable across node restarts. AI tools were used in preparing this commit.
1 parent a555133 commit b068c07

File tree

1 file changed

+8
-10
lines changed

1 file changed

+8
-10
lines changed

tests/common/mod.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::collections::{HashMap, HashSet};
1414
use std::env;
1515
use std::future::Future;
1616
use std::path::PathBuf;
17+
use std::sync::atomic::{AtomicU16, Ordering};
1718
use std::sync::{Arc, RwLock};
1819
use std::time::Duration;
1920

@@ -268,17 +269,14 @@ pub(crate) fn random_storage_path() -> PathBuf {
268269
temp_path
269270
}
270271

271-
pub(crate) fn random_listening_addresses() -> Vec<SocketAddress> {
272-
let num_addresses = 2;
273-
let mut listening_addresses = HashSet::new();
274-
275-
while listening_addresses.len() < num_addresses {
276-
let socket = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
277-
let address: SocketAddress = socket.local_addr().unwrap().into();
278-
listening_addresses.insert(address);
279-
}
272+
static NEXT_PORT: AtomicU16 = AtomicU16::new(20000);
280273

281-
listening_addresses.into_iter().collect()
274+
pub(crate) fn random_listening_addresses() -> Vec<SocketAddress> {
275+
let port = NEXT_PORT.fetch_add(2, Ordering::Relaxed);
276+
vec![
277+
SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port },
278+
SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: port + 1 },
279+
]
282280
}
283281

284282
pub(crate) fn random_node_alias() -> Option<NodeAlias> {

0 commit comments

Comments
 (0)