Restart WebDriver on failure (#4267)

This commit is contained in:
daxpedda 2024-11-14 09:45:18 +01:00 committed by GitHub
parent 03207b3bc0
commit 539ea4323c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 24 deletions

View File

@ -43,6 +43,9 @@
* Deprecate `--reference-types` in favor of automatic target feature detection.
[#4237](https://github.com/rustwasm/wasm-bindgen/pull/4237)
* `wasm-bindgen-test-runner` now tries to restart the WebDriver on failure, instead of spending its timeout period trying to connect to a non-existing WebDriver.
[#4267](https://github.com/rustwasm/wasm-bindgen/pull/4267)
### Fixed
* Fixed methods with `self: &Self` consuming the object.

View File

@ -61,36 +61,49 @@ pub fn run(server: &SocketAddr, shell: &Shell, timeout: u64) -> Result<(), Error
let driver_url = match driver.location() {
Locate::Remote(url) => Ok(url.clone()),
Locate::Local((path, args)) => {
// Allow tests to run in parallel (in theory) by finding any open port
// available for our driver. We can't bind the port for the driver, but
// hopefully the OS gives this invocation unique ports across processes
let driver_addr = TcpListener::bind("127.0.0.1:0")?.local_addr()?;
// Wait for the driver to come online and bind its port before we try to
// connect to it.
let start = Instant::now();
let max = Duration::new(5, 0);
let (driver_addr, mut child) = 'outer: loop {
// Allow tests to run in parallel (in theory) by finding any open port
// available for our driver. We can't bind the port for the driver, but
// hopefully the OS gives this invocation unique ports across processes
let driver_addr = TcpListener::bind("127.0.0.1:0")?.local_addr()?;
// Spawn the driver binary, collecting its stdout/stderr in separate
// threads. We'll print this output later.
let mut cmd = Command::new(path);
cmd.args(args).arg(format!("--port={}", driver_addr.port()));
let mut child = BackgroundChild::spawn(path, &mut cmd, shell)?;
// Wait for the driver to come online and bind its port before we try to
// connect to it.
loop {
if child.has_failed() {
if start.elapsed() >= max {
bail!("driver failed to start")
}
println!("Failed to start driver, trying again ...");
thread::sleep(Duration::from_millis(100));
break;
} else if TcpStream::connect(driver_addr).is_ok() {
break 'outer (driver_addr, child);
} else if start.elapsed() >= max {
bail!("driver failed to bind port during startup")
} else {
thread::sleep(Duration::from_millis(100));
}
}
};
// Spawn the driver binary, collecting its stdout/stderr in separate
// threads. We'll print this output later.
let mut cmd = Command::new(path);
cmd.args(args).arg(format!("--port={}", driver_addr.port()));
let mut child = BackgroundChild::spawn(path, &mut cmd, shell)?;
drop_log = Box::new(move || {
let _ = &child;
child.print_stdio_on_drop = false;
});
// Wait for the driver to come online and bind its port before we try to
// connect to it.
let start = Instant::now();
let max = Duration::new(5, 0);
let mut bound = false;
while start.elapsed() < max {
if TcpStream::connect(driver_addr).is_ok() {
bound = true;
break;
}
thread::sleep(Duration::from_millis(100));
}
if !bound {
bail!("driver failed to bind port during startup")
}
Url::parse(&format!("http://{}", driver_addr)).map_err(Error::from)
}
}?;
@ -646,6 +659,14 @@ impl<'a> BackgroundChild<'a> {
print_stdio_on_drop: true,
})
}
fn has_failed(&mut self) -> bool {
match self.child.try_wait() {
Ok(Some(status)) => !status.success(),
Ok(None) => false,
Err(_) => true,
}
}
}
impl<'a> Drop for BackgroundChild<'a> {