From abe968e75e33d9ab76ee8f630d238068189ddc23 Mon Sep 17 00:00:00 2001 From: Nathan Herald Date: Wed, 4 Nov 2026 02:07:13 +0100 Subject: [PATCH] Keep the zombie-cap test's outcomes off the scheduler an_observed_exit_is_gone_once_the_zombie_shows_within_the_cap gave liveness_after_exit_with a 5 ms wall-clock cap in every case. Two of its assertions then depended on how long the 200 us sleeps between reads took: - The in-time case needs a third read before the cap. When a sleep ran past the cap, the loop correctly returned Unknown("exiting") after the second read, and the test expected Gone. - The still-exiting case asserted a second read. One long sleep after the first read used the whole cap. The in-time case is about stopping at the zombie, so it now has an ample cap and still asserts exactly three reads. The still-exiting case keeps the short cap and drops the read count; the in-time case already shows that the loop reads again. liveness_after_exit_with is unchanged. --- crates/pty-core/src/operation/record.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/pty-core/src/operation/record.rs b/crates/pty-core/src/operation/record.rs index fa7a44c4..8d3d6647 100644 --- a/crates/pty-core/src/operation/record.rs +++ b/crates/pty-core/src/operation/record.rs @@ -975,18 +975,21 @@ mod tests { let token = id.start_token.clone(); let cap = Duration::from_millis(5); + // How many reads fit in the cap is up to the scheduler: a loaded core + // can sleep past all of it after the first. The next case shows that + // it reads again. let started = Instant::now(); - let reads = std::cell::Cell::new(0); let still_exiting = id.liveness_after_exit_with(Some("boot"), cap, || { - reads.set(reads.get() + 1); ProcTable::from_rows(vec![row("E", &token)]) }); assert_eq!(still_exiting, Liveness::Unknown("exiting")); assert!(started.elapsed() >= cap, "it waited out the cap"); - assert!(reads.get() > 1, "and read again in between"); + // This case is about stopping at the zombie, not about the cap. On a + // loaded core one of the sleeps between reads can outlast a short cap. + let ample = Duration::from_secs(10); let reads = std::cell::Cell::new(0); - let zombie_in_time = id.liveness_after_exit_with(Some("boot"), cap, || { + let zombie_in_time = id.liveness_after_exit_with(Some("boot"), ample, || { reads.set(reads.get() + 1); let state = if reads.get() < 3 { "E" } else { "Z" }; ProcTable::from_rows(vec![row(state, &token)])