next-dev test runner: ask os for free port (vercel/turbo#238)

These integration tests have been flaky, failing when a "free" port turns out to be in use. Since nextest parallelizes test runs and portpicker guesses and checks free ports [0], I'm guessing that there's a collision occurring. 

Instead, ask the operating system for a free port by binding to port 0 and read the port back from the resulting address.

Test Plan: Tried local runs with nextest, but those succeeded before as well. I'll probably retry things on CI a few times.

[0] 912f913ac3/src/lib.rs (L53)
This commit is contained in:
Will Binns-Smith 2022-08-12 14:21:21 -07:00 committed by GitHub
parent c2fb81dd37
commit 935e46f995
2 changed files with 10 additions and 4 deletions

View file

@ -45,7 +45,6 @@ chromiumoxide = { version = "0.3.5", features = [
"tokio-runtime",
], default-features = false }
lazy_static = "1.4.0"
portpicker = "0.1.1"
test-generator = "0.3.0"
[build-dependencies]

View file

@ -12,7 +12,7 @@ use lazy_static::lazy_static;
use next_dev::{register, NextDevServerBuilder};
use serde::Deserialize;
use test_generator::test_resources;
use tokio::task::JoinHandle;
use tokio::{net::TcpSocket, task::JoinHandle};
use tungstenite::{error::ProtocolError::ResetWithoutClosingHandshake, Error::Protocol};
use turbo_tasks::TurboTasks;
use turbo_tasks_memory::MemoryBackend;
@ -116,6 +116,7 @@ async fn run_test(resource: &str) -> JestRunResult {
test_entry.to_str().unwrap()
);
let requested_addr = get_free_local_addr().unwrap();
let server = NextDevServerBuilder::new()
.turbo_tasks(TurboTasks::new(MemoryBackend::new()))
.project_dir("tests".into())
@ -129,8 +130,8 @@ async fn run_test(resource: &str) -> JestRunResult {
.replace('\\', "/"),
)
.eager_compile(false)
.hostname("127.0.0.1".parse().unwrap())
.port(portpicker::pick_unused_port().unwrap())
.hostname(requested_addr.ip())
.port(requested_addr.port())
.build()
.await
.unwrap();
@ -201,3 +202,9 @@ async fn run_test_browser(addr: SocketAddr) -> Result<JestRunResult, Box<dyn std
Ok(page.evaluate("__jest__.run()").await?.into_value()?)
}
fn get_free_local_addr() -> Result<SocketAddr, std::io::Error> {
let socket = TcpSocket::new_v4()?;
socket.bind("127.0.0.1:0".parse().unwrap())?;
socket.local_addr()
}