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

nordisk/facett

facett-map3d/tests/the_gpu_proofs_are_dark_by_default.rs

//! **Every `tests/*.rs` this crate hides behind `wgpu` is written down, and the
//! list may not grow in silence.**
//!
//! `facett-map3d` declares `default = []`, so a plain `cargo test -p facett-map3d`
//! compiles every `#![cfg(feature = "wgpu")]` file into a test binary that reports
//! `running 0 tests` and exits 0. Cargo says nothing; the run is green; the
//! binaries are there. The only thing missing is the tests.
//!
//! MEASURED on oden:
//!
//! * 2026-08-03 (stinky `korpdep-11`): 179 tests ran, **13** binaries reported
//!   `running 0 tests`.
//! * 2026-08-22, `origin/main` `25c17413`, same command: 262 tests ran, **18**
//!   binaries reported `running 0 tests`. Five more went dark in nineteen days and
//!   nothing said so.
//!
//! And of all the file classes to lose, this is the one that hurts: the dark
//! eighteen are the depth buffer, the scissor rect, the post-FX bypass, the shadow
//! softness, the sky LUT, SSAO, z-fighting, the water and flight-sim proofs — the
//! whole list of things that can only break ON the GPU, which is exactly what a CPU
//! test run cannot substitute for.
//!
//! # What this gate is, and what it deliberately is NOT
//!
//! It does **not** claim the eighteen run. It claims the SET IS KNOWN. A file that
//! goes dark is a decision — "this proof needs an adapter" — and a decision gets
//! written down. Silence is what turned 13 into 18.
//!
//! So: the roster below is the written decision, and the assertion is set EQUALITY
//! in both directions.
//!
//! * A **new** `#![cfg(feature = "wgpu")]` file fails this test until it is added
//!   here — the drift that happened five times is now loud the first time.
//! * A file that **stops** being gated (or is deleted, or is renamed) fails it too,
//!   asking for the stale line to go. A dead excuse hides the next real one.
//!
//! In particular, if `facett-map3d` ever gains `default = ["wgpu"]`, this test goes
//! red with all eighteen names and the fix is to DELETE the roster and this file:
//! the debt it tracks would be paid, and a gate that outlives its defect is itself
//! rot. That is the intended way for it to die.
//!
//! The gate itself is NOT feature-gated — it is the one file here that must compile
//! and run in every arm, because a guard that hides behind the feature it is
//! guarding cannot report anything.
//!
//! Run the dark eighteen with:
//!
//! ```text
//! cargo test -p facett-map3d --features wgpu
//! ```

use std::collections::BTreeSet;
use std::path::{Path, PathBuf};

/// The test files this crate compiles only with `wgpu` on — the GPU proofs.
///
/// Grouped by what they prove, because a bare list of eighteen names does not tell
/// the next reader what is being lost.
const DARK_BY_DESIGN: &[&str] = &[
    // Depth, ordering and clipping — the things the CPU painter approximates with a
    // centroid sort and cannot prove.
    "gpu_depth",
    "gpu_scissor",
    "zfight",
    // Lighting and post-processing: nothing below exists on the CPU path at all.
    "bloom_proof",
    // Bloom OFF as a NO-OP, not merely as a saving: it dirties the bloom ping-pong with
    // real glow on one renderer and then asserts a bloom-off frame is byte-identical to a
    // fresh one. Every word of that needs a device — a pass count read back from the
    // encoder and two 480x480 frames off the same adapter.
    "bloom_off_costs_nothing",
    "postfx_bypass",
    "shadow_softness",
    "sky_lut_proof",
    "sky_proof",
    "ssao_proof",
    // The flight-sim scene, which is GPU-only end to end.
    "flightsim_phase1",
    "flightsim_shadows",
    "flightsim_water",
    "flythrough_render",
    "water_altitude_blob",
    // Adapter-level plumbing: the clock, the stats sampler, the geometry swap and
    // the overlay's frame stability all read back from a real device.
    "gpu_clock",
    "gpu_geometry_swap",
    "gpu_stats_sampling",
    "overlay_frame_stability",
    // The 1-in-16-frame software scene analysis, timed on the device it hitches on
    // (`13d47d59` bounded it to a 1024-triangle sample). The measurement is a wall clock
    // around a real `prepare`, so it has nothing to say without an adapter. Landed
    // wholly gated and unlisted — which is exactly the drift this roster exists to
    // catch, and it caught it.
    "gpu_analyze_spike",
    // Whether a mesh mutation ever REACHES the device. `gpu_geometry_swap` above proves
    // the renderer replaces a payload it is handed with a new build stamp; this one proves
    // a new payload is built and handed over at all, and its oracle is the vertex count
    // the next `draw` will use — so it cannot exist without an adapter.
    "route_reaches_the_gpu",
];

