Skip to content

Commit 5954546

Browse files
feat: update timed out test counting logic
Since timed out tests can now be treated as either successes or failures, update the logic for handling them. Note that before `self.failed` and `self.timed_out` were separate, but now `self.failed` includes `self.failed_timed_out`.
1 parent 0c34d2b commit 5954546

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

nextest-runner/src/reporter/events.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ pub struct RunStats {
553553
/// The number of tests that passed on retry.
554554
pub flaky: usize,
555555

556-
/// The number of tests that failed.
556+
/// The number of tests that failed. Includes `leaky_failed` and `failed_timed_out`.
557557
pub failed: usize,
558558

559559
/// The number of failed tests that were slow.
@@ -592,7 +592,7 @@ impl RunStats {
592592

593593
/// Returns count of tests that did not pass.
594594
pub fn failed_count(&self) -> usize {
595-
self.failed + self.exec_failed + self.failed_timed_out
595+
self.failed + self.exec_failed
596596
}
597597

598598
/// Summarizes the stats as an enum at the end of a test run.
@@ -720,7 +720,21 @@ impl RunStats {
720720
self.failed_slow += 1;
721721
}
722722
}
723-
ExecutionResult::Timeout { .. } => self.failed_timed_out += 1,
723+
ExecutionResult::Timeout {
724+
result: SlowTimeoutResult::Pass,
725+
} => {
726+
self.passed += 1;
727+
self.passed_timed_out += 1;
728+
if run_statuses.len() > 1 {
729+
self.flaky += 1;
730+
}
731+
}
732+
ExecutionResult::Timeout {
733+
result: SlowTimeoutResult::Fail,
734+
} => {
735+
self.failed += 1;
736+
self.failed_timed_out += 1;
737+
}
724738
ExecutionResult::ExecFail => self.exec_failed += 1,
725739
}
726740
}

nextest-runner/tests/integration/basic.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,95 @@ fn test_termination() -> Result<()> {
749749

750750
Ok(())
751751
}
752+
753+
#[test]
754+
fn test_timeout_result() -> Result<()> {
755+
test_init();
756+
757+
let pcx = ParseContext::new(&PACKAGE_GRAPH);
758+
let expr = Filterset::parse(
759+
"test(/^test_slow_timeout/)".to_owned(),
760+
&pcx,
761+
FiltersetKind::Test,
762+
)
763+
.unwrap();
764+
let test_filter = TestFilterBuilder::new(
765+
RunIgnored::Only,
766+
None,
767+
TestFilterPatterns::default(),
768+
vec![expr],
769+
)
770+
.unwrap();
771+
772+
let test_list = FIXTURE_TARGETS.make_test_list(
773+
"with-timeout-success",
774+
&test_filter,
775+
&TargetRunner::empty(),
776+
)?;
777+
let config = load_config();
778+
let profile = config
779+
.profile("with-timeout-success")
780+
.expect("with-timeout-success config is valid");
781+
let build_platforms = BuildPlatforms::new_with_no_target().unwrap();
782+
let profile = profile.apply_build_platforms(&build_platforms);
783+
784+
let runner = TestRunnerBuilder::default()
785+
.build(
786+
&test_list,
787+
&profile,
788+
vec![],
789+
SignalHandlerKind::Noop,
790+
InputHandlerKind::Noop,
791+
DoubleSpawnInfo::disabled(),
792+
TargetRunner::empty(),
793+
)
794+
.unwrap();
795+
796+
let (instance_statuses, run_stats) = execute_collect(runner);
797+
assert_eq!(
798+
run_stats.passed_timed_out, 3,
799+
"3 tests timed out and passed"
800+
);
801+
for test_name in [
802+
"test_slow_timeout",
803+
"test_slow_timeout_2",
804+
"test_slow_timeout_subprocess",
805+
] {
806+
let (_, instance_value) = instance_statuses
807+
.iter()
808+
.find(|&(&(_, name), _)| name == test_name)
809+
.unwrap_or_else(|| panic!("{test_name} should be present"));
810+
let valid = match &instance_value.status {
811+
InstanceStatus::Skipped(_) => panic!("{test_name} should have been run"),
812+
InstanceStatus::Finished(run_statuses) => {
813+
// This test should not have been retried since retries aren't configured.
814+
assert_eq!(
815+
run_statuses.len(),
816+
1,
817+
"{test_name} should have been run exactly once",
818+
);
819+
let run_status = run_statuses.last_status();
820+
// The test should have taken less than 5 seconds (most relevant for
821+
// test_slow_timeout_subprocess -- without job objects it gets stuck on Windows
822+
// until the subprocess exits.)
823+
assert!(
824+
run_status.time_taken < Duration::from_secs(5),
825+
"{test_name} should have taken less than 5 seconds, actually took {:?}",
826+
run_status.time_taken
827+
);
828+
run_status.result
829+
== ExecutionResult::Timeout {
830+
result: SlowTimeoutResult::Pass,
831+
}
832+
}
833+
};
834+
if !valid {
835+
panic!(
836+
"for test_slow_timeout, mismatch in status: expected timeout, actual {:?}",
837+
instance_value.status
838+
);
839+
}
840+
}
841+
842+
Ok(())
843+
}

0 commit comments

Comments
 (0)