use std::env;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::time::Instant;
fn main() {
let iterations: usize = env::var("HOMEBOY_BENCH_ITERATIONS")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(10);
let manifest_dir =
env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set (run via cargo)");
let homeboy_bin: PathBuf = [&manifest_dir, "target", "release", "homeboy"]
.iter()
.collect();
if !homeboy_bin.exists() {
eprintln!(
"FATAL: homeboy binary not found at {} — run `cargo build --release` first",
homeboy_bin.display()
);
std::process::exit(2);
}
let fixture_path = manifest_dir.clone();
eprintln!(
"[bench-audit-self] iterations={}, binary={}, fixture={}",
iterations,
homeboy_bin.display(),
fixture_path
);
let mut timings_ns: Vec<u64> = Vec::with_capacity(iterations);
for i in 0..iterations {
let start = Instant::now();
let status = Command::new(&homeboy_bin)
.args([
"audit",
"homeboy", "--path",
&fixture_path,
"--ignore-baseline",
"--json-summary",
])
.stdout(Stdio::null()) .stderr(Stdio::null())
.status();
let elapsed = start.elapsed();
match status {
Ok(s) if s.success() || s.code() == Some(1) => {
}
Ok(s) => {
eprintln!(
"FATAL: iteration {}/{} — homeboy audit exited {} (unexpected)",
i + 1,
iterations,
s.code().unwrap_or(-1)
);
std::process::exit(3);
}
Err(e) => {
eprintln!(
"FATAL: iteration {}/{} — failed to spawn homeboy: {}",
i + 1,
iterations,
e
);
std::process::exit(4);
}
}
timings_ns.push(elapsed.as_nanos() as u64);
eprintln!(
"[bench-audit-self] iteration {}/{}: {:.2}ms",
i + 1,
iterations,
elapsed.as_secs_f64() * 1000.0
);
}
let csv: String = timings_ns
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(",");
println!("{{\"timings_ns\":[{}]}}", csv);
}