Skip to content

Commit 55cac33

Browse files
branchseerclaude
andcommitted
fix(test): eliminate race in exit-on-ctrlc output ordering
Move "ctrl-c received" print from the signal handler to the main thread (after OnceLock::wait), so it always executes after the milestone flush println!(). Previously, std::process::exit(0) in the handler could terminate before output reached the PTY, causing flaky snapshot diffs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c5aa545 commit 55cac33

File tree

4 files changed

+24
-15
lines changed

4 files changed

+24
-15
lines changed

crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::sync::Arc;
2+
13
/// exit-on-ctrlc
24
///
35
/// Sets up a Ctrl+C handler, emits a "ready" milestone, then waits.
@@ -25,19 +27,25 @@ pub fn run() -> Result<(), Box<dyn std::error::Error>> {
2527
}
2628
}
2729

28-
ctrlc::set_handler(move || {
29-
use std::io::Write;
30-
let _ = write!(std::io::stdout(), "ctrl-c received");
31-
let _ = std::io::stdout().flush();
32-
std::process::exit(0);
30+
let ctrlc_once_lock = Arc::new(std::sync::OnceLock::<()>::new());
31+
32+
ctrlc::set_handler({
33+
let ctrlc_once_lock = Arc::clone(&ctrlc_once_lock);
34+
move || {
35+
let _ = ctrlc_once_lock.set(());
36+
}
3337
})?;
3438

39+
// Print "ready" before the milestone so it is always visible in the screen
40+
// capture at milestone time. The milestone's mark_milestone() flushes stdout
41+
// first, ensuring "ready" reaches the PTY before the OSC 8 sequence. The
42+
// trailing println!() provides a newline to flush milestone bytes through
43+
// line-buffered writers (labeled log mode).
44+
print!("ready");
3545
pty_terminal_test_client::mark_milestone("ready");
36-
// Print a newline so the milestone bytes get flushed through line-buffered
37-
// writers (labeled/grouped log modes).
3846
println!();
3947

40-
loop {
41-
std::thread::park();
42-
}
48+
ctrlc_once_lock.wait();
49+
println!("ctrl-c received");
50+
Ok(())
4351
}

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (cached).snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ expression: e2e_outputs
55
> vt run dev-cached
66
@ expect-milestone: ready
77
$ vtt exit-on-ctrlc
8+
ready
89
@ write-key: ctrl-c
910
$ vtt exit-on-ctrlc
10-
11+
ready
1112
ctrl-c received

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (labeled).snap

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ expression: e2e_outputs
55
> vt run --log=labeled dev
66
@ expect-milestone: ready
77
[ctrl-c-test#dev] $ vtt exit-on-ctrlccache disabled
8-
[ctrl-c-test#dev]
8+
[ctrl-c-test#dev] ready
99
@ write-key: ctrl-c
1010
[ctrl-c-test#dev] $ vtt exit-on-ctrlccache disabled
11-
[ctrl-c-test#dev]
12-
11+
[ctrl-c-test#dev] ready
1312
[ctrl-c-test#dev] ctrl-c received

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ expression: e2e_outputs
55
> vt run dev
66
@ expect-milestone: ready
77
$ vtt exit-on-ctrlccache disabled
8+
ready
89
@ write-key: ctrl-c
910
$ vtt exit-on-ctrlccache disabled
10-
11+
ready
1112
ctrl-c received

0 commit comments

Comments
 (0)