xtask/tests/wasm_bundle_installs_the_lanes_it_selects.rs
//! **The OTHER half of the GPU path: a lane that is selected but never installed.**
//!
//! `wasm_bundle_has_gpu_features.rs` — this file's sibling and the row before it —
//! asserts that `facet-wrapped/Cargo.toml` turns the components' GPU features ON. That
//! is necessary and it is not sufficient, and the gap between the two cost a day.
//!
//! # What was measured, on oden's RTX 4090, 2026-09-06
//!
//! The bundle mounted `osm3d` inside an iframe carrying Streamlit 1.60.0's exact
//! `sandbox`/`allow` strings and reported, off the running page:
//!
//! ```text
//! facet_mounted: "osm3d" facet_error: ""
//! facet_canvas_api: "webgpu" backend: "wgpu-vello"
//! gpu_lane_selected: true lane_flag: "cpu" ← the defect
//! ```
//!
//! Not `pending` — so a frame really had painted, and it had painted on the CPU
//! painter. **Identically on the 4090 and on SwiftShader**, which is the signature of a
//! fault that is not a property of the adapter at all: a missing function call.
//!
//! Selecting a lane and installing its renderer are two acts and only the first was
//! being done. `with_gpu(true)` swaps the backend — that is what `gpu_lane_selected`
//! and `backend` report. `install_renderer` puts the renderer into the `RenderState`'s
//! `callback_resources`; **without it the paint callback no-ops**, so
//! `facett_map3d::gpu::renderer_installed()` is `false`,
//! `WgpuVelloBackend::paint` reports `used_gpu = false`, and `lane_flag` answers a
//! perfectly honest `cpu`. Before the fix, `facet-wrapped/` contained ZERO occurrences
//! of `install_renderer` in `src/` or `tests/`.
//!
//! Red → green on the same box, same harness, same Chrome flags, two byte-distinct
//! bundles differing by one commit:
//!
//! ```text
//! RED f6a408a5… GREEN 65ba3f1a…
//! lane_flag cpu gpu
//! used_gpu false true
//! fps 30.48 60.00
//! ```
//!
//! (`visible_triangles` was 8 in BOTH arms and is deliberately not quoted as evidence:
//! it comes from the software geometry oracle that runs on either lane, so it is an
//! identity value here in LAW 2's sense. `fps` is the independent applied signal.)
//!
//! # Why this test is a source-shape test, and what that costs
//!
//! Said plainly rather than glossed: `eframe`/`egui_wgpu` are
//! `[target.'cfg(target_arch = "wasm32")'.dependencies]` of `facet-wrapped`, so the
//! rlib a native `cargo test` links **has no `RenderState` type in it at all** and the
//! mount body cannot be executed on the host. That is also exactly why
//! `facet-wrapped/tests/gpu_lane_is_observable.rs` could pass forever with the install
//! missing: its three assertions (`gpu_lane_selected == true`, `backend !=
//! "cpu-painter"`, `lane_flag == "pending"` before any frame) are all true of a bundle
//! that never dispatches, because on a host with no `RenderState` there is no frame to
//! observe. It proves the lane is WIRED and is structurally incapable of proving
//! anything DISPATCHED.
//!
//! So the host-side guard available is: **the manifest edges (read from cargo's own
//! parse) and the install calls (read from the source) must agree.** It cannot prove a
//! frame reached the GPU — the browser measurement above is what does that, and it is
//! recorded here so the number has a home. It CAN fail, and it fails on exactly the
//! change that caused the defect: deleting an install, or adding a fourth GPU edge to
//! the manifest without an install beside it.
use std::process::Command;
fn root() -> std::path::PathBuf {
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().to_path_buf()
}
/// The GPU edges the bundle declares, and the install each one needs.
///
/// The two graph surfaces share one entry point on purpose: `facett-graph3d` and
/// `facett-graphview` both route their node/edge cloud through facett-core's ONE
/// `graphcloud::cloud` renderer, whose `cloud_renderer_installed()` is what unlocks
/// `Graph3D`'s instanced fast path. Not a coincidence to be tidied away — it is the
/// LAW 5 seam, and a future third graph surface needs no new install.
///
/// The fourth row (2026-09-18) is a different kind of install and the same kind of
/// defect. `facett-graphnav/gpu` selects the compute-shader force layout; what it
/// needs installed is not a renderer but a LOAN of the host's device, because a
/// browser cannot block to make its own. Select the feature without the loan and the
/// selector finds no device — every large graph silently converges on wasm32's one CPU
/// thread, which is the state row 13 of `facet-wrapped-wheel.md` recorded.
/// The map rows (2026-09-28): the 2-D map lane, which `osm2d` (`OsmView`) and
/// `map` (`MapView`) select. It used to be deliberately absent (facett-map on default
/// features); the owner ruled that a map painting on the CPU in a headful browser is a
/// defect, so the manifest now enables it and the install sits beside the others.
/// The graphpan and graphnav `wgpu` rows (2026-09-28) put those node/edge clouds on the
/// same shared `graphcloud::cloud` renderer as the graph surfaces above.
const LANES: [(&str, &str, &str); 12] = [
("facett-flow", "wgpu", "facett_flow::gpu::install_renderer"),
("facett-pipeline", "wgpu", "facett_flow::gpu::install_renderer"),
("facett-plandag", "wgpu", "facett_flow::gpu::install_renderer"),
("facett-brokkrview", "wgpu", "facett_flow::gpu::install_renderer"),
("facett-graphpan", "wgpu", "graphcloud::cloud::install_cloud_renderer"),
("facett-map3d", "wgpu", "facett_map3d::gpu::install_renderer"),
("facett-map", "wgpu", "facett_map::gpu::install_renderer"),
("facett-geomap", "map-wgpu", "facett_map::gpu::install_renderer"),
("facett-graph3d", "wgpu", "graphcloud::cloud::install_cloud_renderer"),
("facett-graphview", "gpu", "graphcloud::cloud::install_cloud_renderer"),
("facett-graphnav", "gpu", "gpu_layout::install_host_device"),
("facett-graphnav", "wgpu", "graphcloud::cloud::install_cloud_renderer"),
];
/// The mount source, flattened to one line with runs of whitespace collapsed.
///
/// NORMALISED, and that is not a nicety — it is the lesson the sibling test wrote down
/// in blood: it was GREEN on the very manifest it existed to catch, because the phrase
/// it searched for happened to be line-wrapped. A call written across two lines by
/// rustfmt is the same call.
fn mount_source_flat() -> String {
let src = std::fs::read_to_string(root().join("facet-wrapped/src/wasm.rs"))
.expect("facet-wrapped/src/wasm.rs is readable");
src.split_whitespace().collect::<Vec<_>>().join(" ")
}
/// Everything inside `fn install_gpu_lanes(...) { ... }`, flattened. Empty string when
/// the function does not exist at all — which is the state this row found.
fn install_body_flat() -> String {
let flat = mount_source_flat();
let Some(start) = flat.find("fn install_gpu_lanes(") else {
return String::new();
};
let after = &flat[start..];
let Some(open) = after.find('{') else { return String::new() };
let mut depth = 0usize;
for (i, c) in after[open..].char_indices() {
match c {
'{' => depth += 1,
'}' => {
depth -= 1;
if depth == 0 {
return after[open + 1..open + i].to_string();
}
}
_ => {}
}
}
String::new()
}
fn metadata() -> serde_json::Value {
let out = Command::new("cargo")
.current_dir(root())
.args(["metadata", "--no-deps", "--format-version", "1"])
.output()
.expect("run cargo metadata");
assert!(out.status.success(), "cargo metadata failed: {}", String::from_utf8_lossy(&out.stderr));
serde_json::from_slice(&out.stdout).expect("cargo metadata emits JSON")
}
/// The GPU edges the manifest ACTUALLY declares right now, read from cargo's parse and
/// never from the TOML text. This is the half that makes the test track the manifest
/// instead of restating it: turn an edge off and this shrinks, and the pairing test
/// below stops requiring its install.
fn declared_gpu_edges() -> Vec<(&'static str, &'static str)> {
let md = metadata();
let deps = md["packages"]
.as_array()
.expect("packages")
.iter()
.find(|p| p["name"] == "facet-wrapped")
.expect("facet-wrapped is a workspace member")["dependencies"]
.as_array()
.expect("dependencies")
.clone();
LANES
.iter()
.filter(|(name, feature, _)| {
deps.iter().any(|d| {
d["name"] == *name
&& d["features"]
.as_array()
.is_some_and(|a| a.iter().any(|f| f.as_str() == Some(*feature)))
})
})
.map(|(name, _, install)| (*name, *install))
.collect()
}
#[test]
fn every_gpu_lane_the_manifest_enables_has_an_install_beside_it() {
let body = install_body_flat();
assert!(
!body.is_empty(),
"facet-wrapped has no `install_gpu_lanes` at all. That was the state on \
2026-09-06 and it is what made a 4090 report `lane_flag: \"cpu\"` behind a \
WebGPU canvas: the bundle selected three GPU lanes and installed none of them."
);
let mut missing = Vec::new();
for (crate_name, install) in declared_gpu_edges() {
if !body.contains(install) {
missing.push(format!("{crate_name} → {install}"));
}
}
assert!(
missing.is_empty(),
"these GPU lanes are SELECTED by the manifest and never INSTALLED: {missing:?}\n\
The component will report `gpu_lane_selected: true` and `backend: \"wgpu-vello\"` \
and paint every frame on the CPU painter, on any adapter, with no error."
);
}
#[test]
fn the_install_is_actually_called_from_the_mount() {
// A function nobody calls is the hollow guard's own shape, and it would satisfy the
// test above completely. So: the mount's `wgpu_render_state` block must call it.
let flat = mount_source_flat();
assert!(
flat.contains("install_gpu_lanes(rs)"),
"`install_gpu_lanes` is defined but never called from the mount. The \
`RenderState` is already in hand at the `cc.wgpu_render_state` block — before \
this row the ONLY thing done with it was `record_adapter`, which names the \
device and puts nothing on any lane."
);
}
#[test]
fn no_lane_is_installed_that_the_bundle_does_not_select() {
// The reverse lie, and it is worth a test of its own: installing a renderer for a
// lane the manifest does not enable would register it with
// `facett_core::render::lane` and let an About box report a GPU lane that no
// component can reach. `facett-map`'s 2-D GPU lane was the live case until
// 2026-09-28, when the manifest started enabling it (owner ruling: a map that paints
// on the CPU in a headful browser is a defect); remove the feature and this refuses
// the install again.
let body = install_body_flat();
let selected = declared_gpu_edges();
for (crate_name, _, install) in LANES {
// An install shared with a SELECTED lane (the one graph cloud) is required by it.
if !selected.iter().any(|(_, i)| *i == install) {
assert!(
!body.contains(install),
"{crate_name}'s renderer is installed but the manifest does not enable \
its GPU feature — that registers a lane nothing can dispatch to"
);
}
}
// The 2-D map lane is now SELECTED (the table's facett-map/facett-geomap rows), so
// the loop above holds it: its install may appear only while the manifest enables it.
assert!(
selected.iter().any(|(n, _)| *n == "facett-map")
|| !body.contains("facett_map::gpu::install_renderer"),
"facett-map's 2-D GPU lane is installed, but the manifest takes facett-map on \
default features — that renderer is not in this binary"
);
}
// ── The SIBLING entry point: facett-demo's gh-pages bundle ─────────────────────
//
// Found 2026-09-18, fixed 2026-09-19: `facett-demo/src/main.rs::wasm_start` selected
// `map-wgpu,map3d-wgpu` (the declared `DEMO_WASM_FEATURES` axis) and made NO install
// call at all — its comment still said "no wgpu RenderState on the glow web path" from
// before the WebGPU backend landed. The exact defect the tests above end for the
// wheel, alive one crate over. Same shape of guard: the axis the build-thing declares
// (one writer; the xtask reads it) against the body of `wasm_install_gpu_lanes`.
/// facett-demo feature → the install it needs inside `wasm_install_gpu_lanes`.
const DEMO_LANES: [(&str, &str); 6] = [
("map-wgpu", "facett::map::gpu::install_renderer"),
("map3d-wgpu", "facett::map3d::gpu::install_renderer"),
("gpu", "install_cloud_renderer"),
// The 2-D GraphView draws through the SAME graphcloud renderer as `gpu`.
("graph-wgpu", "feature = \"graph-wgpu\"))] facett::core::render::gpu::graphcloud::cloud::install_cloud_renderer"),
("graph-layout-gpu", "facett_graphnav::install_layout_device"),
// Falsett's resident curve/packet renderer (facett-flow), 2026-10-04.
("flow-wgpu", "facett::flow::gpu::install_renderer"),
];
fn demo_source_flat() -> String {
let src = std::fs::read_to_string(root().join("facett-demo/src/main.rs"))
.expect("facett-demo/src/main.rs is readable");
src.split_whitespace().collect::<Vec<_>>().join(" ")
}
fn demo_install_body_flat() -> String {
let flat = demo_source_flat();
let Some(start) = flat.find("fn wasm_install_gpu_lanes(") else {
return String::new();
};
let after = &flat[start..];
let Some(open) = after.find('{') else { return String::new() };
let mut depth = 0usize;
for (i, c) in after[open..].char_indices() {
match c {
'{' => depth += 1,
'}' => {
depth -= 1;
if depth == 0 {
return after[open + 1..open + i].to_string();
}
}
_ => {}
}
}
String::new()
}
#[test]
fn the_pages_demo_installs_every_gpu_lane_its_declared_wasm_axis_selects() {
let body = demo_install_body_flat();
assert!(
!body.is_empty(),
"facett-demo has no `wasm_install_gpu_lanes` — the state of `wasm_start` until \
2026-09-19: GPU features selected, nothing installed, every map/graph pane on \
the gh-pages demo painting on the CPU behind a WebGPU canvas."
);
let axis = facett_build_thing::DEMO_WASM_FEATURES;
let mut missing = Vec::new();
for (feature, install) in DEMO_LANES {
let selected = axis.contains(&feature);
let installed = body.contains(install);
if selected && !installed {
missing.push(format!("{feature} → {install}"));
}
assert!(
selected || !installed,
"`wasm_install_gpu_lanes` installs {install} but `{feature}` is not on the \
declared wasm axis {axis:?} — a lane nothing can dispatch to"
);
}
assert!(
missing.is_empty(),
"the `facett-demo-wasm` row selects these GPU lanes and `wasm_start` never installs \
them: {missing:?}"
);
// Every lane on the axis must also be a KNOWN lane here, so a fifth feature cannot be
// added to the axis without deciding what its install is.
for f in axis {
assert!(
DEMO_LANES.iter().any(|(n, _)| *n == f),
"`{f}` is on DEMO_WASM_FEATURES but this guard does not know what it installs — \
add its row to DEMO_LANES"
);
}
}
#[test]
fn the_pages_demo_calls_its_install_from_the_mount() {
let flat = demo_source_flat();
let start = flat.find("pub fn wasm_start(").expect("wasm_start exists");
assert!(
flat[start..].contains("wasm_install_gpu_lanes(rs)"),
"`wasm_install_gpu_lanes` exists but `wasm_start` never calls it from its \
`cc.wgpu_render_state` block"
);
}