Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-testmatrix/tests/required_features_gate.rs

//! **The gate cargo does not announce: `required-features`.**
//!
//! `gatedtests::classify` read [`TestTarget::required_features`] out of
//! `cargo metadata` and never once consulted it in the verdict. A field parsed
//! and dropped is worse than one never read: the code looks like it handles the
//! case, so nobody checks — and this one is the QUIETEST of the four gate
//! sources. An unsatisfied `#![cfg]` at least compiles the file to an empty
//! binary that prints `running 0 tests ... ok`; an unsatisfied
//! `required-features` makes cargo skip the target with **no output at all**.
//! Worse still, such a target usually carries no crate-level `#![cfg]` — so
//! `classify` bailed on its very first line and the target produced no row of
//! any kind.
//!
//! # Measured, 2026-08-26, over every repo under `~/git`
//!
//! `cargo metadata --no-deps` in each workspace, counting `test`-kind targets
//! with a non-empty `required-features`:
//!
//! | repo | package | target | required-features | fns | before | after |
//! |---|---|---|---|---|---|---|
//! | holger | holger-server-cli | `appliance_gate` | `appliance` | 6 | *no row* | **Silenced** |
//! | dwarves | dwarves | `min_req_floor_live` | `release` | 4 | *no row* | **Silenced** |
//! | facett | facett | `matrix` | `model3d,docview,video,plotters` | 8 | *no row* | ViaEdge |
//! | facett | facett | `compliance` | `model3d,plotters` | 3 | *no row* | ViaEdge |
//! | facett | facett | `coherence` | `plotters` | 5 | *no row* | ViaEdge |
//! | facett | facett | `umbrella_exports` | `model3d` | 3 | *no row* | ViaEdge |
//! | gunnar | gunnar-lfs | `interop` | `fs` | 4 | *no row* | ViaEdge |
//! | gunnar | gunnar-server | `appliance_container_robot` | `wg-client` | 1 | *no row* | Default |
//! | gunnar | gunnar-server | `appliance_matrix_rows` | `wg-client` | 1 | *no row* | Default |
//!
//! **9 targets in 4 repos, and not one of them carries a crate-level `#![cfg]`**
//! — so all nine were invisible. (The 2026-08-25 skid-forge note said 12 in 7;
//! re-measured here it is 9 in 4, or 10 in 5 counting this crate's own
//! `broken_target` fixture.)
//!
//! # Why five of the nine are NOT red, and why that matters more than the two that are
//!
//! A `default`-closure-only reading would have called facett's four umbrella
//! targets and `gunnar-lfs/interop` SILENCED. That is FALSE: `facett-demo`
//! depends on `facett` with `features = ["model3d", "docview", "video",
//! "plotters"]`, and `gunnar-cli` on `gunnar-lfs` with `features = ["fs"]`, so
//! cargo's workspace-wide feature unification really does build and run all five
//! under a plain `cargo test --workspace`. A detector that reports a live test as
//! dark is a detector people switch off. They get [`GateVerdict::ViaEdge`] — a
//! pass that names the sibling holding the file up.
//!
//! # RED-when-broken
//!
//! Both fixtures below reported **nothing at all** before this change:
//! `audit_repo` on `broken_target` returned `files: []`, so
//! `assert_no_silenced_tests` was GREEN on a workspace with a test target cargo
//! never compiles. Revert `classify`'s `required_features` handling and the first
//! test here fails on `silenced().len() == 1` (it becomes 0). Delete the
//! `resolved` argument's `ViaEdge` branch and the second fails the other way:
//! `gpu_probe` becomes SILENCED, the false red.
//!
//! Deliberately NOT feature-gated — see `gated_tests_guard.rs` next door.

use std::path::PathBuf;

use nornir_testmatrix::{audit_repo, status, GateVerdict, ASPECT_GATED_TESTS};

fn fixture(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests").join("fixtures").join(name)
}

fn audit(name: &str) -> nornir_testmatrix::GatedTestReport {
    let dir = fixture(name);
    assert!(dir.join("Cargo.toml").exists(), "fixture {name} exists at {}", dir.display());
    audit_repo(&dir, "required-features-run").unwrap_or_else(|e| panic!("audit {name}: {e:#}"))
}

