dwarves-gui/tests/robot_warehouse_dead_upstream.rs
//! **ROBOT-UI (LAW): a DEAD upstream degrades HONESTLY through the host — never false-green.**
//!
//! Sibling to `robot_warehouse_proxy_live.rs` (which proves the LIVE path). Here the REAL
//! dwarves warehouse/Mímir PROXY (`dwarves::warehouse_proxy`) fronts a **dead** embedded
//! nornir: the proxy binds and serves, but every forwarded read fails because the upstream
//! is not there. The SHIPPED shell (`build_native_app`, host-only, given ONLY the dwarves
//! proxy host) must then say so HONESTLY — an outage that reads as a clean/empty warehouse
//! is the exact false-green this suite exists to catch.
//!
//! (dead) embedded nornir ──✗──> dwarves warehouse-proxy (:auto) ──> the UI panes
//!
//! 1. [`the_lenses_pane_reports_unavailable_not_an_empty_clean_warehouse`] — the 🔍 Lenses
//! (Mímir) pane, scanned through the dead proxy, reports `status = "UNAVAILABLE — …"`,
//! `scanned=false`, a non-empty `error`, and NO fabricated findings (every lens report
//! null) — an outage, not "no findings".
//! 2. [`the_warehouse_navigator_draws_no_node_and_names_the_outage_on_a_dead_upstream`] —
//! the 🌐 Warehouse navigator, driven to its world tier through the dead proxy, draws
//! NO node (there is no fixture skeleton and no synthetic function to fall back to)
//! and names the outage for both tiers.
//!
//! Both assert no `:7878`/nornir address leaks. Each emits a `nornir-testmatrix` cell.
use dwarves_gui::{build_native_app, DWARVES_TABS};
use facett_core::Facet;
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";
/// A dead upstream the proxy fronts (nothing listens) — stands in for a host whose embedded
/// nornir is down / not wired, so every proxied read is an honest failure.
const DEAD_UPSTREAM: &str = "http://127.0.0.1:9";
#[allow(unused_variables)]
fn matrix(check: &str, ok: bool, detail: &str) {
#[cfg(feature = "testmatrix")]
nornir_testmatrix::functional_status("dwarves-gui", check, ok, detail);
}
/// Build the shipped shell host-only against a REAL dwarves proxy that fronts a dead
/// upstream. `NORNIR_SERVER` is poisoned; `DWARVES_SERVER` is the proxy endpoint.
fn shell_over_dead_proxy() -> (
dwarves::warehouse_proxy::ProxyServer,
dwarves_gui::tabbed::TabbedView,
) {
let proxy = dwarves::warehouse_proxy::spawn_proxy(DEAD_UPSTREAM.to_string(), String::new());
let dwarves_host = proxy.endpoint.clone();
// SAFETY: single-purpose test binary. `build_native_app` takes NO nornir arg by design.
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 app = build_native_app(
dwarves_host,
std::path::PathBuf::from("/nonexistent/dwarves-gui/dead-upstream"),
);
(proxy, app)
}
/// Fold the whole shell and assert the nornir booby-trap never appears.
fn assert_host_only(app: &mut dwarves_gui::tabbed::TabbedView) {
for (_key, label) in DWARVES_TABS.iter() {
Facet::update_json(app, &json!({ "set_tab": label }).to_string());
}
let whole = Facet::state_json(app).to_string();
assert!(
!whole.contains(":7878") && !whole.contains("nornir-poison.example"),
"host-only: no nornir `:7878` address may leak into the shell state_json"
);
}
#[test]
fn the_lenses_pane_reports_unavailable_not_an_empty_clean_warehouse() {
let (proxy, mut app) = shell_over_dead_proxy();
// Open Lenses and SCAN — the read crosses the dwarves host to a dead upstream and fails.
Facet::update_json(&mut app, &json!({ "set_tab": "Lenses" }).to_string());
Facet::update_json(&mut app, r#""scan""#);
let s = Facet::state_json(&app);
let lens = &s["lenses"];
let status = lens["status"].as_str().unwrap_or_default();
let unavailable_ok = status.starts_with("UNAVAILABLE");
let scanned_ok = lens["scanned"] == false;
let error_ok = lens["error"]
.as_str()
.map(|e| !e.is_empty())
.unwrap_or(false);
// NO fabricated findings: a dead read leaves every lens report null (not empty lists
// dressed as "no findings").
let no_false_findings = lens["bloat"].is_null()
&& lens["zombie"].is_null()
&& lens["risk"].is_null()
&& lens["weak_tests"].is_null();
assert!(
unavailable_ok,
"a dead upstream ⇒ the Lenses status says UNAVAILABLE: {status:?}"
);
// ── THE CODE (dwarves::errcode) — keyed, not string-matched ──────────────────────
// A dead upstream is diagnosed by the PROXY (`dwarves-proxy-2`) and that code travels
// up into the pane; a lens fold that fails without a deeper diagnosis is
// `dwarves-mimir-1`. Either is an honest, stable, KEYABLE outage — what must never
// happen is a failed scan with NO code at all (that is the false-green shape).
let code = lens["error_code"].as_str().unwrap_or_default();
let code_ok = code == "dwarves-proxy-2" || code == "dwarves-mimir-1";
assert!(
code_ok,
"a dead upstream raises a STABLE outage code (dwarves-proxy-2 / dwarves-mimir-1), \
got {code:?} — a failed scan must never be code-less: {lens}"
);
assert_eq!(
lens["error_object"]["code"], code,
"the dual-channel error object agrees with error_code: {}",
lens["error_object"]
);
assert!(
scanned_ok,
"a failed scan is NOT 'scanned' (no clean bill): {lens}"
);
assert!(
error_ok,
"the honest outage reason is carried in `error`: {lens}"
);
assert!(
no_false_findings,
"no fabricated lens findings on a dead read: {lens}"
);
assert_host_only(&mut app);
drop(proxy);
let ok = unavailable_ok && scanned_ok && error_ok && no_false_findings && code_ok;
matrix(
"lenses_pane_unavailable_on_dead_upstream",
ok,
"the 🔍 Lenses (Mímir) pane, scanned through the shipped host-only shell against a REAL \
dwarves proxy fronting a DEAD upstream, reports status=UNAVAILABLE with scanned=false, \
a non-empty error, and NO fabricated lens findings (bloat/zombie/risk/weak_tests all \
null) — an outage reads as an outage, never as a clean/empty warehouse; no :7878 leaks",
);
}
#[test]
fn the_warehouse_navigator_draws_no_node_and_names_the_outage_on_a_dead_upstream() {
let (proxy, mut app) = shell_over_dead_proxy();
// Drive the navigator to its world tier — it asks its two sources (the skeleton and
// the function tier) through the dead proxy, gets no answer from either, and draws
// NOTHING in their place: there is no fixture skeleton and no synthetic function.
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 consulted_ok = wh["real_source"] == true && wh["real_scanned"] == true;
// Neither tier was read, so nothing is counted: `null`, never a `0` nobody counted.
let no_node = wh["skeleton_read"] == false
&& wh["functions_read"] == false
&& wh["preview_nodes"].is_null()
&& wh["real_fn_nodes"].is_null()
&& wh["real_call_edges"].is_null()
&& wh.get("synthetic_functions").is_none();
// Each tier names WHY: a state in brackets, then the proxy's own words for the outage.
let named = |key: &str| {
wh[key]
.as_str()
.is_some_and(|e| e.starts_with('[') && e.contains("embedded nornir unreachable"))
};
assert!(level_ok, "the navigator entered world mode: {wh}");
assert!(
consulted_ok,
"the function-tier source is wired + consulted: {wh}"
);
assert!(
no_node,
"a dead upstream draws NO node — nothing stands in for the room: {wh}"
);
assert!(
named("skeleton_error") && named("real_error"),
"both tiers name the outage: {wh}"
);
assert_host_only(&mut app);
drop(proxy);
let ok = level_ok && consulted_ok && no_node;
matrix(
"warehouse_nav_draws_no_node_on_dead_upstream",
ok,
"the 🌐 Warehouse navigator, driven to its world tier through the shipped host-only \
shell against a REAL dwarves proxy fronting a DEAD upstream, draws no node at all \
(no fixture skeleton, no synthetic function) and names the outage for both tiers; \
no :7878 leaks",
);
}