diff options
author | Michal 'vorner' Vaner <vorner@vorner.cz> | 2018-09-01 10:57:20 +0200 |
---|---|---|
committer | Michal 'vorner' Vaner <vorner@vorner.cz> | 2018-09-14 23:25:57 +0200 |
commit | 35687f1d187ec21019906f900e99f064bf55c0eb (patch) | |
tree | dc8d638ecc521655d5e05f8157bf74aa8a65bf33 /tokio-signal/tests | |
parent | e7dc3a10916f298915ae40503b33041e53593c86 (diff) |
signal: Move to tokio-signal subdirectory
As a preparation to merge with tokio.
Diffstat (limited to 'tokio-signal/tests')
-rw-r--r-- | tokio-signal/tests/drop_multi_loop.rs | 39 | ||||
-rw-r--r-- | tokio-signal/tests/drop_then_get_a_signal.rs | 28 | ||||
-rw-r--r-- | tokio-signal/tests/dropping_does_not_deregister_other_instances.rs | 32 | ||||
-rw-r--r-- | tokio-signal/tests/multi_loop.rs | 40 | ||||
-rw-r--r-- | tokio-signal/tests/notify_both.rs | 27 | ||||
-rw-r--r-- | tokio-signal/tests/signal.rs | 20 | ||||
-rw-r--r-- | tokio-signal/tests/simple.rs | 20 | ||||
-rw-r--r-- | tokio-signal/tests/support.rs | 50 | ||||
-rw-r--r-- | tokio-signal/tests/twice.rs | 19 |
9 files changed, 275 insertions, 0 deletions
diff --git a/tokio-signal/tests/drop_multi_loop.rs b/tokio-signal/tests/drop_multi_loop.rs new file mode 100644 index 00000000..62d8da53 --- /dev/null +++ b/tokio-signal/tests/drop_multi_loop.rs @@ -0,0 +1,39 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +const TEST_SIGNAL: libc::c_int = libc::SIGUSR1; + +#[test] +fn dropping_loops_does_not_cause_starvation() { + let (mut rt, signal) = { + let mut first_rt = CurrentThreadRuntime::new() + .expect("failed to init first runtime"); + + let first_signal = run_with_timeout(&mut first_rt, Signal::new(TEST_SIGNAL)) + .expect("failed to register first signal"); + + let mut second_rt = CurrentThreadRuntime::new() + .expect("failed to init second runtime"); + + let second_signal = run_with_timeout(&mut second_rt, Signal::new(TEST_SIGNAL)) + .expect("failed to register second signal"); + + drop(first_rt); + drop(first_signal); + + (second_rt, second_signal) + }; + + send_signal(TEST_SIGNAL); + + let signal_future = signal.into_future() + .map_err(|(e, _)| e); + + run_with_timeout(&mut rt, signal_future) + .expect("failed to get signal"); +} + diff --git a/tokio-signal/tests/drop_then_get_a_signal.rs b/tokio-signal/tests/drop_then_get_a_signal.rs new file mode 100644 index 00000000..4323e38b --- /dev/null +++ b/tokio-signal/tests/drop_then_get_a_signal.rs @@ -0,0 +1,28 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +#[test] +fn drop_then_get_a_signal() { + let mut lp = Core::new().unwrap(); + let handle = lp.handle(); + + let signal = run_core_with_timeout(&mut lp, Signal::with_handle( + libc::SIGUSR1, + &handle.new_tokio_handle(), + )).expect("failed to create first signal"); + drop(signal); + + send_signal(libc::SIGUSR1); + let signal = lp.run(Signal::with_handle(libc::SIGUSR1, &handle.new_tokio_handle())) + .expect("failed to create signal") + .into_future() + .map(|_| ()) + .map_err(|(e, _)| panic!("{}", e)); + + run_core_with_timeout(&mut lp, signal) + .expect("failed to get signal"); +} diff --git a/tokio-signal/tests/dropping_does_not_deregister_other_instances.rs b/tokio-signal/tests/dropping_does_not_deregister_other_instances.rs new file mode 100644 index 00000000..d8d3ee1d --- /dev/null +++ b/tokio-signal/tests/dropping_does_not_deregister_other_instances.rs @@ -0,0 +1,32 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +const TEST_SIGNAL: libc::c_int = libc::SIGUSR1; + +#[test] +fn dropping_signal_does_not_deregister_any_other_instances() { + // NB: Deadline requires a timer registration which is provided by + // tokio's `current_thread::Runtime`, but isn't available by just using + // tokio's default CurrentThread executor which powers `current_thread::block_on_all`. + let mut rt = CurrentThreadRuntime::new() + .expect("failed to init runtime"); + + // NB: Testing for issue #38: signals should not starve based on ordering + let first_duplicate_signal = run_with_timeout(&mut rt, Signal::new(TEST_SIGNAL)) + .expect("failed to register first duplicate signal"); + let signal = run_with_timeout(&mut rt, Signal::new(TEST_SIGNAL)) + .expect("failed to register signal"); + let second_duplicate_signal = run_with_timeout(&mut rt, Signal::new(TEST_SIGNAL)) + .expect("failed to register second duplicate signal"); + + drop(first_duplicate_signal); + drop(second_duplicate_signal); + + send_signal(TEST_SIGNAL); + run_with_timeout(&mut rt, signal.into_future().map_err(|(e, _)| e)) + .expect("failed to get signal"); +} diff --git a/tokio-signal/tests/multi_loop.rs b/tokio-signal/tests/multi_loop.rs new file mode 100644 index 00000000..40facc19 --- /dev/null +++ b/tokio-signal/tests/multi_loop.rs @@ -0,0 +1,40 @@ +#![cfg(unix)] + +extern crate libc; + +use std::sync::mpsc::channel; +use std::thread; + +pub mod support; +use support::*; + +#[test] +fn multi_loop() { + // An "ordinary" (non-future) channel + let (sender, receiver) = channel(); + // Run multiple times, to make sure there are no race conditions + for _ in 0..10 { + // Run multiple event loops, each one in its own thread + let threads: Vec<_> = (0..4) + .map(|_| { + let sender = sender.clone(); + thread::spawn(move || { + let mut lp = Core::new().unwrap(); + let signal = lp.run(Signal::new(libc::SIGHUP)).unwrap(); + sender.send(()).unwrap(); + run_core_with_timeout(&mut lp, signal.into_future()).ok().unwrap(); + }) + }) + .collect(); + // Wait for them to declare they're ready + for &_ in threads.iter() { + receiver.recv().unwrap(); + } + // Send a signal + send_signal(libc::SIGHUP); + // Make sure the threads terminated correctly + for t in threads { + t.join().unwrap(); + } + } +} diff --git a/tokio-signal/tests/notify_both.rs b/tokio-signal/tests/notify_both.rs new file mode 100644 index 00000000..ddcec33b --- /dev/null +++ b/tokio-signal/tests/notify_both.rs @@ -0,0 +1,27 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +#[test] +fn notify_both() { + let mut lp = Core::new().unwrap(); + let handle = lp.handle(); + + let signal1 = run_core_with_timeout(&mut lp, Signal::with_handle( + libc::SIGUSR2, + &handle.new_tokio_handle(), + )).expect("failed to create signal1"); + + let signal2 = run_core_with_timeout(&mut lp, Signal::with_handle( + libc::SIGUSR2, + &handle.new_tokio_handle(), + )).expect("failed to create signal2"); + + send_signal(libc::SIGUSR2); + run_core_with_timeout(&mut lp, signal1.into_future().join(signal2.into_future())) + .ok() + .expect("failed to create signal2"); +} diff --git a/tokio-signal/tests/signal.rs b/tokio-signal/tests/signal.rs new file mode 100644 index 00000000..05318e41 --- /dev/null +++ b/tokio-signal/tests/signal.rs @@ -0,0 +1,20 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +#[test] +fn tokio_simple() { + let signal_future = Signal::new(libc::SIGUSR1) + .and_then(|signal| { + send_signal(libc::SIGUSR1); + signal.into_future().map(|_| ()).map_err(|(err, _)| err) + }); + + let mut rt = CurrentThreadRuntime::new() + .expect("failed to init runtime"); + run_with_timeout(&mut rt, signal_future) + .expect("failed"); +} diff --git a/tokio-signal/tests/simple.rs b/tokio-signal/tests/simple.rs new file mode 100644 index 00000000..117cdce1 --- /dev/null +++ b/tokio-signal/tests/simple.rs @@ -0,0 +1,20 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +#[test] +fn simple() { + let mut lp = Core::new().unwrap(); + + let signal = run_core_with_timeout(&mut lp, Signal::new(libc::SIGUSR1)) + .expect("failed to create signal"); + + send_signal(libc::SIGUSR1); + + run_core_with_timeout(&mut lp, signal.into_future()) + .ok() + .expect("failed to get signal"); +} diff --git a/tokio-signal/tests/support.rs b/tokio-signal/tests/support.rs new file mode 100644 index 00000000..c9c7fd62 --- /dev/null +++ b/tokio-signal/tests/support.rs @@ -0,0 +1,50 @@ +extern crate libc; +extern crate futures; +extern crate tokio; +extern crate tokio_core; +extern crate tokio_signal; + +use self::libc::{c_int, getpid, kill}; +use std::time::{Duration, Instant}; +use self::tokio::timer::Deadline; +use self::tokio_core::reactor::Timeout; + +pub use self::futures::{Future, Stream}; +pub use self::tokio_core::reactor::Core; +pub use self::tokio::runtime::current_thread::Runtime as CurrentThreadRuntime; +pub use self::tokio_signal::unix::Signal; + +pub fn run_core_with_timeout<F>(lp: &mut Core, future: F) -> Result<F::Item, F::Error> + where F: Future +{ + let timeout = Timeout::new(Duration::from_secs(1), &lp.handle()) + .expect("failed to register timeout") + .map(|()| panic!("timeout exceeded")) + .map_err(|e| panic!("timeout error: {}", e)); + + lp.run(future.select(timeout)) + .map(|(r, _)| r) + .map_err(|(e, _)| e) +} + +pub fn run_with_timeout<F>(rt: &mut CurrentThreadRuntime, future: F) -> Result<F::Item, F::Error> + where F: Future +{ + let deadline = Deadline::new(future, Instant::now() + Duration::from_secs(1)) + .map_err(|e| if e.is_timer() { + panic!("failed to register timer"); + } else if e.is_elapsed() { + panic!("timed out") + } else { + e.into_inner().expect("missing inner error") + }); + + rt.block_on(deadline) +} + +#[cfg(unix)] +pub fn send_signal(signal: c_int) { + unsafe { + assert_eq!(kill(getpid(), signal), 0); + } +} diff --git a/tokio-signal/tests/twice.rs b/tokio-signal/tests/twice.rs new file mode 100644 index 00000000..3ddefa58 --- /dev/null +++ b/tokio-signal/tests/twice.rs @@ -0,0 +1,19 @@ +#![cfg(unix)] + +extern crate libc; + +pub mod support; +use support::*; + +#[test] +fn twice() { + let mut lp = Core::new().unwrap(); + let signal = run_core_with_timeout(&mut lp, Signal::new(libc::SIGUSR1)).unwrap(); + + send_signal(libc::SIGUSR1); + let (num, signal) = run_core_with_timeout(&mut lp, signal.into_future()).ok().unwrap(); + assert_eq!(num, Some(libc::SIGUSR1)); + + send_signal(libc::SIGUSR1); + run_core_with_timeout(&mut lp, signal.into_future()).ok().unwrap(); +} |