forked from ZcashFoundation/zebra
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Some of these tests are ignored, because they trigger known TestDirExt bugs. See ZcashFoundation#1140 for details.
- Loading branch information
Showing
1 changed file
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(()) | ||
} |