contrib: Only print fuzz output on failure

This makes it humanly possible to track progress as only "[N/M]"-lines are printed as long as we succeed.

Also, use char (a, b) to indicate run_id instead of u8 (0, 1).
Also, use emojis to indicate final success or error.

Co-Authored-By: Hodlinator <172445034+hodlinator@users.noreply.github.com>
This commit is contained in:
MarcoFalke 2025-03-31 14:02:45 +02:00
parent fa82fe2c73
commit fa900bb2dc
No known key found for this signature in database
2 changed files with 26 additions and 22 deletions

View file

@ -120,12 +120,12 @@ fn deterministic_coverage(
.map(|entry| entry.expect("IO error"))
.collect::<Vec<_>>();
entries.sort_by_key(|entry| entry.file_name());
let run_single = |run_id: u8, entry: &Path, thread_id: usize| -> Result<PathBuf, AppError> {
let cov_txt_path = build_dir.join(format!("fuzz_det_cov.show.t{thread_id}.r{run_id}.txt"));
let profraw_file = build_dir.join(format!("fuzz_det_cov.t{thread_id}.r{run_id}.profraw"));
let profdata_file = build_dir.join(format!("fuzz_det_cov.t{thread_id}.r{run_id}.profdata"));
if !{
let run_single = |run_id: char, entry: &Path, thread_id: usize| -> Result<PathBuf, AppError> {
let cov_txt_path = build_dir.join(format!("fuzz_det_cov.show.t{thread_id}.{run_id}.txt"));
let profraw_file = build_dir.join(format!("fuzz_det_cov.t{thread_id}.{run_id}.profraw"));
let profdata_file = build_dir.join(format!("fuzz_det_cov.t{thread_id}.{run_id}.profdata"));
{
let output = {
let mut cmd = Command::new(fuzz_exe);
if using_libfuzzer {
cmd.arg("-runs=1");
@ -135,11 +135,15 @@ fn deterministic_coverage(
.env("LLVM_PROFILE_FILE", &profraw_file)
.env("FUZZ", fuzz_target)
.arg(entry)
.status()
.map_err(|e| format!("fuzz failed with {e}"))?
.success()
} {
Err("fuzz failed".to_string())?;
.output()
.map_err(|e| format!("fuzz failed: {e}"))?;
if !output.status.success() {
Err(format!(
"fuzz failed!\nstdout:\n{}\nstderr:\n{}\n",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
))?;
}
}
if !Command::new(LLVM_PROFDATA)
.arg("merge")
@ -210,8 +214,8 @@ The coverage was not deterministic between runs.
if !entry.is_file() {
Err(format!("{} should be a file", entry.display()))?;
}
let cov_txt_base = run_single(0, &entry, thread_id)?;
let cov_txt_repeat = run_single(1, &entry, thread_id)?;
let cov_txt_base = run_single('a', &entry, thread_id)?;
let cov_txt_repeat = run_single('b', &entry, thread_id)?;
check_diff(
&cov_txt_base,
&cov_txt_repeat,
@ -249,15 +253,15 @@ The coverage was not deterministic between runs.
if !corpus_dir.is_dir() {
Err(format!("{} should be a folder", corpus_dir.display()))?;
}
let cov_txt_base = run_single(0, &corpus_dir, 0)?;
let cov_txt_repeat = run_single(1, &corpus_dir, 0)?;
let cov_txt_base = run_single('a', &corpus_dir, 0)?;
let cov_txt_repeat = run_single('b', &corpus_dir, 0)?;
check_diff(
&cov_txt_base,
&cov_txt_repeat,
&format!("All fuzz inputs in {} were used.", corpus_dir.display()),
)?;
}
println!("Coverage test passed for {fuzz_target}.");
println!("Coverage test passed for {fuzz_target}.");
Ok(())
}
@ -265,7 +269,7 @@ fn main() -> ExitCode {
match app() {
Ok(()) => ExitCode::SUCCESS,
Err(err) => {
eprintln!("{}", err);
eprintln!("⚠️\n{}", err);
ExitCode::FAILURE
}
}

View file

@ -71,7 +71,7 @@ fn app() -> AppResult {
fn deterministic_coverage(build_dir: &Path, test_exe: &Path, filter: &str) -> AppResult {
let profraw_file = build_dir.join("test_det_cov.profraw");
let profdata_file = build_dir.join("test_det_cov.profdata");
let run_single = |run_id: u8| -> Result<PathBuf, AppError> {
let run_single = |run_id: char| -> Result<PathBuf, AppError> {
println!("Run with id {run_id}");
let cov_txt_path = build_dir.join(format!("test_det_cov.show.{run_id}.txt"));
if !Command::new(test_exe)
@ -131,10 +131,10 @@ fn deterministic_coverage(build_dir: &Path, test_exe: &Path, filter: &str) -> Ap
}
Ok(())
};
let r0 = run_single(0)?;
let r1 = run_single(1)?;
let r0 = run_single('a')?;
let r1 = run_single('b')?;
check_diff(&r0, &r1)?;
println!("The coverage was deterministic across two runs.");
println!("The coverage was deterministic across two runs.");
Ok(())
}
@ -142,7 +142,7 @@ fn main() -> ExitCode {
match app() {
Ok(()) => ExitCode::SUCCESS,
Err(err) => {
eprintln!("{}", err);
eprintln!("⚠️\n{}", err);
ExitCode::FAILURE
}
}