mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
fix(test): add process sigint handler for --watch (#18678)
Fixes #18676.
This commit is contained in:
parent
babfad7113
commit
a1845a041b
2 changed files with 48 additions and 0 deletions
|
@ -1122,6 +1122,35 @@ fn test_watch_unload_handler_error_on_drop() {
|
||||||
check_alive_then_kill(child);
|
check_alive_then_kill(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[test]
|
||||||
|
fn test_watch_sigint() {
|
||||||
|
use nix::sys::signal;
|
||||||
|
use nix::sys::signal::Signal;
|
||||||
|
use nix::unistd::Pid;
|
||||||
|
|
||||||
|
let t = TempDir::new();
|
||||||
|
let file_to_watch = t.path().join("file_to_watch.js");
|
||||||
|
write(&file_to_watch, r#"Deno.test("foo", () => {});"#).unwrap();
|
||||||
|
let mut child = util::deno_cmd()
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("test")
|
||||||
|
.arg("--watch")
|
||||||
|
.arg(&file_to_watch)
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.stdout(std::process::Stdio::piped())
|
||||||
|
.stderr(std::process::Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child);
|
||||||
|
wait_contains("Test started", &mut stderr_lines);
|
||||||
|
wait_contains("ok | 1 passed | 0 failed", &mut stdout_lines);
|
||||||
|
wait_contains("Test finished", &mut stderr_lines);
|
||||||
|
signal::kill(Pid::from_raw(child.id() as i32), Signal::SIGINT).unwrap();
|
||||||
|
let exit_status = child.wait().unwrap();
|
||||||
|
assert_eq!(exit_status.code(), Some(130));
|
||||||
|
}
|
||||||
|
|
||||||
// Regression test for https://github.com/denoland/deno/issues/15465.
|
// Regression test for https://github.com/denoland/deno/issues/15465.
|
||||||
#[test]
|
#[test]
|
||||||
fn run_watch_reload_once() {
|
fn run_watch_reload_once() {
|
||||||
|
|
|
@ -57,7 +57,9 @@ use std::io::Write;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
@ -1174,6 +1176,8 @@ pub async fn check_specifiers(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HAS_TEST_RUN_SIGINT_HANDLER: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
/// Test a collection of specifiers with test modes concurrently.
|
/// Test a collection of specifiers with test modes concurrently.
|
||||||
async fn test_specifiers(
|
async fn test_specifiers(
|
||||||
ps: &ProcState,
|
ps: &ProcState,
|
||||||
|
@ -1201,6 +1205,7 @@ async fn test_specifiers(
|
||||||
signal::ctrl_c().await.unwrap();
|
signal::ctrl_c().await.unwrap();
|
||||||
sender_.upgrade().map(|s| s.send(TestEvent::Sigint).ok());
|
sender_.upgrade().map(|s| s.send(TestEvent::Sigint).ok());
|
||||||
});
|
});
|
||||||
|
HAS_TEST_RUN_SIGINT_HANDLER.store(true, Ordering::Relaxed);
|
||||||
|
|
||||||
let join_handles =
|
let join_handles =
|
||||||
specifiers_with_mode
|
specifiers_with_mode
|
||||||
|
@ -1388,6 +1393,7 @@ async fn test_specifiers(
|
||||||
}
|
}
|
||||||
|
|
||||||
sigint_handler_handle.abort();
|
sigint_handler_handle.abort();
|
||||||
|
HAS_TEST_RUN_SIGINT_HANDLER.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
let elapsed = Instant::now().duration_since(earlier);
|
let elapsed = Instant::now().duration_since(earlier);
|
||||||
reporter.report_summary(&summary, &elapsed);
|
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();
|
let clear_screen = !ps.borrow().options.no_clear_screen();
|
||||||
file_watcher::watch_func(
|
file_watcher::watch_func(
|
||||||
resolver,
|
resolver,
|
||||||
|
|
Loading…
Reference in a new issue