/// `broken_target/tests/gpu_only.rs` — holger's `appliance_gate` shape exactly:
/// `required-features = ["gpu"]`, `gpu` not in `default`, **no crate-level
/// `#![cfg]`**, no arms file, no sibling edge. Cargo skips it in silence.
#[test]
fn a_required_features_target_nothing_turns_on_is_red() {
    let rep = audit("broken_target");

    assert!(
        !rep.is_green(),
        "a target cargo never compiles must FAIL the gate — {}",
        rep.summary()
    );

    let silenced = rep.silenced();
    assert_eq!(
        silenced.len(),
        1,
        "exactly one silenced target (got {:?}) — {}",
        silenced.iter().map(|f| &f.path).collect::<Vec<_>>(),
        rep.summary()
    );
    let f = silenced[0];
    assert_eq!(f.target, "gpu_only");
    assert_eq!(f.crate_name, "broken_target");
    assert!(f.path.ends_with("tests/gpu_only.rs"), "repo-relative path: {}", f.path);

    // The gate is the MANIFEST's, not the file's — the file carries no `#![cfg]`
    // at all, and a message that claimed one would send the reader to the wrong
    // place.
    assert_eq!(f.cfg, "", "gpu_only.rs has no crate-level cfg");
    assert_eq!(f.required_features, vec!["gpu".to_string()]);
    assert_eq!(f.missing_required, vec!["gpu".to_string()]);
    assert!(f.missing_features.is_empty(), "no cfg features to miss");
    assert_eq!(f.hidden_tests, 1);
    assert_eq!(f.gate_phrase(), "required-features = [gpu]");

    let msg = f.message();
    assert!(msg.contains("SILENTLY SKIPS"), "the message names the real mechanism: {msg}");
    assert!(msg.contains("gpu"), "and the feature: {msg}");

    // And it reaches the sink as a RED row on the gated-tests aspect.
    let row = rep
        .rows()
        .into_iter()
        .find(|r| r.test_name == "gated-tests::gpu_only")
        .expect("a row for the skipped target");
    assert_eq!(row.status, status::FAIL);
    assert!(status::is_red(&row.status));
    assert_eq!(row.aspect, ASPECT_GATED_TESTS);
    assert_eq!(row.metric, 1.0, "metric carries the hidden-test count");

    // The three ungated siblings (compiles.rs, does_not.rs, also_does_not.rs) are
    // NOT this guard's business, broken or not.
    assert_eq!(rep.files.len(), 1, "only the gated target is a finding: {}", rep.summary());
    assert_eq!(rep.scanned, 4, "all four test targets were looked at");
}

/// The same manifest gate, held up by a SIBLING'S dependency edge: `rfe_driver`
/// names `rfe_engine` with `features = ["gpu"]`, so `cargo test --workspace`
/// really does run `gpu_probe`. Calling that silenced is the false red this
/// verdict exists to refuse — and leaving it indistinguishable from `Default`
/// would hide that nothing declares the route.
#[test]
fn a_required_features_target_lit_only_by_a_dependency_edge_passes_and_names_the_sibling() {
    let rep = audit("required_features_edge");

    assert!(
        rep.is_green(),
        "the edge really does turn `gpu` on — reporting it dark would be a false red: {}",
        rep.summary()
    );

    let edge = rep.via_edge();
    assert_eq!(
        edge.len(),
        1,
        "exactly one edge-lit target (got {:?}) — {}",
        edge.iter().map(|f| &f.path).collect::<Vec<_>>(),
        rep.summary()
    );
    let f = edge[0];
    assert_eq!(f.target, "gpu_probe");
    assert_eq!(f.crate_name, "rfe_engine");
    assert_eq!(f.verdict, GateVerdict::ViaEdge);
    assert_eq!(f.required_features, vec!["gpu".to_string()]);
    assert_eq!(f.missing_required, vec!["gpu".to_string()]);
    assert_eq!(
        f.selected_via.as_deref(),
        Some("rfe_driver"),
        "the report names the sibling whose edge holds the file up"
    );
    assert_eq!(f.hidden_tests, 2);

    let msg = f.message();
    assert!(msg.contains("rfe_driver"), "the sibling is named in the line: {msg}");
    assert!(msg.contains("UNDECLARED"), "and the line says the route is undeclared: {msg}");

    // A pass, so it must not be counted as damage.
    assert!(rep.silenced().is_empty());
    assert_eq!(rep.hidden_tests(), 0);
    let row = rep
        .rows()
        .into_iter()
        .find(|r| r.test_name == "gated-tests::gpu_probe")
        .expect("a row for the edge-lit target");
    assert_eq!(row.status, status::PASS);

    // The ungated `plain` target is not a finding.
    assert_eq!(rep.files.len(), 1, "only the gated target is a finding: {}", rep.summary());
    assert_eq!(
        rep.scanned, 2,
        "both of the engine's test targets were looked at: {}",
        rep.summary()
    );

    // The summary states the new axis outright, so a reader of a green run still
    // sees that something is being held up by an undeclared edge.
    let s = rep.summary();
    assert!(s.contains("1 of them by `required-features`"), "{s}");
    assert!(s.contains("1 run only through a dependency edge"), "{s}");
}