Skip to content

Commit

Permalink
Add initial implementation of combined test output
Browse files Browse the repository at this point in the history
Checkpointing so I can check Windows impl on an actual windows machine
  • Loading branch information
Jake-Shadle committed Nov 2, 2023
1 parent b697409 commit f5e3f51
Show file tree
Hide file tree
Showing 11 changed files with 505 additions and 75 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion integration-tests/tests/integration/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,10 @@ pub fn check_run_output(stderr: &[u8], relocated: bool) {

for (result, name) in expected {
let reg = make_check_result_regex(*result, name);
assert!(reg.is_match(&output), "{name}: result didn't match");
assert!(
reg.is_match(&output),
"{name}: result didn't match\n\n--- output ---\n{output}\n--- end output ---"
);
}

let summary_reg = if relocated {
Expand Down
6 changes: 5 additions & 1 deletion nextest-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ camino = { version = "1.1.6", features = ["serde1"] }
camino-tempfile = "1.0.2"
# config's "preserve_order" feature is needed for preserving the order of
# setup scripts in .config/nextest.toml.
config = { version = "0.13.3", default-features = false, features = ["toml", "preserve_order"] }
config = { version = "0.13.3", default-features = false, features = [
"toml",
"preserve_order",
] }
cargo_metadata = "0.18.1"
cfg-if = "1.0.0"
chrono = "0.4.31"
Expand Down Expand Up @@ -112,6 +115,7 @@ windows = { version = "0.48.0", features = [
"Win32_System_Console",
"Win32_System_JobObjects",
] }
windows-sys = { version = "0.48.0", features = ["Win32_System_Pipes"] }
win32job = "1.0.2"
dunce = "1.0.4"

Expand Down
1 change: 1 addition & 0 deletions nextest-runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod signal;
pub mod target_runner;
mod test_command;
pub mod test_filter;
pub mod test_output;
mod time;
#[cfg(feature = "self-update")]
pub mod update;
58 changes: 32 additions & 26 deletions nextest-runner/src/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,36 +1347,42 @@ impl<'a> TestReporterImpl<'a> {
(self.styles.fail, self.styles.fail_output)
};

if !run_status.stdout.is_empty() {
write!(writer, "\n{}", "--- ".style(header_style))?;
let out_len = self.write_attempt(run_status, header_style, writer)?;
// The width is to align test instances.
write!(
writer,
"{:width$}",
"STDOUT:".style(header_style),
width = (21 - out_len)
)?;
self.write_instance(*test_instance, writer)?;
writeln!(writer, "{}", " ---".style(header_style))?;
{
let stdout = run_status.output.stdout();
if !stdout.is_empty() {
write!(writer, "\n{}", "--- ".style(header_style))?;
let out_len = self.write_attempt(run_status, header_style, writer)?;
// The width is to align test instances.
write!(
writer,
"{:width$}",
"STDOUT:".style(header_style),
width = (21 - out_len)
)?;
self.write_instance(*test_instance, writer)?;
writeln!(writer, "{}", " ---".style(header_style))?;

self.write_test_output(&run_status.stdout, writer)?;
self.write_test_output(&stdout, writer)?;
}

Check warning on line 1366 in nextest-runner/src/reporter.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter.rs#L1366

Added line #L1366 was not covered by tests
}

if !run_status.stderr.is_empty() {
write!(writer, "\n{}", "--- ".style(header_style))?;
let out_len = self.write_attempt(run_status, header_style, writer)?;
// The width is to align test instances.
write!(
writer,
"{:width$}",
"STDERR:".style(header_style),
width = (21 - out_len)
)?;
self.write_instance(*test_instance, writer)?;
writeln!(writer, "{}", " ---".style(header_style))?;
{
let stderr = run_status.output.stderr();
if !stderr.is_empty() {
write!(writer, "\n{}", "--- ".style(header_style))?;
let out_len = self.write_attempt(run_status, header_style, writer)?;
// The width is to align test instances.
write!(
writer,
"{:width$}",
"STDERR:".style(header_style),
width = (21 - out_len)
)?;
self.write_instance(*test_instance, writer)?;
writeln!(writer, "{}", " ---".style(header_style))?;

self.write_test_output(&run_status.stderr, writer)?;
self.write_test_output(&stderr, writer)?;
}
}

writeln!(writer)
Expand Down
37 changes: 22 additions & 15 deletions nextest-runner/src/reporter/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ impl<'cfg> MetadataJunit<'cfg> {

for rerun in reruns {
let (kind, ty) = kind_ty(rerun);
let stdout = String::from_utf8_lossy(&rerun.stdout);
let stderr = String::from_utf8_lossy(&rerun.stderr);
let stdout = rerun.output.stdout_lossy();
let stderr = rerun.output.stderr_lossy();

Check warning on line 149 in nextest-runner/src/reporter/aggregator.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/aggregator.rs#L148-L149

Added lines #L148 - L149 were not covered by tests
let stack_trace = heuristic_extract_description(rerun.result, &stdout, &stderr);

let mut test_rerun = TestRerun::new(kind);
Expand Down Expand Up @@ -174,22 +174,29 @@ impl<'cfg> MetadataJunit<'cfg> {
// https://github.com/allure-framework/allure2/blob/master/plugins/junit-xml-plugin/src/main/java/io/qameta/allure/junitxml/JunitXmlPlugin.java#L192-L196
// we may have to update this format to handle that.
let is_success = main_status.result.is_success();
if !is_success {
let stdout = String::from_utf8_lossy(&main_status.stdout);
let stderr = String::from_utf8_lossy(&main_status.stderr);
let description =
heuristic_extract_description(main_status.result, &stdout, &stderr);
if let Some(description) = description {
testcase.status.set_description(description);
}
}

if (junit_store_success_output && is_success)
if !is_success
|| (junit_store_success_output && is_success)

Check warning on line 179 in nextest-runner/src/reporter/aggregator.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/aggregator.rs#L178-L179

Added lines #L178 - L179 were not covered by tests
|| (junit_store_failure_output && !is_success)
{
testcase
.set_system_out_lossy(&main_status.stdout)
.set_system_err_lossy(&main_status.stderr);
let stdout = main_status.output.stdout_lossy();
let stderr = main_status.output.stderr_lossy();

if !is_success {
let description =
heuristic_extract_description(main_status.result, &stdout, &stderr);
if let Some(description) = description {
testcase.status.set_description(description);
}
}

Check warning on line 191 in nextest-runner/src/reporter/aggregator.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/aggregator.rs#L182-L191

Added lines #L182 - L191 were not covered by tests

if (junit_store_success_output && is_success)
|| (junit_store_failure_output && !is_success)
{
testcase
.set_system_out(&stdout)
.set_system_err_lossy(&stderr);
}

Check warning on line 199 in nextest-runner/src/reporter/aggregator.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/aggregator.rs#L193-L199

Added lines #L193 - L199 were not covered by tests
}

testsuite.add_test_case(testcase);
Expand Down
13 changes: 4 additions & 9 deletions nextest-runner/src/reporter/structured/libtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ impl<'cfg> LibtestReporter<'cfg> {
match last_status.result {

Check warning on line 346 in nextest-runner/src/reporter/structured/libtest.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/structured/libtest.rs#L346

Added line #L346 was not covered by tests
ExecutionResult::Fail { .. } | ExecutionResult::ExecFail => {
test_suite.failed += 1;
let stdout = String::from_utf8_lossy(&last_status.stdout);
let stderr = String::from_utf8_lossy(&last_status.stderr);

let output = last_status.output.lossy();

// TODO: Get the combined stdout and stderr streams, in the order they
// are supposed to be, to accurately replicate libtest's output
Expand All @@ -364,13 +364,8 @@ impl<'cfg> LibtestReporter<'cfg> {
// \n\nfailures:\n\nfailures:\n <name>\n\ntest result: FAILED
// ```

write!(
out,
r#","stdout":"{}{}""#,
EscapedString(&stdout),
EscapedString(&stderr)
)
.map_err(fmt_err)?;
write!(out, r#","stdout":"{}""#, EscapedString(&output),)
.map_err(fmt_err)?;

Check warning on line 368 in nextest-runner/src/reporter/structured/libtest.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/reporter/structured/libtest.rs#L348-L368

Added lines #L348 - L368 were not covered by tests
}
ExecutionResult::Timeout => {
test_suite.failed += 1;
Expand Down
35 changes: 16 additions & 19 deletions nextest-runner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
},
signal::{JobControlEvent, ShutdownEvent, SignalEvent, SignalHandler, SignalHandlerKind},
target_runner::TargetRunner,
test_output::TestOutput,
time::{PausableSleep, StopwatchEnd, StopwatchStart},
};
use async_scoped::TokioScope;
Expand Down Expand Up @@ -906,12 +907,14 @@ impl<'a> TestRunnerInner<'a> {
Ok(run_status) => run_status,
Err(error) => {
// Put the error chain inside stderr.
let mut stderr = bytes::BytesMut::new();
writeln!(&mut stderr, "{}", DisplayErrorChain::new(error)).unwrap();
let mut acc = crate::test_output::TestOutputAccumulator::new();
{
let mut stderr = acc.stderr();
writeln!(&mut stderr, "{}", DisplayErrorChain::new(error)).unwrap();
}

Check warning on line 914 in nextest-runner/src/runner.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/runner.rs#L910-L914

Added lines #L910 - L914 were not covered by tests

InternalExecuteStatus {
stdout: Bytes::new(),
stderr: stderr.freeze(),
output: acc.freeze(),

Check warning on line 917 in nextest-runner/src/runner.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/runner.rs#L917

Added line #L917 was not covered by tests
result: ExecutionResult::ExecFail,
stopwatch_end: stopwatch.end(),
is_slow: false,
Expand Down Expand Up @@ -977,15 +980,14 @@ impl<'a> TestRunnerInner<'a> {

let child_stdout = child.stdout.take();
let child_stderr = child.stderr.take();
let mut stdout = bytes::BytesMut::new();
let mut stderr = bytes::BytesMut::new();

let mut acc = crate::test_output::TestOutputAccumulator::new();

let (res, leaked) = {
let mut collect_output_fut = std::pin::pin!(collect_output(
let mut collect_output_fut = std::pin::pin!(crate::test_output::collect_test_output(
child_stdout,
&mut stdout,
child_stderr,
&mut stderr
&mut acc,
));
let mut collect_output_done = false;

Expand Down Expand Up @@ -1080,8 +1082,7 @@ impl<'a> TestRunnerInner<'a> {
let status = status.unwrap_or_else(|| create_execution_result(exit_status, leaked));

Ok(InternalExecuteStatus {
stdout: stdout.freeze(),
stderr: stderr.freeze(),
output: acc.freeze(),
result: status,
stopwatch_end: stopwatch.end(),
is_slow,
Expand Down Expand Up @@ -1400,10 +1401,8 @@ impl<'a> ExecutionDescription<'a> {
pub struct ExecuteStatus {
/// Retry-related data.
pub retry_data: RetryData,
/// Standard output for this test.
pub stdout: Bytes,
/// Standard error for this test.
pub stderr: Bytes,
/// The stdout and stderr output for this test.
pub output: TestOutput,
/// The execution result for this test: pass, fail or execution error.
pub result: ExecutionResult,
/// The time at which the test started.
Expand All @@ -1417,8 +1416,7 @@ pub struct ExecuteStatus {
}

struct InternalExecuteStatus {
stdout: Bytes,
stderr: Bytes,
output: TestOutput,
result: ExecutionResult,
stopwatch_end: StopwatchEnd,
is_slow: bool,
Expand All @@ -1429,8 +1427,7 @@ impl InternalExecuteStatus {
fn into_external(self, retry_data: RetryData) -> ExecuteStatus {
ExecuteStatus {
retry_data,
stdout: self.stdout,
stderr: self.stderr,
output: self.output,
result: self.result,
start_time: self.stopwatch_end.start_time,
time_taken: self.stopwatch_end.duration,
Expand Down
Loading

0 comments on commit f5e3f51

Please sign in to comment.