process: Ensure all tests are run with an explicit timeout

This commit is contained in:
Ivan Petkov
2019-06-24 16:57:19 -07:00
parent d0d13d0bd0
commit 6fa2fdab44
4 changed files with 43 additions and 24 deletions
+6 -4
View File
@@ -5,7 +5,7 @@ name = "tokio-process"
# - Update CHANGELOG.md.
# - Create "X.Y.Z" git tag.
version = "0.2.3"
authors = ["Alex Crichton <[email protected]>"]
authors = ["Alex Crichton <[email protected]>", "Ivan Petkov <[email protected]>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/alexcrichton/tokio-process"
homepage = "https://github.com/alexcrichton/tokio-process"
@@ -27,11 +27,13 @@ tokio-io = "0.1"
tokio-reactor = "0.1"
[dev-dependencies]
env_logger = { version = "0.4", default-features = false }
failure = "0.1"
log = "0.4"
tokio = "0.1"
tokio-current-thread = "0.1"
[dev-dependencies.tokio]
version = "0.1"
default-features = false
features = ["rt-full"]
[target.'cfg(windows)'.dependencies]
mio-named-pipes = "0.1"
+2 -2
View File
@@ -1,4 +1,3 @@
extern crate tokio_current_thread;
extern crate tokio_process;
use tokio_process::CommandExt;
@@ -15,7 +14,8 @@ fn simple() {
let id = child.id();
assert!(id > 0);
let status = tokio_current_thread::block_on_all(&mut child).unwrap();
let status = support::run_with_timeout(&mut child)
.expect("failed to run future");
assert_eq!(status.code(), Some(2));
assert_eq!(child.id(), id);
+7 -16
View File
@@ -1,21 +1,16 @@
extern crate futures;
extern crate tokio;
extern crate tokio_current_thread;
extern crate tokio_io;
extern crate tokio_process;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate tokio_io;
extern crate tokio_process;
use std::io;
use std::process::{Stdio, ExitStatus, Command};
use std::time::Duration;
use futures::future::Future;
use futures::stream::{self, Stream};
use tokio_io::io::{read_until, write_all, read_to_end};
use tokio_process::{CommandExt, Child};
use tokio::timer::Timeout;
mod support;
@@ -72,7 +67,6 @@ fn feed_cat(mut cat: Child, n: usize) -> Box<Future<Item = ExitStatus, Error = i
Box::new(write.join(read).and_then(|_| cat))
}
#[test]
/// Check for the following properties when feeding stdin and
/// consuming stdout of a cat-like process:
///
@@ -84,9 +78,10 @@ fn feed_cat(mut cat: Child, n: usize) -> Box<Future<Item = ExitStatus, Error = i
/// - We read the same lines from the child that we fed it.
///
/// - The child does produce EOF on stdout after the last line.
#[test]
fn feed_a_lot() {
let child = cat().spawn_async().unwrap();
let status = tokio_current_thread::block_on_all(feed_cat(child, 10000)).unwrap();
let status = support::run_with_timeout(feed_cat(child, 10000)).unwrap();
assert_eq!(status.code(), Some(0));
}
@@ -103,7 +98,7 @@ fn drop_kills() {
let future = writer.join(reader).map(|(_, (_, out))| out);
let output = tokio_current_thread::block_on_all(future).unwrap();
let output = support::run_with_timeout(future).unwrap();
assert_eq!(output.len(), 0);
}
@@ -114,7 +109,7 @@ fn wait_with_output_captures() {
let out = child.wait_with_output();
let future = write_all(stdin, b"1234").map(|p| p.1).join(out);
let ret = tokio_current_thread::block_on_all(future).unwrap();
let ret = support::run_with_timeout(future).unwrap();
let (written, output) = ret;
assert!(output.status.success());
@@ -129,10 +124,6 @@ fn status_closes_any_pipes() {
// we would end up blocking forever (and time out).
let child = cat().status_async().expect("failed to spawn child");
// 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 = tokio::runtime::current_thread::Runtime::new().unwrap();
rt.block_on(Timeout::new(child, Duration::from_secs(1)))
support::run_with_timeout(child)
.expect("time out exceeded! did we get stuck waiting on the child?");
}
+28 -2
View File
@@ -1,9 +1,12 @@
extern crate env_logger;
extern crate futures;
extern crate tokio_process;
extern crate tokio;
use self::futures::Future;
use self::tokio::runtime::current_thread;
use self::tokio::timer::Timeout;
use std::env;
use std::process::Command;
use std::time::Duration;
pub fn cmd(s: &str) -> Command {
let mut me = env::current_exe().unwrap();
@@ -14,3 +17,26 @@ pub fn cmd(s: &str) -> Command {
me.push(s);
Command::new(me)
}
fn with_timeout<F: Future>(future: F) -> impl Future<Item = F::Item, Error = F::Error> {
Timeout::new(future, 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")
}
})
}
pub fn run_with_timeout<F>(future: F) -> Result<F::Item, F::Error>
where
F: Future,
{
// NB: Timeout 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 = current_thread::Runtime::new().expect("failed to get runtime");
rt.block_on(with_timeout(future))
}