Skip to content

Commit 37f0aa1

Browse files
authored
Better handle stuck WebDriver processes (#4350)
1 parent 237babb commit 37f0aa1

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
* Adding `getter`, `setter`, and `constructor` methods to enums now results in a compiler error. This was previously erroneously allowed and resulted in invalid JS code gen.
2323
[#4278](https://github.com/rustwasm/wasm-bindgen/pull/4278)
2424

25+
* Handle stuck and failed WebDriver processes when re-trying to start them.
26+
[#4340](https://github.com/rustwasm/wasm-bindgen/pull/4340)
27+
2528
### Fixed
2629

2730
- Fixed using [JavaScript keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) as identifiers not being handled correctly.

crates/cli/src/bin/wasm-bindgen-test-runner/headless.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ use serde::{Deserialize, Serialize};
66
use serde_json::{json, Map, Value as Json};
77
use std::env;
88
use std::fs::File;
9-
use std::io::{self, Read};
9+
use std::io::{self, Cursor, ErrorKind, Read, Write};
1010
use std::net::{SocketAddr, TcpListener, TcpStream};
1111
use std::path::{Path, PathBuf};
1212
use std::process::{Child, Command, Stdio};
13+
use std::sync::atomic::{AtomicBool, Ordering};
14+
use std::sync::Arc;
1315
use std::thread;
1416
use std::time::{Duration, Instant};
1517
use ureq::Agent;
@@ -615,12 +617,6 @@ impl Drop for Client {
615617
}
616618
}
617619

618-
fn read<R: Read>(r: &mut R) -> io::Result<Vec<u8>> {
619-
let mut dst = Vec::new();
620-
r.read_to_end(&mut dst)?;
621-
Ok(dst)
622-
}
623-
624620
fn tab(s: &str) -> String {
625621
let mut result = String::new();
626622
for line in s.lines() {
@@ -635,6 +631,7 @@ struct BackgroundChild<'a> {
635631
child: Child,
636632
stdout: Option<thread::JoinHandle<io::Result<Vec<u8>>>>,
637633
stderr: Option<thread::JoinHandle<io::Result<Vec<u8>>>>,
634+
any_stderr: Arc<AtomicBool>,
638635
shell: &'a Shell,
639636
print_stdio_on_drop: bool,
640637
}
@@ -654,12 +651,36 @@ impl<'a> BackgroundChild<'a> {
654651
.context(format!("failed to spawn {:?} binary", path))?;
655652
let mut stdout = child.stdout.take().unwrap();
656653
let mut stderr = child.stderr.take().unwrap();
657-
let stdout = Some(thread::spawn(move || read(&mut stdout)));
658-
let stderr = Some(thread::spawn(move || read(&mut stderr)));
654+
let stdout = Some(thread::spawn(move || {
655+
let mut dst = Vec::new();
656+
stdout.read_to_end(&mut dst)?;
657+
Ok(dst)
658+
}));
659+
let any_stderr = Arc::new(AtomicBool::new(false));
660+
let any_stderr_clone = Arc::clone(&any_stderr);
661+
let stderr = Some(thread::spawn(move || {
662+
let mut dst = Cursor::new(Vec::new());
663+
let mut buffer = [0];
664+
665+
match stderr.read_exact(&mut buffer) {
666+
Ok(()) => {
667+
dst.write_all(&buffer).unwrap();
668+
any_stderr_clone.store(true, Ordering::Relaxed);
669+
}
670+
Err(error) if error.kind() == ErrorKind::UnexpectedEof => {
671+
return Ok(dst.into_inner())
672+
}
673+
Err(error) => return Err(error),
674+
}
675+
676+
io::copy(&mut stderr, &mut dst)?;
677+
Ok(dst.into_inner())
678+
}));
659679
Ok(BackgroundChild {
660680
child,
661681
stdout,
662682
stderr,
683+
any_stderr,
663684
shell,
664685
print_stdio_on_drop: true,
665686
})
@@ -668,7 +689,7 @@ impl<'a> BackgroundChild<'a> {
668689
fn has_failed(&mut self) -> bool {
669690
match self.child.try_wait() {
670691
Ok(Some(status)) => !status.success(),
671-
Ok(None) => false,
692+
Ok(None) => self.any_stderr.load(Ordering::Relaxed),
672693
Err(_) => true,
673694
}
674695
}

0 commit comments

Comments
 (0)