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"
);
}