use std::process::Command;
const CORPUS: &str = include_str!("fixtures/path_policy_corpus.tsv");
struct Row<'a> {
want_allow: bool,
category: &'a str,
command: &'a str,
}
fn rows() -> Vec<Row<'static>> {
CORPUS
.lines()
.filter(|l| !l.trim_start().starts_with('#') && !l.trim().is_empty())
.map(|line| {
let mut f = line.splitn(3, '\t');
let (want, category, command) = (
f.next().expect("verdict column"),
f.next().expect("category column"),
f.next().expect("command column"),
);
assert!(
matches!(want, "allow" | "deny"),
"corpus verdict must be allow/deny, got {want:?} in: {line}"
);
Row { want_allow: want == "allow", category, command }
})
.collect()
}
fn workspace() -> String {
env!("CARGO_MANIFEST_DIR").to_string()
}
fn allows(command: &str) -> bool {
let w = workspace();
Command::new(env!("CARGO_BIN_EXE_safe-chains"))
.args(["--cwd", &w, "--root", &w, command])
.output()
.expect("run safe-chains")
.status
.success()
}
#[test]
fn the_path_policy_corpus_holds() {
let rows = rows();
assert!(rows.len() >= 70, "corpus shrank to {} rows — cases were deleted, not fixed", rows.len());
let mut wrong = Vec::new();
for row in &rows {
let got = allows(row.command);
if got != row.want_allow {
let (want, got) = if row.want_allow { ("allow", "deny") } else { ("deny", "allow") };
wrong.push(format!(" [{}] want {want}, got {got}: {}", row.category, row.command));
}
}
assert!(
wrong.is_empty(),
"the path policy no longer matches its corpus ({} of {} rows):\n{}\n\n\
If the change was intended, edit the corpus in the same commit and say why there — a \
verdict that moves without the corpus moving is the drift this guard exists to catch.",
wrong.len(),
rows.len(),
wrong.join("\n")
);
}
#[test]
fn each_face_of_the_corpus_pins_both_answers() {
let rows = rows();
for (face, prefix) in [("read", "read-"), ("write", "write-")] {
let mine: Vec<bool> =
rows.iter().filter(|r| r.category.starts_with(prefix)).map(|r| r.want_allow).collect();
assert!(mine.len() >= 10, "{face}: only {} rows — too thin to discriminate", mine.len());
assert!(mine.iter().any(|a| *a), "{face}: corpus expects no allows, so refusing everything would pass");
assert!(mine.iter().any(|a| !*a), "{face}: corpus expects no denies, so allowing everything would pass");
}
}