diff --git a/cargo-test-fuzz/Cargo.toml b/cargo-test-fuzz/Cargo.toml index 9425915c..a8a724af 100644 --- a/cargo-test-fuzz/Cargo.toml +++ b/cargo-test-fuzz/Cargo.toml @@ -47,6 +47,7 @@ rustc_version = "0.4" semver = "1.0" serde_json = "1.0" tempfile = "3.10" +walkdir = "2.5" xshell = "0.2" testing = { path = "../testing", package = "test-fuzz-testing" } diff --git a/cargo-test-fuzz/tests/fuzz_parallel.rs b/cargo-test-fuzz/tests/fuzz_parallel.rs new file mode 100644 index 00000000..50432c95 --- /dev/null +++ b/cargo-test-fuzz/tests/fuzz_parallel.rs @@ -0,0 +1,46 @@ +use internal::dirs::output_directory_from_target; +use predicates::prelude::*; +use std::{ffi::OsStr, fs::remove_dir_all}; +use testing::{examples, retry, CommandExt}; + +const CPUS: &str = "2"; +const TIME_SLICE: &str = "30"; + +#[test] +fn fuzz_parallel() { + for i in 0..6 { + let output_dir = output_directory_from_target("parallel", &format!("target_{i}")); + remove_dir_all(output_dir).unwrap_or_default(); + } + + examples::test("parallel", "test") + .unwrap() + .logged_assert() + .success(); + + retry(3, || { + examples::test_fuzz_inexact("parallel", "target") + .unwrap() + .args([ + "--exit-code", + "--run-until-crash", + "--cpus", + CPUS, + "--slice", + TIME_SLICE, + ]) + .logged_assert() + .try_code(predicate::eq(1)) + }) + .unwrap(); + + // smoelius: Verify that all `.cur_input` files were removed. + for i in 0..6 { + let output_dir = output_directory_from_target("parallel", &format!("target_{i}")); + if output_dir.exists() { + assert!(!walkdir::WalkDir::new(output_dir) + .into_iter() + .any(|entry| entry.unwrap().path().file_name() == Some(OsStr::new(".cur_input")))); + } + } +} diff --git a/examples/tests/parallel.rs b/examples/tests/parallel.rs new file mode 100644 index 00000000..7b33f144 --- /dev/null +++ b/examples/tests/parallel.rs @@ -0,0 +1,29 @@ +#[test_fuzz::test_fuzz] +fn target_0(x: bool) {} + +#[test_fuzz::test_fuzz] +fn target_1(x: bool) {} + +#[test_fuzz::test_fuzz] +fn target_2(x: bool) {} + +#[test_fuzz::test_fuzz] +fn target_3(x: bool) { + assert!(!x); +} + +#[test_fuzz::test_fuzz] +fn target_4(x: bool) {} + +#[test_fuzz::test_fuzz] +fn target_5(x: bool) {} + +#[test] +fn test() { + target_0(false); + target_1(false); + target_2(false); + target_3(false); + target_4(false); + target_5(false); +} diff --git a/testing/src/examples.rs b/testing/src/examples.rs index 2ee76aa9..11ba039b 100644 --- a/testing/src/examples.rs +++ b/testing/src/examples.rs @@ -110,3 +110,10 @@ pub fn test_fuzz(krate: &str, target: &str) -> Result { command }) } + +pub fn test_fuzz_inexact(krate: &str, target: &str) -> Result { + test_fuzz_all().map(|mut command| { + command.args(["--test", krate, target]); + command + }) +}