Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

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