tests/no_silenced_tests.rs
//! **Tripwire: no `tests/*.rs` in this repo may compile to ZERO tests.**
//!
//! A test file whose crate-level inner attribute — `#![cfg(feature = "X")]` —
//! is not satisfied by its crate's `default` feature closure compiles to an
//! EMPTY test binary. `cargo test` then prints `running 0 tests ... ok` and the
//! file is green-by-vacuum: it looks exactly like a passing file, forever.
//! `nornir_testmatrix::audit_repo` resolves every workspace member's `default`
//! closure statically and RED-flags any gated file that is neither
//! default-reachable nor re-invoked by an arm declared in
//! `.nornir/testmatrix-arms.json`.
//!
//! ## What this repo looks like today
//!
//! Measured 2026-08-01 on `oden`: **10 test targets scanned · 1 feature-gated ·
//! 1 rescued by a declared arm · 0 silenced**.
//!
//! skade is the repo whose green is *earned rather than accidental*, and it is
//! the interesting case of the six. Its one gated target is
//! `tests/testmatrix_wiring.rs`, headed `#![cfg(feature = "testmatrix")]` — and
//! `testmatrix` can never be a default here, by design: it flips
//! `nornir_testmatrix::functional_status` from a compiled-out no-op into a real
//! row-appender, and the release build must strip it. So the file is
//! permanently unreachable from `default` and the ONLY thing keeping it honest
//! is the single arm skade declares:
//!
//! ```json
//! { "package": "skade-katalog", "features": ["testmatrix"] }
//! ```
//!
//! That arm is a promise that someone actually runs
//! `cargo test -p skade-katalog --features testmatrix`. This guard checks that
//! the promise still *covers* the file, which is the failure mode skade was
//! caught by in the first place: the original 2026-07-21 audit found a NEAR-MISS
//! arm name here — CI passing `lineage` where the file needed `lineage-http`, a
//! different feature that does not imply it. The arm reads plausible; the file
//! stayed dark. The guard re-resolves the arm's transitive feature closure
//! against the cfg the file actually carries instead of trusting the string, so
//! a rename on either side goes red rather than quiet.
//!
//! What this file does NOT prove: that the arm is ever executed. It proves the
//! arm exists and would rescue the file if run. Nothing in a static audit can
//! tell you a command was invoked.
//!
//! The non-vacuity assertion below matters as much as the silence assertion: a
//! repo root that resolves but scans nothing reports "0 silenced" because it
//! looked at nothing. `scanned > 0` is what separates a real green from an empty
//! one. (Two repos in this fleet — bifrost and heimdal — genuinely scan zero
//! targets, and for that reason deliberately do NOT carry this file.)
//!
//! Deliberately NOT feature-gated — and in this repo that is more than a
//! wisecrack. Every other emitting test here is `#![cfg(feature =
//! "testmatrix")]`, so the locally idiomatic thing would have been to gate this
//! one too; that would have made a guard against silenced tests the 11th
//! silenced test.
use std::path::{Path, PathBuf};
/// This file lives at `<repo>/tests/`, and `skade-katalog` is the workspace
/// root package (the `[workspace]` table is in the same manifest), so
/// `CARGO_MANIFEST_DIR` is already the directory the audit must run in.
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(0)
.unwrap()
.to_path_buf()
}
#[test]
fn this_repo_has_no_silenced_test_files() {
let root = repo_root();
let rep = nornir_testmatrix::audit_repo(&root, "self-audit").unwrap_or_else(|e| {
panic!(
"the silenced-test audit could not RUN at {} — that is a RED, not a skip: {e:#}",
root.display()
)
});
// Non-vacuity (LAW 2: check output, not exit code). A root that resolves but
// scans nothing reports "0 silenced" because it looked at nothing.
assert!(
rep.scanned > 0,
"the audit scanned ZERO test targets under {} — it proved nothing",
root.display()
);
assert!(
rep.is_green(),
"SILENCED TESTS in `skade` — {}\n{}",
rep.summary(),
rep.silenced()
.iter()
.map(|f| format!(" · {}", f.message()))
.collect::<Vec<_>>()
.join("\n")
);
}