// `lane_flag` is deliberately ABSENT: only its GPU arm carries `#[cfg(feature = "wgpu")]`,
// so the file is not wholly gated and its CPU + Pending claims run in the default arm.
// That is the distinction `wholly_gated` draws and the reason it draws it — a binary that
// still reports two real tests has not gone dark.

/// This crate's `tests/` directory, resolved at compile time so the test works from
/// any cwd and from a worktree anywhere.
fn tests_dir() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR")).join("tests")
}

/// Every `tests/*.rs` whose WHOLE FILE is behind `wgpu` — an inner attribute
/// (`#![cfg(feature = "wgpu")]`), which is what empties the binary. An inner
/// `#[cfg]` on a single `fn` only silences that one test, so it is deliberately not
/// matched here: this gate is about binaries that hold nothing.
fn wholly_gated() -> BTreeSet<String> {
    let mut out = BTreeSet::new();
    let mut all = 0usize;
    for entry in std::fs::read_dir(tests_dir()).expect("facett-map3d/tests must be readable") {
        let path = entry.expect("a readable dir entry").path();
        if path.extension().and_then(|e| e.to_str()) != Some("rs") {
            continue;
        }
        all += 1;
        let src = std::fs::read_to_string(&path).expect("a readable test file");
        let gated = src.lines().any(|l| {
            let l = l.trim();
            l.starts_with("#![cfg(") && l.contains("feature") && l.contains("\"wgpu\"")
        });
        if gated {
            out.insert(
                path.file_stem()
                    .and_then(|s| s.to_str())
                    .expect("a utf-8 test file name")
                    .to_string(),
            );
        }
    }
    // NON-VACUOUS: the scan must have seen a real directory. Without this, a wrong
    // path returns an empty set and "no unexpected dark files" reads as PASS — the
    // shape this crate's own `assert!(r.drew())` findings are about.
    assert!(
        all >= 40,
        "the scan found only {all} test files in {} — that is not this crate's tests/ \
         directory, so every verdict below would be over an empty world",
        tests_dir().display()
    );
    out
}

/// The roster is exactly the dark set — in both directions.
#[test]
fn the_dark_test_files_are_exactly_the_written_roster() {
    let found = wholly_gated();
    let roster: BTreeSet<String> = DARK_BY_DESIGN.iter().map(|s| (*s).to_string()).collect();
    assert_eq!(
        roster.len(),
        DARK_BY_DESIGN.len(),
        "DARK_BY_DESIGN lists a name twice: {:?}",
        DARK_BY_DESIGN
    );

    let newly_dark: Vec<&String> = found.difference(&roster).collect();
    assert!(
        newly_dark.is_empty(),
        "these tests/*.rs are behind `#![cfg(feature = \"wgpu\")]` and are NOT in the \
         roster: {newly_dark:?}. A default `cargo test -p facett-map3d` compiles each \
         of them to a binary that reports `running 0 tests` and exits 0 — which is how \
         this crate went from 13 dark binaries to 18 without anyone noticing. Either \
         un-gate the file, or add it here and say what GPU behaviour is going dark."
    );

    let stale: Vec<&String> = roster.difference(&found).collect();
    assert!(
        stale.is_empty(),
        "the roster names files that are NOT dark any more (deleted, renamed, or the \
         gate came off): {stale:?}. Delete those lines — a stale excuse is the place \
         the next real gap hides. If `default = [\"wgpu\"]` landed, delete the whole \
         roster and this file with it."
    );
}

/// The oracle can tell the two classes apart.
///
/// A scan that matched every file, or no file, would satisfy the equality above just
/// as happily against a broken matcher — so assert that both sides are populated and
/// that a specific always-compiled file really is on the light side.
#[test]
fn the_scan_separates_dark_files_from_light_ones() {
    let found = wholly_gated();
    assert!(
        !found.is_empty(),
        "the matcher found NO wholly-gated file, so the equality check above is over \
         an empty set and can never report red"
    );
    let all: usize = std::fs::read_dir(tests_dir())
        .expect("tests/ readable")
        .filter_map(|e| e.ok())
        .filter(|e| e.path().extension().and_then(|x| x.to_str()) == Some("rs"))
        .count();
    assert!(
        found.len() < all,
        "the matcher flagged all {all} test files as dark — it is matching something \
         other than the inner cfg attribute"
    );
    // THIS file is the control: it must never be gated, or the guard hides behind the
    // feature it guards.
    assert!(
        !found.contains("the_gpu_proofs_are_dark_by_default"),
        "this gate has been feature-gated — it must run in every arm, or it reports \
         nothing in the arm where the defect lives"
    );
}