the port-bind test no longer loses its released port to other sockets
This commit is contained in:
parent
daf38e4c55
commit
c6d26a0904
1 changed files with 19 additions and 2 deletions
|
|
@ -486,10 +486,27 @@ mod tests {
|
|||
use crate::events::Bus;
|
||||
use crate::login::LoginState;
|
||||
|
||||
/// A port another listener holds for a moment is waited out.
|
||||
/// Hold a loopback port just below the kernel's ephemeral range. Once the
|
||||
/// holder drops, nothing that binds `:0` or connects outward can take the
|
||||
/// port, and the pid offset keeps concurrent test processes apart.
|
||||
fn hold_port_below_ephemeral_range() -> tokio::net::TcpListener {
|
||||
let low = std::fs::read_to_string("/proc/sys/net/ipv4/ip_local_port_range")
|
||||
.ok()
|
||||
.and_then(|s| s.split_whitespace().next()?.parse::<u16>().ok())
|
||||
.unwrap_or(32768);
|
||||
let start = low.saturating_sub(1 + (std::process::id() % 2000) as u16);
|
||||
(1024..=start)
|
||||
.rev()
|
||||
.find_map(|port| try_bind(([127, 0, 0, 1], port).into()).ok())
|
||||
.expect("a free port below the ephemeral range")
|
||||
}
|
||||
|
||||
/// A port another listener holds for a moment is waited out. The paused
|
||||
/// clock runs all retries in microseconds of real time, so the port must
|
||||
/// not be one the kernel hands to other sockets once released.
|
||||
#[tokio::test(start_paused = true)]
|
||||
async fn bind_waits_out_a_port_that_is_briefly_held() {
|
||||
let holder = try_bind("127.0.0.1:0".parse().expect("addr")).expect("holder");
|
||||
let holder = hold_port_below_ephemeral_range();
|
||||
let addr = holder.local_addr().expect("local addr");
|
||||
let release = tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
|
|
|
|||
Loading…
Reference in a new issue