use crate::common::*;
#[test]
fn bench_refuses_a_debug_build() {
let f = tmp("bench-refuse.txt");
std::fs::write(&f, b"hello bench\n").unwrap();
let (code, err) = bench_err(&["bench", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert_eq!(
err,
"stuffr: bench: timings from a debug build are meaningless; build with --release\n"
);
assert!(!err.contains("usage error"), "{err}");
}
#[test]
fn bench_with_no_match_is_a_usage_error() {
let dir = tmp_dir();
let pattern = format!("{}/nomatch*.log", dir.display());
let (code, err) = bench_err(&["bench", &pattern]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("no input matched"), "{err}");
}
#[test]
fn bench_on_a_missing_path_is_a_usage_error() {
let dir = tmp_dir();
let missing = dir.join("absent.log");
let (code, err) = bench_err(&["bench", missing.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("no input matched"), "{err}");
}
#[cfg(unix)]
#[test]
fn bench_on_a_dangling_symlink_is_a_usage_error() {
let dir = tmp_dir();
std::fs::write(dir.join("real.log"), b"x").unwrap();
let link = dir.join("dangling.log");
std::os::unix::fs::symlink(dir.join("gone.log"), &link).unwrap();
let want = format!("{}: cannot read it (", link.display());
let (code, err) = bench_err(&["bench", link.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
let pattern = format!("{}/*.log", dir.display());
let (code, err) = bench_err(&["bench", &pattern]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
}
#[cfg(unix)]
#[test]
fn bench_on_an_unreadable_directory_under_a_pattern_is_a_usage_error() {
use std::os::unix::fs::PermissionsExt;
let dir = tmp_dir();
std::fs::write(dir.join("a.log"), b"x").unwrap();
let locked = dir.join("locked");
std::fs::create_dir(&locked).unwrap();
std::fs::write(locked.join("b.log"), b"x").unwrap();
std::fs::set_permissions(&locked, std::fs::Permissions::from_mode(0o000)).unwrap();
if std::fs::read_dir(&locked).is_ok() {
return; }
let pattern = format!("{}/*/*.log", dir.display());
let (code, err) = bench_err(&["bench", &pattern]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("locked: cannot read it ("), "{err}");
}
#[cfg(unix)]
#[test]
fn bench_on_a_file_it_cannot_open_is_a_usage_error() {
use std::os::unix::fs::PermissionsExt;
let dir = tmp_dir();
std::fs::write(dir.join("a.log"), b"x").unwrap();
let locked = dir.join("locked.log");
std::fs::write(&locked, b"secret").unwrap();
std::fs::set_permissions(&locked, std::fs::Permissions::from_mode(0o000)).unwrap();
if std::fs::File::open(&locked).is_ok() {
return; }
let want = format!("{}: cannot read it (", locked.display());
let (code, err) = bench_err(&["bench", "-q", locked.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
let pattern = format!("{}/*.log", dir.display());
let (code, err) = bench_err(&["bench", "-q", &pattern]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
}
#[cfg(unix)]
#[test]
fn bench_on_a_pattern_under_an_unreadable_directory_names_it() {
use std::os::unix::fs::PermissionsExt;
let dir = tmp_dir();
let locked = dir.join("locked");
std::fs::create_dir_all(locked.join("sub")).unwrap();
std::fs::write(locked.join("sub/b.log"), b"x").unwrap();
std::fs::set_permissions(&locked, std::fs::Permissions::from_mode(0o000)).unwrap();
if std::fs::read_dir(&locked).is_ok() {
return; }
let pattern = format!("{}/locked/sub/*.log", dir.display());
let (code, err) = bench_err(&["bench", &pattern]);
assert_eq!(code, Some(2), "{err}");
let want = format!("{}: cannot read it (", locked.join("sub").display());
assert!(err.contains(&want), "{err}");
}
#[test]
fn bench_on_a_directory_is_a_usage_error() {
let dir = tmp_dir();
let (code, err) = bench_err(&["bench", dir.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("is a directory"), "{err}");
}
#[test]
fn bench_rejects_json_with_csv() {
let f = tmp("bench-json-csv.txt");
std::fs::write(&f, b"x").unwrap();
let (code, err) = bench_err(&["bench", "--json", "--csv", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("cannot be used with"), "{err}");
}
#[test]
fn bench_rejects_an_unknown_format() {
let f = tmp("bench-unknown.txt");
std::fs::write(&f, b"x").unwrap();
let (code, err) = bench_err(&["bench", "--formats", "nosuch", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("unknown format `nosuch`"), "{err}");
}
#[test]
fn bench_rejects_a_container_format() {
let f = tmp("bench-container.txt");
std::fs::write(&f, b"x").unwrap();
let (code, err) = bench_err(&["bench", "--formats", "tar", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("cannot be benchmarked"), "{err}");
assert!(err.contains("container"), "{err}");
}
#[test]
fn bench_rejects_a_zero_repeat() {
let f = tmp("bench-repeat.txt");
std::fs::write(&f, b"x").unwrap();
let (code, err) = bench_err(&["bench", "--repeat", "0", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains("--repeat"), "{err}");
}
#[test]
fn bench_rejects_no_memory_with_an_unknown_value() {
let f = tmp("bench-no-memory.txt");
std::fs::write(&f, b"x").unwrap();
let (code, err) = bench_err(&["bench", "--no-memory=yes", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(
err.contains("unexpected value 'yes' for '--no-memory'"),
"{err}"
);
let (code, err) = bench_err(&["bench", "--no-memory", f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(
err.contains("timings from a debug build are meaningless"),
"{err}"
);
}
#[cfg(unix)]
#[test]
fn bench_refuses_a_fifo_named_or_matched() {
let dir = tmp_dir();
let fifo = dir.join("pipe.log");
let made = std::process::Command::new("mkfifo")
.arg(&fifo)
.status()
.unwrap();
assert!(made.success());
let want = format!(
"{} is not a regular file; bench needs files whose size it can read",
fifo.display()
);
let (code, err) = bench_err(&["bench", fifo.to_str().unwrap()]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
let pattern = format!("{}/*.log", dir.display());
let (code, err) = bench_err(&["bench", &pattern]);
assert_eq!(code, Some(2), "{err}");
assert!(err.contains(&want), "{err}");
}
#[test]
fn bench_table_only_conflicts_with_json_and_csv() {
let f = tmp("bench-q-json.txt");
std::fs::write(&f, b"x").unwrap();
for machine in ["--json", "--csv"] {
for q in ["-q", "--table-only"] {
let (code, err) = bench_err(&["bench", q, machine, f.to_str().unwrap()]);
assert_eq!(code, Some(2), "{q} {machine}: {err}");
assert!(err.contains("cannot be used with"), "{q} {machine}: {err}");
}
}
}