crates/nornir-testmatrix/tests/dep_edge_surface_guard.rs
//! **The gate the dependency-edge work shipped without.**
//!
//! `src/testsurface.rs` (1284 lines) and its two fixtures landed in `bbde6c9`
//! with NO test reaching any of it: `resolve`, `audit_test_surface`,
//! `dep_closure` and `surface_gaps` were `pub`, re-exported from `lib.rs`, and
//! called by nothing — not a unit test, not an integration test, not a binary.
//! `tests/fixtures/dep_edge_lit` was named only in doc comments. A detector no
//! test executes is a detector that cannot go red, which is precisely the state
//! LAW 2 exists to forbid.
//!
//! Every assertion here is on APPLIED output — the resolved feature set, the
//! verdict, the closure — never on a state round-trip, and each one is paired
//! with the pre-fix input that makes it fail.
use std::collections::{BTreeMap, BTreeSet};
use std::path::{Path, PathBuf};
use nornir_build_thing::variant::BuildVariantSet;
use nornir_testmatrix::{
audit_test_surface, config_for_variant, dep_closure, resolve, surface_gaps, CrateManifest,
MatrixArms, RunVerdict, SurfaceGap, TestSurfaceReport,
};
use nornir_testmatrix::targetcheck::VariantSpec;
fn fixture() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/dep_edge_lit")
}
/// The fixture's real `cargo metadata`, parsed by the code under test.
fn crates() -> Vec<CrateManifest> {
let c = nornir_testmatrix::workspace_crates(&fixture()).expect("cargo metadata on the fixture");
assert_eq!(
c.iter().map(|k| k.name.as_str()).collect::<Vec<_>>(),
vec!["driver", "engine"],
"fixture workspace changed shape"
);
c
}
/// The declared variants, read from the fixture's own
/// `.nornir/build-variants.toml` — not hand-built, so the test fails if the
/// declaration stops saying what the doc comment claims it says.
fn variants() -> Vec<VariantSpec> {
let set = BuildVariantSet::discover(&fixture())
.expect("load build-variants.toml")
.expect("the fixture declares variants");
set.variants
.iter()
.map(|v| VariantSpec {
name: v.name.clone(),
package: v.package.clone(),
features: v.features.clone(),
no_default_features: v.no_default_features,
target: v.target.clone(),
manifest_dir: None,
})
.collect()
}
fn variant(name: &str) -> VariantSpec {
variants()
.into_iter()
.find(|v| v.name == name)
.unwrap_or_else(|| panic!("no variant `{name}` in the fixture"))
}
/// The **pre-`bbde6c9` `CrateManifest`**: `deps` did not exist as a field, so
/// every manifest behaved exactly as one with no edges. This is the red input.
fn without_dep_edges(c: &[CrateManifest]) -> Vec<CrateManifest> {
c.iter()
.map(|k| CrateManifest {
deps: Vec::new(),
..k.clone()
})
.collect()
}
// ─── the third source: a feature turned on along a dependency EDGE ─────────
/// RED, then GREEN, in one test so the red can never quietly stop being red.
///
/// `engine/served` is written by nothing: not by `[build] offers`, not by any
/// variant's `--features`, not by `engine`'s own `default`. The ONLY thing that
/// turns it on is `driver`'s optional edge
/// `engine-lib = { package = "engine", features = ["served"] }`, activated by
/// `bench = ["dep:engine-lib"]`.
#[test]
fn a_feature_lit_only_by_a_dependency_edge_is_invisible_without_the_edges() {
let all = crates();
let cfg = config_for_variant(&all, &variant("bench"), &[], None);
// The seeds prove the feature is genuinely unwritten: `bench` + `default` on
// `driver`, and nothing at all said about `engine`.
assert_eq!(
cfg.seeds.get("driver").map(|s| s.as_slice()),
Some(["bench".to_string(), "default".to_string()].as_slice()),
"the variant seeds `driver` with bench+default and nothing else"
);
assert!(
!cfg.seeds.values().flatten().any(|f| f == "served"),
"nothing in the configuration writes the word `served`: {:?}",
cfg.seeds
);
// ── RED: the pre-fix manifest, with no `deps` field. ──
let red = resolve(&without_dep_edges(&all), &cfg);
let red_engine = red.enabled.get("engine").cloned().unwrap_or_default();
assert!(
!red_engine.contains("served"),
"PRE-FIX BASELINE BROKEN: without dependency edges `served` must be \
invisible — that invisibility is the bug this work fixed. Got {red_engine:?}"
);
// ── GREEN: the same resolve, same config, with the edges the fix added. ──
let green = resolve(&all, &cfg);
let engine_on = green
.enabled
.get("engine")
.unwrap_or_else(|| panic!("`engine` absent from the resolution: {:?}", green.enabled));
assert!(
engine_on.contains("served"),
"`served` is turned on by driver's edge and must resolve as ON, got {engine_on:?}"
);
// And it must name the sibling that lit it — a verdict with no provenance
// cannot be acted on.
assert_eq!(
green
.via_edge
.get(&("engine".to_string(), "served".to_string()))
.map(String::as_str),
Some("driver"),
"the resolution must attribute `served` to the edge from `driver`"
);
}
/// The control the fixture ships. `engine/dark` has the identical *shape* to
/// `served` — a `#[cfg(feature)] pub mod` over `#[test]` fns — and is lit by
/// nothing. A resolver that cannot separate the two is not a resolver, it is a
/// function that returns every feature.
#[test]
fn the_unlit_control_feature_stays_dark_under_every_declared_variant() {
let all = crates();
for v in variants() {
let cfg = config_for_variant(&all, &v, &[], None);
let on = resolve(&all, &cfg).enabled.get("engine").cloned().unwrap_or_default();
assert!(
!on.contains("dark"),
"variant `{}` lit the control feature `dark`, which nothing declares: {on:?}",
v.name
);
}
}
/// The fourth shape in `resolve`'s doc list: a cross-crate feature string
/// `alias/feat` written in the PARENT's feature table. `driver`'s
/// `deep = ["dep:engine-lib", "engine-lib/probe"]` is the only mention of
/// `probe` anywhere, and it names the RENAME, not the package.
#[test]
fn a_cross_crate_feature_string_lights_the_sibling_and_only_under_its_own_variant() {
let all = crates();
let deep = resolve(&all, &config_for_variant(&all, &variant("deep"), &[], None));
let on = deep.enabled.get("engine").cloned().unwrap_or_default();
assert!(
on.contains("probe"),
"`deep` must light `engine/probe` through `engine-lib/probe`, got {on:?}"
);
// Discrimination: `bench` activates the same edge but does NOT write
// `engine-lib/probe`, so `probe` must stay off there. Without this the test
// above passes for a resolver that turns on everything it can reach.
let bench = resolve(&all, &config_for_variant(&all, &variant("bench"), &[], None));
let on_b = bench.enabled.get("engine").cloned().unwrap_or_default();
assert!(
!on_b.contains("probe"),
"`bench` does not name `probe`; it must not be on: {on_b:?}"
);
}
// ─── the third verdict: COMPILED-ONLY is neither Run nor Dark ──────────────
fn report(all: &[CrateManifest], vs: &[(VariantSpec, Vec<String>)]) -> TestSurfaceReport {
audit_test_surface(
&fixture(),
"dep_edge_lit",
"guard",
all,
vs,
&MatrixArms::default(),
None,
)
}
fn row_verdict(r: &TestSurfaceReport, pkg: &str, feat: &str) -> RunVerdict {
r.rows
.iter()
.find(|x| x.package == pkg && x.feature == feat)
.unwrap_or_else(|| {
panic!(
"no row for {pkg}/{feat}; rows: {:?}",
r.rows.iter().map(|x| (&x.package, &x.feature)).collect::<Vec<_>>()
)
})
.verdict
}
/// The claim `testsurface.rs`'s module docs make, asserted on the produced
/// report rather than on prose: an edge-lit feature is COMPILED by a declared
/// variant and still never RUN, because cargo never builds a dependency's test
/// targets. Three states, not two.
#[test]
fn an_edge_lit_feature_is_compiled_only_and_the_unlit_one_is_dark() {
let all = crates();
let vs: Vec<(VariantSpec, Vec<String>)> =
variants().into_iter().map(|v| (v, Vec::new())).collect();
let r = report(&all, &vs);
assert_eq!(
row_verdict(&r, "engine", "served"),
RunVerdict::CompiledOnly,
"`served` is lit by the `bench` variant's edge but `engine` is never \
selected for testing — that is COMPILED-ONLY, not RUN and not DARK"
);
assert_eq!(
row_verdict(&r, "engine", "dark"),
RunVerdict::Dark,
"`dark` is lit by nothing at all"
);
// The distinction must survive into the human-facing text, naming the
// sibling and the fix — a COMPILED-ONLY row with no `lit_by` line is a
// verdict a reader cannot act on.
let served = r.rows.iter().find(|x| x.feature == "served").unwrap();
assert!(
served.lit_by.iter().any(|l| l.contains("driver") && l.contains("test-packages")),
"the COMPILED-ONLY row must name the lighting sibling and the fix: {:?}",
served.lit_by
);
// RED counterpart: strip the edges and the same report calls `served` dark,
// i.e. reports a feature the forge really does compile as never built.
let red = report(&without_dep_edges(&all), &vs);
assert_eq!(
row_verdict(&red, "engine", "served"),
RunVerdict::Dark,
"PRE-FIX BASELINE BROKEN: without edges the report must mis-call \
`served` DARK — the false negative this work removed"
);
}
// ─── hole 2: what a `tests` step actually selects ─────────────────────────
/// `dep_closure` is the honest bound on a variant's test selection. Asserted on
/// membership, not on a count that a closure returning everything would also
/// satisfy.
#[test]
fn the_build_closure_reaches_the_sibling_the_variant_only_links() {
let all = crates();
assert_eq!(
dep_closure(&all, "driver"),
BTreeSet::from(["engine".to_string()]),
"`cargo build -p driver` compiles `engine`"
);
assert!(
dep_closure(&all, "engine").is_empty(),
"`engine` is a leaf; a closure that walked edges backwards would fail here"
);
}
/// **Hole 2, on the fixture.** The `bench` variant's build compiles `engine`,
/// `engine` holds `#[test]` fns, and the variant's `tests` step selects exactly
/// one package — its own `-p`. Nothing runs `engine`'s tests, and `surface_gaps`
/// must say so.
#[test]
fn a_variant_leaves_the_sibling_it_compiles_unclaimed_by_any_test_run() {
let all = crates();
let bench = variant("bench");
// The selection is ONE package. This is the measured behaviour under test,
// not an assumption: `-p` is inherited and nothing widens it.
let cfg = config_for_variant(&all, &bench, &[], None);
assert_eq!(
cfg.selected,
BTreeSet::from(["driver".to_string()]),
"with no declared test-packages a variant's tests step runs exactly its own -p"
);
let tests_per_package = BTreeMap::from([("engine".to_string(), 5usize)]);
let gaps = surface_gaps(&all, &[(bench.clone(), Vec::new())], &tests_per_package);
assert_eq!(
gaps,
vec![SurfaceGap::Unclaimed {
variant: "bench".to_string(),
package: "engine".to_string(),
tests: 5,
}],
"the sibling the build compiles and nothing tests must be reported"
);
// GREEN counterpart: naming it in `test-packages` closes the gap, and the
// selection widens to both packages. If this did not change, `test-packages`
// would be inert.
let claimed = surface_gaps(
&all,
&[(bench.clone(), vec!["engine".to_string()])],
&tests_per_package,
);
assert!(claimed.is_empty(), "declaring the package must close the gap: {claimed:?}");
assert_eq!(
config_for_variant(&all, &bench, &["engine".to_string()], None).selected,
BTreeSet::from(["driver".to_string(), "engine".to_string()]),
"a declared test-package must actually enter the selection"
);
}
/// A package OUTSIDE the build's closure is the opposite error: testing it here
/// runs a configuration nothing ships. `Outsider` was unreachable in practice
/// because no declaration could ever populate `declared`.
#[test]
fn naming_a_package_outside_the_build_closure_is_reported_as_an_outsider() {
let all = crates();
let gaps = surface_gaps(
&all,
&[(variant("bench"), vec!["nonesuch".to_string()])],
&BTreeMap::new(),
);
assert!(
gaps.contains(&SurfaceGap::Outsider {
variant: "bench".to_string(),
package: "nonesuch".to_string(),
}),
"a package the build never compiles must be rejected, got {gaps:?}"
);
}