dwarves-gui/tests/robot_warehouse_proxy_live.rs
//! **ROBOT-UI (LAW): the host-only panes render LIVE warehouse data THROUGH the host.**
//!
//! The host-only follow-up closed the fixture-degradation gap: the dwarves forge now
//! re-serves the `nornir.v1` READ surface (`crate::warehouse_proxy`) and the UI's
//! `warehouse_endpoint` is the FORGE endpoint. This headless robot proves the whole chain
//! end-to-end with NO cluster and NO window — a real dwarves PROXY in front of a mock
//! nornir, driving the SHIPPED shell (`build_native_app` — the exact builder `main` runs)
//! given ONLY the dwarves host:
//!
//! mock nornir Warehouse ── forwards ──> dwarves warehouse-proxy (:auto) ──> the UI panes
//!
//! 1. [`the_warehouse_pane_renders_live_data_via_the_host_given_only_dwarves_server`] —
//! `DWARVES_SERVER` is the dwarves PROXY (and `NORNIR_SERVER` is poisoned). The shell's
//! Data view, scanned, binds the upstream's `git_heat_facts` + `dep_graph_edges` rows
//! into panes and names the DWARVES host as its source — the data crossed dwarves →
//! its (mock) embedded nornir and came back live, and the UI reached the dwarves host,
//! never `:7878`. The same upstream still serves `symbol_facts` / `call_edges` (a
//! warehouse made before Mímir v2): the Warehouse navigator does NOT draw them — its
//! tiers are nornir's code room, this upstream has no code-room door, and the pane
//! draws no node and says so.
//!
//! Emits a `nornir-testmatrix` cell under `--features testmatrix`.
use dwarves_gui::{build_native_app, DWARVES_TABS};
use facett_core::Facet;
use nornir_warehouse_embed::testkit::spawn_mock_warehouse;
use serde_json::json;
/// The nornir address the UI must NEVER adopt — poisoned in the env as a booby-trap.
const NORNIR_POISON: &str = "http://nornir-poison.example:7878";
#[allow(unused_variables)]
fn matrix(check: &str, ok: bool, detail: &str) {
#[cfg(feature = "testmatrix")]
nornir_testmatrix::functional_status("dwarves-gui", check, ok, detail);
}
fn to_s(v: &[&str]) -> Vec<String> {
v.iter().map(|s| s.to_string()).collect()
}
/// A mock nornir Warehouse — the UPSTREAM the dwarves proxy fronts (stands in for the
/// embedded nornir). It serves two tables that are still written (`git_heat_facts`,
/// `dep_graph_edges`) AND the two a warehouse made before Mímir v2 still holds
/// (`symbol_facts`, `call_edges`), which nothing keeps current.
fn seeded_upstream() -> nornir_warehouse_embed::testkit::MockWarehouseServer {
let sym_cols = to_s(&[
"snapshot_id",
"repo",
"crate_name",
"module_path",
"item_kind",
"item_name",
"visibility",
"file",
"line",
]);
let symbol_facts = vec![
to_s(&[
"s1",
"edda",
"nornir-depgraph",
"crate",
"fn",
"build",
"pub",
"src/lib.rs",
"10",
]),
to_s(&[
"s1",
"edda",
"nornir-depgraph",
"crate",
"fn",
"layout",
"pub",
"src/layout.rs",
"20",
]),
];
let call_cols = to_s(&[
"snapshot_id",
"repo",
"crate_name",
"caller_path",
"callee_ident",
"call_kind",
]);
let call_edges = vec![to_s(&[
"s1",
"edda",
"nornir-depgraph",
"crate::build",
"layout",
"call",
])];
let heat = vec![
to_s(&["edda", "crates/nornir-depgraph/src/lib.rs", "37"]),
to_s(&["korp", "src/spark.rs", "5"]),
];
let deps = vec![to_s(&["korp", "edda"]), to_s(&["nornir", "edda"])];
spawn_mock_warehouse(vec![
("symbol_facts".to_string(), sym_cols, symbol_facts),
("call_edges".to_string(), call_cols, call_edges),
(
"git_heat_facts".to_string(),
to_s(&["repo", "file", "commits_90d"]),
heat,
),
(
"dep_graph_edges".to_string(),
to_s(&["from_repo", "to_repo"]),
deps,
),
])
}
#[test]
fn the_warehouse_pane_renders_live_data_via_the_host_given_only_dwarves_server() {
// The embedded-nornir stand-in, and the REAL dwarves proxy fronting it. The UI will be
// given ONLY the proxy's (dwarves-host) endpoint.
let upstream = seeded_upstream();
let proxy = dwarves::warehouse_proxy::spawn_proxy(upstream.endpoint.clone(), String::new());
let dwarves_host = proxy.endpoint.clone();
// SAFETY: single-purpose test binary. Poison NORNIR_SERVER (the UI must ignore it) and
// seed one warehouse name so the selector opens on a concrete workspace. `build_native_app`
// takes NO nornir arg — it is given only the dwarves host.
unsafe {
std::env::set_var("NORNIR_SERVER", NORNIR_POISON);
std::env::set_var("DWARVES_SERVER", &dwarves_host);
std::env::set_var("DWARVES_WAREHOUSES", "nordisk");
}
let mut app = build_native_app(
dwarves_host.clone(),
std::path::PathBuf::from("/nonexistent/dwarves-gui/proxy-live"),
);
// Open the Data view and scan — every table of its wall is one thin `Warehouse.Scan`,
// which now goes THROUGH the dwarves host.
Facet::update_json(&mut app, &json!({ "set_tab": "Data view" }).to_string());
Facet::update_json(&mut app, "\"scan\"");
let s = Facet::state_json(&app);
let dv = &s["data-view"];
let bound: Vec<String> = serde_json::from_value(dv["tables_bound"].clone()).unwrap_or_default();
let live_ok = dv["scanned"] == true
&& bound.contains(&"git_heat_facts".to_string())
&& bound.contains(&"dep_graph_edges".to_string());
// The source names the DWARVES host — the live data was served via the host, and the
// client reached the dwarves endpoint, not nornir directly.
let desc = dv["source"].as_str().unwrap_or_default().to_string();
let via_host = desc.contains(&dwarves_host);
// The tables nothing writes any more are NOT on the wall, although this upstream
// serves them.
let retired_off_the_wall =
!bound.contains(&"symbol_facts".to_string()) && !bound.contains(&"call_edges".to_string());
// The Warehouse navigator used to draw those two tables as its function tier. It
// asks nornir's code room now (`CodeRoom.Answer`); this upstream is a WAREHOUSE-only
// nornir (an older one, with no code-room door), so the forge relays `Unimplemented`
// and the navigator draws no node and says the door is not served.
Facet::update_json(&mut app, &json!({ "set_tab": "Warehouse" }).to_string());
Facet::update_json(&mut app, r#"{"world_target":100000}"#);
Facet::update_json(&mut app, r#"{"world":true}"#);
let s = Facet::state_json(&app);
let wh = &s["warehouse"];
let level_ok = wh["level"] == "world";
let real_ok = wh["real_source"] == true && wh["real_scanned"] == true;
let nav_refuses = wh.get("synthetic_functions").is_none()
&& wh["skeleton_read"] == false
&& wh["functions_read"] == false
&& wh["preview_nodes"].is_null()
&& wh["real_fn_nodes"].is_null()
&& wh["real_error"]
.as_str()
.is_some_and(|e| e.starts_with("[door_not_served]"))
&& wh["skeleton_error"]
.as_str()
.is_some_and(|e| e.starts_with("[door_not_served]"));
// THE LAW: no `:7878`/nornir address anywhere in the shell — the UI is host-only even
// while rendering live warehouse data.
let whole = s.to_string();
// Materialise every pane, then re-scan for the booby-trap.
let mut app2 = app;
for (_key, label) in DWARVES_TABS.iter() {
Facet::update_json(&mut app2, &json!({ "set_tab": label }).to_string());
}
let whole_all = Facet::state_json(&app2).to_string();
let no_nornir = !whole.contains(":7878")
&& !whole.contains("nornir-poison.example")
&& !whole_all.contains(":7878")
&& !whole_all.contains("nornir-poison.example");
assert!(
live_ok,
"LIVE warehouse rows arrived via the host and were bound: {dv}"
);
assert!(
via_host,
"the source names the dwarves host `{dwarves_host}`, got `{desc}`"
);
assert!(
retired_off_the_wall,
"a retired table got a pane: {bound:?}"
);
assert!(level_ok, "the navigator entered world mode: {wh}");
assert!(real_ok, "the navigator's source is wired + consulted: {wh}");
assert!(
nav_refuses,
"the navigator draws nothing an old server cannot answer, and says why: {wh}"
);
assert!(
no_nornir,
"the UI stayed host-only — no `:7878`/nornir address leaked"
);
drop(upstream);
let ok = live_ok
&& via_host
&& retired_off_the_wall
&& level_ok
&& real_ok
&& nav_refuses
&& no_nornir;
matrix(
"warehouse_pane_live_data_via_the_host",
ok,
"the SHIPPED shell, given ONLY the dwarves host (a real dwarves warehouse-proxy in \
front of a mock nornir, NORNIR_SERVER poisoned), binds the Data view's wall from LIVE \
warehouse rows served THROUGH the host (git_heat_facts + dep_graph_edges bound, the \
source names the dwarves host) while no :7878/nornir address appears anywhere in the \
shell; and the tables nothing writes since Mímir v2, which the upstream still serves, \
get no pane, and the navigator — whose tiers are nornir's code room — draws no node \
against a server without that door and says `door_not_served`",
);
}