diff options
Diffstat (limited to 'vendor/signal-hook/tests')
-rw-r--r-- | vendor/signal-hook/tests/default.rs | 25 | ||||
-rw-r--r-- | vendor/signal-hook/tests/iterator.rs | 260 | ||||
-rw-r--r-- | vendor/signal-hook/tests/shutdown.rs | 81 |
3 files changed, 0 insertions, 366 deletions
diff --git a/vendor/signal-hook/tests/default.rs b/vendor/signal-hook/tests/default.rs deleted file mode 100644 index bccf55891..000000000 --- a/vendor/signal-hook/tests/default.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Check the hack of SIG_DFL for windows. -//! -//! Libc doesn't export SIG_DFL on windows. It seems to be 0 on all platforms, though, but just to -//! make sure, we observe it is so. We try to read the previous signal on startup and it must be -//! the default. - -extern crate libc; - -use libc::{sighandler_t, signal, SIGTERM}; - -const SIG_DFL: sighandler_t = 0; - -#[test] -fn sig_dfl() { - unsafe { - let prev = signal(SIGTERM, SIG_DFL); - assert_eq!(SIG_DFL, prev); - } -} - -#[cfg(not(windows))] -#[test] -fn sig_dfl_static() { - assert_eq!(::libc::SIG_DFL, SIG_DFL); -} diff --git a/vendor/signal-hook/tests/iterator.rs b/vendor/signal-hook/tests/iterator.rs deleted file mode 100644 index 90e0598fe..000000000 --- a/vendor/signal-hook/tests/iterator.rs +++ /dev/null @@ -1,260 +0,0 @@ -#![cfg(not(windows))] - -extern crate signal_hook; - -use std::collections::HashSet; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::{self, RecvTimeoutError}; -use std::sync::Arc; -use std::thread::{self, JoinHandle}; -use std::time::Duration; - -use signal_hook::consts::{SIGUSR1, SIGUSR2}; -use signal_hook::iterator::{Handle, Signals}; -use signal_hook::low_level::raise; - -use serial_test::serial; - -fn send_sigusr1() { - raise(SIGUSR1).unwrap(); -} - -fn send_sigusr2() { - raise(SIGUSR2).unwrap(); -} - -fn setup_without_any_signals() -> (Signals, Handle) { - let signals = Signals::new(&[]).unwrap(); - let controller = signals.handle(); - (signals, controller) -} - -fn setup_for_sigusr2() -> (Signals, Handle) { - let signals = Signals::new(&[SIGUSR2]).unwrap(); - let controller = signals.handle(); - (signals, controller) -} - -macro_rules! assert_signals { - ($actual:expr, $($expected:expr),+ $(,)?) => { - let actual = $actual.collect::<HashSet<libc::c_int>>(); - let expected = vec!($($expected),+).into_iter().collect::<HashSet<libc::c_int>>(); - assert_eq!(actual, expected); - }; -} - -macro_rules! assert_no_signals { - ($signals:expr) => { - assert_eq!($signals.next(), None); - }; -} - -#[test] -#[serial] -fn forever_terminates_when_closed() { - let (mut signals, controller) = setup_for_sigusr2(); - - // Detect early terminations. - let stopped = Arc::new(AtomicBool::new(false)); - - let stopped_bg = Arc::clone(&stopped); - let thread = thread::spawn(move || { - // Eat all the signals there are (might come from a concurrent test, in theory). - // Would wait forever, but it should be terminated by the close below. - for _sig in &mut signals {} - - stopped_bg.store(true, Ordering::SeqCst); - }); - - // Wait a bit to see if the thread terminates by itself. - thread::sleep(Duration::from_millis(100)); - assert!(!stopped.load(Ordering::SeqCst)); - - controller.close(); - - thread.join().unwrap(); -} - -// A reproducer for #16: if we had the mio-support enabled (which is enabled also by the -// tokio-support feature), blocking no longer works. The .wait() would return immediately (an empty -// iterator, possibly), .forever() would do a busy loop. -// flag) -#[test] -#[serial] -fn signals_block_wait() { - let mut signals = Signals::new(&[SIGUSR2]).unwrap(); - let (s, r) = mpsc::channel(); - let finish = Arc::new(AtomicBool::new(false)); - let thread_id = thread::spawn({ - let finish = Arc::clone(&finish); - move || { - // Technically, it may spuriously return early. But it shouldn't be doing it too much, - // so we just try to wait multiple times ‒ if they *all* return right away, it is - // broken. - for _ in 0..10 { - for _ in signals.wait() { - if finish.load(Ordering::SeqCst) { - // Asked to terminate at the end of the thread. Do so (but without - // signalling the receipt). - return; - } else { - panic!("Someone really did send us SIGUSR2, which breaks the test"); - } - } - } - let _ = s.send(()); - } - }); - - // A RAII guard to make sure we shut down the thread even if the test fails. - struct ThreadGuard { - thread: Option<JoinHandle<()>>, - finish: Arc<AtomicBool>, - } - - impl ThreadGuard { - fn shutdown(&mut self) { - // Tell it to shut down - self.finish.store(true, Ordering::SeqCst); - // Wake it up - send_sigusr2(); - // Wait for it to actually terminate. - if let Some(thread) = self.thread.take() { - thread.join().unwrap(); // Propagate panics - } - } - } - - impl Drop for ThreadGuard { - fn drop(&mut self) { - self.shutdown(); // OK if done twice, won't have the thread any more. - } - } - - let mut bg_thread = ThreadGuard { - thread: Some(thread_id), - finish, - }; - - let err = r - .recv_timeout(Duration::from_millis(100)) - .expect_err("Wait didn't wait properly"); - assert_eq!(err, RecvTimeoutError::Timeout); - - bg_thread.shutdown(); -} - -#[test] -#[serial] -fn pending_doesnt_block() { - let (mut signals, _) = setup_for_sigusr2(); - - let mut recieved_signals = signals.pending(); - - assert_no_signals!(recieved_signals); -} - -#[test] -#[serial] -fn wait_returns_recieved_signals() { - let (mut signals, _) = setup_for_sigusr2(); - send_sigusr2(); - - let recieved_signals = signals.wait(); - - assert_signals!(recieved_signals, SIGUSR2); -} - -#[test] -#[serial] -fn forever_returns_recieved_signals() { - let (mut signals, _) = setup_for_sigusr2(); - send_sigusr2(); - - let signal = signals.forever().take(1); - - assert_signals!(signal, SIGUSR2); -} - -#[test] -#[serial] -fn wait_doesnt_block_when_closed() { - let (mut signals, controller) = setup_for_sigusr2(); - controller.close(); - - let mut recieved_signals = signals.wait(); - - assert_no_signals!(recieved_signals); -} - -#[test] -#[serial] -fn wait_unblocks_when_closed() { - let (mut signals, controller) = setup_without_any_signals(); - - let thread = thread::spawn(move || { - signals.wait(); - }); - - controller.close(); - - thread.join().unwrap(); -} - -#[test] -#[serial] -fn forever_doesnt_block_when_closed() { - let (mut signals, controller) = setup_for_sigusr2(); - controller.close(); - - let mut signal = signals.forever(); - - assert_no_signals!(signal); -} - -#[test] -#[serial] -fn add_signal_after_creation() { - let (mut signals, _) = setup_without_any_signals(); - signals.add_signal(SIGUSR1).unwrap(); - - send_sigusr1(); - - assert_signals!(signals.pending(), SIGUSR1); -} - -#[test] -#[serial] -fn delayed_signal_consumed() { - let (mut signals, _) = setup_for_sigusr2(); - signals.add_signal(SIGUSR1).unwrap(); - - send_sigusr1(); - let mut recieved_signals = signals.wait(); - send_sigusr2(); - - assert_signals!(recieved_signals, SIGUSR1, SIGUSR2); - - // The pipe still contains the byte from the second - // signal and so wait won't block but won't return - // a signal. - recieved_signals = signals.wait(); - assert_no_signals!(recieved_signals); -} - -#[test] -#[serial] -fn is_closed_initially_returns_false() { - let (_, controller) = setup_for_sigusr2(); - - assert!(!controller.is_closed()); -} - -#[test] -#[serial] -fn is_closed_returns_true_when_closed() { - let (_, controller) = setup_for_sigusr2(); - controller.close(); - - assert!(controller.is_closed()); -} 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); -} |