tests/self_emitters_core.rs
//! nornir eats its own dogfood (AUT8 / AUT8-GAP-NORNIR-SELF): nornir self-emits
//! `functional_status` rows for REAL checks of its OWN marker machinery — the
//! UI/gRPC/core classifier the Architecture tab + autonom rely on — and reads them
//! back via the in-process buffer (the `Aspect::Functional` drain path).
//!
//! EMIT-DOCTRINE: each `assert_emit!` is a real return-value assertion FIRST (the
//! `assert!` is the gate); the emit is the matrix observation. Run the richer
//! form with `cargo test --features testmatrix --test self_emitters_core`; a plain
//! `cargo test` still runs every real assertion (the emit is a stripped no-op).
use std::collections::BTreeMap;
use nornir::arch::{Classifier, NodeKind};
use nornir::assert_emit;
#[test]
fn nornir_self_emits_marker_classification_into_the_matrix() {
// Read only OUR rows: drain any left by a prior test (in-process buffer).
#[cfg(feature = "testmatrix")]
let _ = nornir_testmatrix::drain_functional_rows();
// A classifier wired like nornir's real one: one Facet-owning UI type and one
// tonic gRPC handler — the two marker shapes arch::classify recognises.
let markers: BTreeMap<String, NodeKind> = [("TestTab".to_string(), NodeKind::Component)]
.into_iter()
.collect();
let mut grpc: BTreeMap<String, String> = BTreeMap::new();
grpc.insert(
"nornir::server::VizSvc::architecture".to_string(),
"Viz.Architecture".to_string(),
);
let cls = Classifier {
marker_impls: &markers,
grpc_handlers: &grpc,
};
// REAL check 1 — a tonic handler fqn is a gRPC marker.
let g = cls.classify("nornir::server::VizSvc::architecture");
assert_emit!(
"arch::classify",
"grpc_handler_is_a_grpc_marker",
g.kind == NodeKind::Grpc && g.label == "Viz.Architecture",
"kind={:?} label={}",
g.kind,
g.label
);
// REAL check 2 — a fn owned by a Facet type is a UI-component marker.
let c = cls.classify("nornir::viz::TestTab::draw");
assert_emit!(
"arch::classify",
"facet_owner_is_a_ui_component_marker",
c.kind == NodeKind::Component && c.label == "TestTab",
"kind={:?} label={}",
c.kind,
c.label
);
// REAL check 3 — a plain fn is a core-fn (neither marked).
let f = cls.classify("dwarves::release_doctor::publish::topo_phases");
assert_emit!(
"arch::classify",
"plain_fn_is_a_core_fn",
f.kind == NodeKind::CoreFn,
"kind={:?} id={}",
f.kind,
f.id
);
// REAL check 4 — the discover enumerator turns a handler label into a Thin
// gRPC surface node (the marker the matrix must cover).
use nornir_testmatrix::discover::{Mode, SurfaceKind, grpc_handlers};
let nodes = grpc_handlers(["Viz.Architecture"]);
assert_emit!(
"discover::grpc_handlers",
"handler_becomes_a_thin_grpc_surface",
nodes.len() == 1 && nodes[0].kind == SurfaceKind::Grpc && nodes[0].mode == Mode::Thin,
"n={} kind={:?} mode={:?}",
nodes.len(),
nodes[0].kind,
nodes[0].mode
);
// Under --features testmatrix the four verdicts were recorded as matrix rows;
// drain + assert nornir really self-emitted them (aspect=functional).
#[cfg(feature = "testmatrix")]
{
let rows = nornir_testmatrix::drain_functional_rows();
assert!(
rows.len() >= 4,
"nornir self-emitted >=4 functional rows, got {}",
rows.len()
);
assert!(
rows.iter().all(|r| r.aspect == "functional"),
"all rows aspect=functional"
);
assert!(
rows.iter().any(|r| r.suite == "arch::classify"
&& r.test_name == "grpc_handler_is_a_grpc_marker"
&& r.status == "pass"),
"the gRPC-marker verdict landed as a green row: {rows:?}"
);
}
}