summaryrefslogtreecommitdiffstats
path: root/tokio-signal/tests
diff options
context:
space:
mode:
authorMichal 'vorner' Vaner <vorner@vorner.cz>2018-09-01 10:57:20 +0200
committerMichal 'vorner' Vaner <vorner@vorner.cz>2018-09-14 23:25:57 +0200
commit35687f1d187ec21019906f900e99f064bf55c0eb (patch)
treedc8d638ecc521655d5e05f8157bf74aa8a65bf33 /tokio-signal/tests
parente7dc3a10916f298915ae40503b33041e53593c86 (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.rs39
-rw-r--r--tokio-signal/tests/drop_then_get_a_signal.rs28
-rw-r--r--tokio-signal/tests/dropping_does_not_deregister_other_instances.rs32
-rw-r--r--tokio-signal/tests/multi_loop.rs40
-rw-r--r--tokio-signal/tests/notify_both.rs27
-rw-r--r--tokio-signal/tests/signal.rs20
-rw-r--r--tokio-signal/tests/simple.rs20
-rw-r--r--tokio-signal/tests/support.rs50
-rw-r--r--tokio-signal/tests/twice.rs19
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();
+}