diff options
Diffstat (limited to 'vendor/signal-hook/tests/shutdown.rs')
-rw-r--r-- | vendor/signal-hook/tests/shutdown.rs | 81 |
1 files changed, 0 insertions, 81 deletions
diff --git a/vendor/signal-hook/tests/shutdown.rs b/vendor/signal-hook/tests/shutdown.rs deleted file mode 100644 index 381fab729..000000000 --- a/vendor/signal-hook/tests/shutdown.rs +++ /dev/null @@ -1,81 +0,0 @@ -//! Tests for the shutdown. -//! -//! The tests work like this: -//! -//! * The register an alarm, to fail if anything takes too long (which is very much possible here). -//! * A fork is done, with the child registering a signal with a NOP and cleanup operation (one or -//! the other). -//! * The child puts some kind of infinite loop or sleep inside itself, so it never actually -//! terminates on the first, but would terminate after the signal. - -#![cfg(not(windows))] // Forks don't work on Windows, but windows has the same implementation. - -use std::io::Error; -use std::ptr; -use std::sync::atomic::AtomicBool; -use std::sync::Arc; -use std::thread; -use std::time::Duration; - -use signal_hook::consts::signal::*; -use signal_hook::flag; -use signal_hook::low_level; - -fn do_test<C: FnOnce()>(child: C) { - unsafe { - libc::alarm(10); // Time out the test after 10 seconds and get it killed. - match libc::fork() { - -1 => panic!("Fork failed: {}", Error::last_os_error()), - 0 => { - child(); - loop { - thread::sleep(Duration::from_secs(1)); - } - } - pid => { - // Give the child some time to register signals and stuff - // We could actually signal that the child is ready by it eg. closing STDOUT, but - // this is just a test so we don't really bother. - thread::sleep(Duration::from_millis(250)); - libc::kill(pid, libc::SIGTERM); - // Wait a small bit to make sure the signal got delivered. - thread::sleep(Duration::from_millis(50)); - // The child is still running, because the first signal got "handled" by being - // ignored. - let terminated = libc::waitpid(pid, ptr::null_mut(), libc::WNOHANG); - assert_eq!(0, terminated, "Process {} terminated prematurely", pid); - // But it terminates on the second attempt (we do block on wait here). - libc::kill(pid, libc::SIGTERM); - let terminated = libc::waitpid(pid, ptr::null_mut(), 0); - assert_eq!(pid, terminated); - } - } - } -} - -/// Use automatic cleanup inside the signal handler to get rid of old signals, the aggressive way. -#[test] -fn cleanup_inside_signal() { - fn hook() { - // Make sure we have some signal handler, not the default. - unsafe { low_level::register(SIGTERM, || ()).unwrap() }; - let shutdown_cond = Arc::new(AtomicBool::new(false)); - // „disarmed“ shutdown - flag::register_conditional_shutdown(SIGTERM, 0, Arc::clone(&shutdown_cond)).unwrap(); - // But arm at the first SIGTERM - flag::register(SIGTERM, shutdown_cond).unwrap(); - } - do_test(hook); -} - -/// Manually remove the signal handler just after receiving the signal but before going into an -/// infinite loop. -#[test] -fn cleanup_after_signal() { - fn hook() { - let mut signals = signal_hook::iterator::Signals::new(&[libc::SIGTERM]).unwrap(); - assert_eq!(Some(SIGTERM), signals.into_iter().next()); - flag::register_conditional_shutdown(SIGTERM, 0, Arc::new(AtomicBool::new(true))).unwrap(); - } - do_test(hook); -} |