diff options
author | Nayeem Rahman <nayeemrmn99@gmail.com> | 2023-04-12 23:51:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-13 00:51:04 +0200 |
commit | d97f9d22b3873b89019a0fea67b83ed7cac8bd69 (patch) | |
tree | 4133837dd7dcb509e4a08158bf36ea5b38a93a5a /cli/tools/test.rs | |
parent | 17e4782140a602043c4f92e643c1908c521ae017 (diff) |
fix(test): add process sigint handler for --watch (#18678)
Fixes #18676.
Diffstat (limited to 'cli/tools/test.rs')
-rw-r--r-- | cli/tools/test.rs | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/cli/tools/test.rs b/cli/tools/test.rs index 87cb3c5e3..ce99a6edc 100644 --- a/cli/tools/test.rs +++ b/cli/tools/test.rs @@ -57,7 +57,9 @@ use std::io::Write; use std::num::NonZeroUsize; use std::path::Path; use std::path::PathBuf; +use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; use std::sync::Arc; use std::time::Duration; use std::time::Instant; @@ -1174,6 +1176,8 @@ pub async fn check_specifiers( Ok(()) } +static HAS_TEST_RUN_SIGINT_HANDLER: AtomicBool = AtomicBool::new(false); + /// Test a collection of specifiers with test modes concurrently. async fn test_specifiers( ps: &ProcState, @@ -1201,6 +1205,7 @@ async fn test_specifiers( signal::ctrl_c().await.unwrap(); sender_.upgrade().map(|s| s.send(TestEvent::Sigint).ok()); }); + HAS_TEST_RUN_SIGINT_HANDLER.store(true, Ordering::Relaxed); let join_handles = specifiers_with_mode @@ -1388,6 +1393,7 @@ async fn test_specifiers( } sigint_handler_handle.abort(); + HAS_TEST_RUN_SIGINT_HANDLER.store(false, Ordering::Relaxed); let elapsed = Instant::now().duration_since(earlier); reporter.report_summary(&summary, &elapsed); @@ -1736,6 +1742,19 @@ pub async fn run_tests_with_watch( } }; + // On top of the sigint handlers which are added and unbound for each test + // run, a process-scoped basic exit handler is required due to a tokio + // limitation where it doesn't unbind its own handler for the entire process + // once a user adds one. + tokio::task::spawn(async move { + loop { + signal::ctrl_c().await.unwrap(); + if !HAS_TEST_RUN_SIGINT_HANDLER.load(Ordering::Relaxed) { + std::process::exit(130); + } + } + }); + let clear_screen = !ps.borrow().options.no_clear_screen(); file_watcher::watch_func( resolver, |