Add tests for TestDirExt
Some of these tests are ignored, because they trigger known TestDirExt bugs. See #1140 for details.
This commit is contained in:
parent
3e897722a6
commit
e3e85f5dbd
|
@ -0,0 +1,169 @@
|
|||
#![allow(clippy::try_err)]
|
||||
|
||||
use std::{process::Command, time::Duration};
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use tempdir::TempDir;
|
||||
|
||||
use zebra_test::{command::TestDirExt, prelude::Stdio};
|
||||
|
||||
/// Returns true if `cmd` with `args` runs successfully.
|
||||
///
|
||||
/// On failure, prints an error message to stderr.
|
||||
/// (This message is captured by the test runner, use `cargo test -- --nocapture` to see it.)
|
||||
///
|
||||
/// The command's stdout and stderr are ignored.
|
||||
fn is_command_available(cmd: &str, args: &[&str]) -> bool {
|
||||
let status = Command::new(cmd)
|
||||
.args(args)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status();
|
||||
|
||||
match status {
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Skipping test because '{} {:?}' returned error {:?}",
|
||||
cmd, args, e
|
||||
);
|
||||
false
|
||||
}
|
||||
Ok(status) if !status.success() => {
|
||||
eprintln!(
|
||||
"Skipping test because '{} {:?}' returned status {:?}",
|
||||
cmd, args, status
|
||||
);
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if a process that keeps on producing lines of output is killed after the timeout.
|
||||
#[test]
|
||||
fn kill_on_timeout_output_continuous_lines() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
// Ideally, we'd want to use the 'yes' command here, but BSD yes treats
|
||||
// every string as an argument to repeat - so we can't test if it is
|
||||
// present on the system.
|
||||
const TEST_CMD: &str = "hexdump";
|
||||
// Skip the test if the test system does not have the command
|
||||
if !is_command_available(TEST_CMD, &["/dev/null"]) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Without '-v', hexdump hides duplicate lines. But we want duplicate lines
|
||||
// in this test.
|
||||
let mut child = TempDir::new("zebra_test")?
|
||||
.spawn_child_with_command(TEST_CMD, &["-v", "/dev/zero"])?
|
||||
.with_timeout(Duration::from_secs(2));
|
||||
|
||||
// We need to use expect_stdout, because wait_with_output ignores timeouts.
|
||||
// We use a non-matching regex, to trigger the timeout.
|
||||
assert!(child.expect_stdout("this regex should not match").is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test if the tests pass for a process that produces a single line of output,
|
||||
/// then exits before the timeout.
|
||||
//
|
||||
// TODO: create a similar test that pauses after output
|
||||
#[test]
|
||||
fn finish_before_timeout_output_single_line() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
const TEST_CMD: &str = "echo";
|
||||
// Skip the test if the test system does not have the command
|
||||
if !is_command_available(TEST_CMD, &[]) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut child = TempDir::new("zebra_test")?
|
||||
.spawn_child_with_command(TEST_CMD, &["zebra_test_output"])?
|
||||
.with_timeout(Duration::from_secs(2));
|
||||
|
||||
// We need to use expect_stdout, because wait_with_output ignores timeouts.
|
||||
// We use a non-matching regex, to trigger the timeout.
|
||||
assert!(child.expect_stdout("this regex should not match").is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test if a process that keeps on producing output, but doesn't produce any newlines,
|
||||
/// is killed after the timeout.
|
||||
///
|
||||
/// This test fails due to bugs in TestDirExt, see #1140 for details.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn kill_on_timeout_continuous_output_no_newlines() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
const TEST_CMD: &str = "cat";
|
||||
// Skip the test if the test system does not have the command
|
||||
if !is_command_available(TEST_CMD, &["/dev/null"]) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut child = TempDir::new("zebra_test")?
|
||||
.spawn_child_with_command(TEST_CMD, &["/dev/zero"])?
|
||||
.with_timeout(Duration::from_secs(2));
|
||||
|
||||
// We need to use expect_stdout, because wait_with_output ignores timeouts.
|
||||
// We use a non-matching regex, to trigger the timeout.
|
||||
assert!(child.expect_stdout("this regex should not match").is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test if tests pass for a process that produces a small amount of output,
|
||||
/// with no newlines, then exits before the timeout.
|
||||
//
|
||||
// TODO: create a similar test that pauses after output
|
||||
#[test]
|
||||
fn finish_before_timeout_short_output_no_newlines() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
const TEST_CMD: &str = "printf";
|
||||
// Skip the test if the test system does not have the command
|
||||
// The empty argument is required, because printf expects at least one argument.
|
||||
if !is_command_available(TEST_CMD, &[""]) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut child = TempDir::new("zebra_test")?
|
||||
.spawn_child_with_command(TEST_CMD, &["zebra_test_output"])?
|
||||
.with_timeout(Duration::from_secs(2));
|
||||
|
||||
// We need to use expect_stdout, because wait_with_output ignores timeouts.
|
||||
// We use a non-matching regex, to trigger the timeout.
|
||||
assert!(child.expect_stdout("this regex should not match").is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test if the timeout works for a process that produces no output.
|
||||
///
|
||||
/// This test fails due to bugs in TestDirExt, see #1140 for details.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn kill_on_timeout_no_output() -> Result<()> {
|
||||
zebra_test::init();
|
||||
|
||||
const TEST_CMD: &str = "sleep";
|
||||
// Skip the test if the test system does not have the command
|
||||
if !is_command_available(TEST_CMD, &["0"]) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut child = TempDir::new("zebra_test")?
|
||||
.spawn_child_with_command(TEST_CMD, &["120"])?
|
||||
.with_timeout(Duration::from_secs(2));
|
||||
|
||||
// We need to use expect_stdout, because wait_with_output ignores timeouts.
|
||||
// We use a non-matching regex, to trigger the timeout.
|
||||
assert!(child.expect_stdout("this regex should not match").is_err());
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue