Keep reading buffered test process output after it has exited (#2923)

This commit is contained in:
teor 2021-10-21 11:40:39 +10:00 committed by GitHub
parent 595d75d5fb
commit 3db5ecb80e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 14 additions and 6 deletions

View File

@ -8,11 +8,11 @@ use tracing::instrument;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
use std::{
convert::Infallible as NoDir,
fmt::{self, Write as _},
io::BufRead,
io::{BufReader, Lines, Read},
io::{BufRead, BufReader, Lines, Read, Write as _},
path::Path,
process::{Child, ChildStderr, ChildStdout, Command, ExitStatus, Output, Stdio},
time::{Duration, Instant},
@ -286,10 +286,17 @@ impl<T> TestChild<T> {
L: Iterator<Item = std::io::Result<String>>,
{
let re = regex::Regex::new(regex).expect("regex must be valid");
while !self.past_deadline() && self.is_running() {
// We don't check `is_running` here,
// because we want to read to the end of the buffered output,
// even if the child process has exited.
while !self.past_deadline() {
let line = if let Some(line) = lines.next() {
line?
} else {
// When the child process closes its output,
// and we've read all of the buffered output,
// stop checking for any more output.
break;
};
@ -297,14 +304,15 @@ impl<T> TestChild<T> {
// can be preserved. May cause weird reordering for stdout / stderr.
// Uses stdout even if the original lines were from stderr.
if self.bypass_test_capture {
// send lines to the terminal (or process stdout file redirect)
use std::io::Write;
// Send lines directly to the terminal (or process stdout file redirect).
#[allow(clippy::explicit_write)]
writeln!(std::io::stdout(), "{}", line).unwrap();
} else {
// if the test fails, the test runner captures and displays it
// If the test fails, the test runner captures and displays this output.
println!("{}", line);
}
// Some OSes require a flush to send all output to the terminal.
std::io::stdout().lock().flush()?;
if re.is_match(&line) {
return Ok(());