From 40d39511b3bafc90cf3a6c1ba98f6a690fdf8eaf Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Fri, 20 Sep 2024 18:34:47 +0200 Subject: [PATCH] Add test for behavior if tool is killed mid-run This is the codified version of #36, just with a SIGKILL instead of the mentioned SIGING (or SIGTERM). It is unclear, if the tool could even be- have sane with SIGKILL, but this is the only thing available in the Rust standard library. The test currently fails and thus shows that the issue is reproducible. --- tests/corpus/Cargo.toml | 4 ++++ tests/corpus/issue-36.rs | 6 +++++ tests/regression.rs | 49 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 tests/corpus/issue-36.rs diff --git a/tests/corpus/Cargo.toml b/tests/corpus/Cargo.toml index 86c5d74..6f5fd2d 100644 --- a/tests/corpus/Cargo.toml +++ b/tests/corpus/Cargo.toml @@ -15,6 +15,10 @@ path = "issue-74.rs" name = "issue-20" path = "issue-20.rs" +[[bin]] +name = "issue-36" +path = "issue-36.rs" + [[bin]] name = "issue-70" path = "issue-70.rs" diff --git a/tests/corpus/issue-36.rs b/tests/corpus/issue-36.rs new file mode 100644 index 0000000..68d2e39 --- /dev/null +++ b/tests/corpus/issue-36.rs @@ -0,0 +1,6 @@ +fn main() { + for n in 1..=10 { + std::thread::sleep(std::time::Duration::from_secs(1)); + println!("waited {n} seconds"); + } +} diff --git a/tests/regression.rs b/tests/regression.rs index b62b6dc..6a38ad9 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -74,3 +74,52 @@ fn environment_variables_are_passed_to_program_under_test() { .assert() .stdout(predicates::str::contains("RUST_LOG=debug")); } + +/// Issue: [#36]: make sure, that an interrupted `cargo valgrind` invocation +/// kills the running program, so that it does not run in the background. +/// +/// [#36]: https://github.com/jfrimmel/cargo-valgrind/issues/36 +#[test] +fn interrupted_program_execution() { + use assert_cmd::cargo::CommandCargoExt; + use std::{io::Read, process, thread, time::Duration}; + + // pre-build the crate to run, so that it does not need to be built later on + cargo_valgrind() + .arg("build") + .args(TARGET_CRATE) + .arg("--bin=issue-36"); + + // We need the raw `std::process::Command` in order to send the kill signal + // to it. Therefore this does not use the `cargo_valgrind()` helper as all + // other tests. + let mut cargo_valgrind = process::Command::cargo_bin("cargo-valgrind") + .unwrap() + .arg("valgrind") + .arg("run") + .arg("-q") // silence cargo output + .args(TARGET_CRATE) + .arg("--bin=issue-36") + .stderr(process::Stdio::piped()) + .stdout(process::Stdio::piped()) + .spawn() + .unwrap(); + + // wait until program is certainly started + thread::sleep(Duration::from_millis(500)); + + // kill `cargo valgrind`, which should kill the run program as well. + cargo_valgrind.kill().unwrap(); + cargo_valgrind.wait().unwrap(); + + // Check, what the helper program printed. The run program prints one line + // every second. Since this test should have killed the program before the + // first second is elapsed, there should be no output. + let mut stdout = String::new(); + cargo_valgrind + .stdout + .unwrap() + .read_to_string(&mut stdout) + .unwrap(); + assert_eq!("", stdout, "Program must end before the first print"); +}