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

nordisk/facett

facett-map/tests/one_device_gate.rs

//! **ONE DEVICE OPT-IN, AND IT HAS A WORD FOR EVERY BOX WE RUN ON.** Lane GG #5.
//!
//! # The defect
//!
//! Three test files declared their own `gated()` over `$FACETT_TEST_GPU`, and **two of
//! the three answered differently**:
//!
//! ```text
//! gpu_lane_paint_order.rs   mode == "discrete" || mode == "software"   + a FAILED matrix row on skip
//! blit_cost.rs              mode == "discrete" || mode == "software"   + a FAILED matrix row on skip
//! gpu_lane_share.rs         env::var(GATE).is_ok()                     + NO row at all
//! ```
//!
//! That is the LAW 5 twin arriving as a **semantic** difference rather than a duplicated
//! body, which is the harder kind to see: one `FACETT_TEST_GPU=integrated` ran one file
//! and skipped the other two, and in those two a skip is filed as a FAILED row **on
//! purpose** (a skip must never read as a pass). So the vocabulary gap did not present as
//! "the tests did not run", it presented as a red board.
//!
//! # Why it mattered on 2026-09-05
//!
//! The owner's client box is a **Radeon 890M** — an INTEGRATED GPU — and the vocabulary had
//! no word for it. Every device oracle in this crate has therefore only ever run on oden's
//! discrete 4090, including the three written this morning for the defects the owner sees on
//! the 890M. The only ways to run them on the machine that shows the bugs were to type
//! `FACETT_TEST_GPU=discrete` — a false statement about the hardware, in the variable
//! whose entire job is to describe the hardware — or to accept a board of red rows.
//!
//! Nothing downstream ever needed the lie: `adapter_wgpu` *prefers* a discrete adapter, it
//! does not require one, and on a single-adapter box it selects that adapter and prints
//! which one answered.
//!
//! # The two claims
//!
//! 1. The vocabulary admits every box the fleet owns.
//! 2. No test file declares a `gated` of its own any more — because a fourth copy is how
//!    the first three disagreements happened.

/// The gate under test, included the same way its callers include it.
#[path = "common/gpu_gate.rs"]
mod gpu_gate;

/// **A word for every box.** oden is `discrete`, t14s is `integrated`, a CI runner on
/// lavapipe is `software`. A vocabulary that omits one of them is a box that cannot run
/// the suite honestly.
#[test]
fn the_gate_has_a_word_for_every_box_the_fleet_owns() {
    for want in ["discrete", "integrated", "software"] {
        assert!(
            gpu_gate::RUNNING_CLASSES.contains(&want),
            "`{want}` must be a value the gate accepts — it is a machine we test on. \
             Accepted: {:?}",
            gpu_gate::RUNNING_CLASSES
        );
    }
    assert!(
        !gpu_gate::RUNNING_CLASSES.contains(&""),
        "the EMPTY value must stay a skip: unset means nobody opted this host in, and a \
         gate that reads absence as consent runs the device suite on every CI box that \
         never asked for it"
    );
}

/// **NO SECOND WRITER.** A test file that grows its own `fn gated` is how the three
/// disagreements above happened, and the next one will disagree too.
///
/// Comments are stripped before matching: this file and `common/gpu_gate.rs` both discuss
/// `fn gated` in prose, and a gate that matched its own explanation would be green over a
/// tree that had put the copies back.
#[test]
fn no_test_file_declares_a_gate_of_its_own() {
    let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests");
    let mut offenders = Vec::new();
    let mut checked = 0usize;
    for entry in std::fs::read_dir(&dir).expect("the tests directory is readable") {
        let path = entry.expect("a readable entry").path();
        if path.extension().is_none_or(|e| e != "rs") {
            continue;
        }
        // This file itself carries both needles as string LITERALS — they are the search
        // terms three lines below — so it matches itself. Skipping the guard is not a
        // loophole: the guard is what the other files are measured against, and it holds
        // no `gated` of its own.
        if path.file_name().is_some_and(|f| f == "one_device_gate.rs") {
            continue;
        }
        let src = std::fs::read_to_string(&path).expect("a readable test file");
        checked += 1;
        if declares_its_own_gate(&src) {
            offenders.push(path.file_name().unwrap().to_string_lossy().to_string());
        }
    }
    assert!(
        checked > 10,
        "only {checked} test files scanned — the walk found nothing, so a green here \
         proves nothing about the tree"
    );
    assert!(
        offenders.is_empty(),
        "these files read $FACETT_TEST_GPU themselves instead of delegating to \
         common/gpu_gate.rs: {offenders:?}. Three copies is how two of them ended up \
         disagreeing about whether `integrated` means run."
    );
}

