From a4e6ea1cb4159af44da880ffaff89bb11677adbf Mon Sep 17 00:00:00 2001 From: branchseer Date: Sun, 29 Mar 2026 13:38:40 +0800 Subject: [PATCH] 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) --- crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs | 23 ++++++++++--------- .../fixtures/ctrl-c/snapshots.toml | 14 ----------- ...l-c terminates running tasks (cached).snap | 1 - ...-c terminates running tasks (labeled).snap | 13 ----------- .../ctrl-c terminates running tasks.snap | 1 - 5 files changed, 12 insertions(+), 40 deletions(-) delete mode 100644 crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (labeled).snap diff --git a/crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs b/crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs index 6c26d582..3e13f8f6 100644 --- a/crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs +++ b/crates/vite_task_bin/src/vtt/exit_on_ctrlc.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + /// exit-on-ctrlc /// /// Sets up a Ctrl+C handler, emits a "ready" milestone, then waits. @@ -25,19 +27,18 @@ pub fn run() -> Result<(), Box> { } } - ctrlc::set_handler(move || { - use std::io::Write; - let _ = write!(std::io::stdout(), "ctrl-c received"); - let _ = std::io::stdout().flush(); - std::process::exit(0); + let ctrlc_once_lock = Arc::new(std::sync::OnceLock::<()>::new()); + + ctrlc::set_handler({ + let ctrlc_once_lock = Arc::clone(&ctrlc_once_lock); + move || { + let _ = ctrlc_once_lock.set(()); + } })?; pty_terminal_test_client::mark_milestone("ready"); - // Print a newline so the milestone bytes get flushed through line-buffered - // writers (labeled/grouped log modes). - println!(); - loop { - std::thread::park(); - } + ctrlc_once_lock.wait(); + println!("ctrl-c received"); + Ok(()) } diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots.toml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots.toml index 637c2bee..ec1817db 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots.toml +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots.toml @@ -13,20 +13,6 @@ steps = [ ] }, ] -[[e2e]] -name = "ctrl-c terminates running tasks (labeled)" -steps = [ - { argv = [ - "vt", - "run", - "--log=labeled", - "dev", - ], interactions = [ - { "expect-milestone" = "ready" }, - { "write-key" = "ctrl-c" }, - ] }, -] - [[e2e]] name = "ctrl-c terminates running tasks (cached)" steps = [ diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (cached).snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (cached).snap index 4fe99bae..8673a01f 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (cached).snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (cached).snap @@ -7,5 +7,4 @@ expression: e2e_outputs $ vtt exit-on-ctrlc @ write-key: ctrl-c $ vtt exit-on-ctrlc - ctrl-c received diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (labeled).snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (labeled).snap deleted file mode 100644 index ec161535..00000000 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks (labeled).snap +++ /dev/null @@ -1,13 +0,0 @@ ---- -source: crates/vite_task_bin/tests/e2e_snapshots/main.rs -expression: e2e_outputs ---- -> vt run --log=labeled dev -@ expect-milestone: ready -[ctrl-c-test#dev] $ vtt exit-on-ctrlc ⊘ cache disabled -[ctrl-c-test#dev] -@ write-key: ctrl-c -[ctrl-c-test#dev] $ vtt exit-on-ctrlc ⊘ cache disabled -[ctrl-c-test#dev] - -[ctrl-c-test#dev] ctrl-c received diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks.snap index 84c6c210..b19a6308 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks.snap +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/ctrl-c/snapshots/ctrl-c terminates running tasks.snap @@ -7,5 +7,4 @@ expression: e2e_outputs $ vtt exit-on-ctrlc ⊘ cache disabled @ write-key: ctrl-c $ vtt exit-on-ctrlc ⊘ cache disabled - ctrl-c received