/// Does this test file's source carry a `gated` of its own, i.e. read the device opt-in
/// itself instead of delegating to `common/gpu_gate.rs`?
fn declares_its_own_gate(src: &str) -> bool {
    let code: String =
        src.lines().map(|l| l.split("//").next().unwrap_or("")).collect::<Vec<_>>().join("\n");
    // The shared wrapper each file keeps is `fn gated(..) -> bool { gpu_gate::gated(..) }`
    // — a one-line delegation, which is fine and is not a second writer. A BODY that
    // reads the environment itself is, and so is a file that names the opt-in at all (a
    // wrapper that hands the read to a helper of its own). The rest of a file may read
    // the environment for other things — `$HOME` for a LOOK screenshot path — and that
    // is not a gate.
    let Some(start) = code.find("fn gated") else {
        return false;
    };
    gated_body(&code[start..]).contains("env::var") || code.contains("FACETT_TEST_GPU")
}

/// The text of the function that starts `code`, from its first `{` to the matching `}`
/// (the rest of `code` if the braces never balance, so a malformed body stays visible).
fn gated_body(code: &str) -> &str {
    let Some(open) = code.find('{') else {
        return code;
    };
    let mut depth = 0usize;
    for (i, c) in code[open..].char_indices() {
        match c {
            '{' => depth += 1,
            '}' => {
                depth -= 1;
                if depth == 0 {
                    return &code[open..=open + i];
                }
            }
            _ => {}
        }
    }
    &code[open..]
}

/// **The guard tells a copy of the gate from a file that reads `$HOME`.** The publish prep
/// (`af2f472d`) turned the LOOK screenshot paths in `gpu_lane_paint_order.rs` and
/// `gpu_lane_two_panes.rs` from `/home/<owner>/scratch/...` into
/// `std::env::var("HOME")` — a read of the environment that is not the device opt-in —
/// and the file-wide match named both files as second writers of `$FACETT_TEST_GPU`.
#[test]
fn the_guard_tells_a_home_path_from_a_copy_of_the_gate() {
    let delegating = "fn gated(name: &str) -> bool {\n    gpu_gate::gated(\"facett-map\", name)\n}\n";
    let home_path = "fn look() {\n    let p = format!(\"{}/scratch/a.png\", std::env::var(\"HOME\").unwrap_or_default());\n}\n";
    assert!(!declares_its_own_gate(delegating), "a one-line delegation is not a second writer");
    assert!(
        !declares_its_own_gate(&format!("{delegating}{home_path}")),
        "a delegating file that builds a screenshot path from $HOME is not a second writer"
    );
    // The red arms: a body that reads the opt-in itself, and a wrapper that hands the
    // read to a helper of its own, are both copies of the gate.
    let own_body = "fn gated(name: &str) -> bool {\n    let mode = std::env::var(GATE).unwrap_or_default();\n    mode == \"discrete\"\n}\n";
    let via_helper = "fn gated(name: &str) -> bool {\n    mode() == \"discrete\"\n}\nfn mode() -> String {\n    std::env::var(\"FACETT_TEST_GPU\").unwrap_or_default()\n}\n";
    assert!(declares_its_own_gate(own_body), "a gated BODY reading the environment is a second writer");
    assert!(
        declares_its_own_gate(&format!("{via_helper}{home_path}")),
        "a gated that reads $FACETT_TEST_GPU through a local helper is a second writer"
    );
}