Skip to main content

Crate nornir_testmatrix

Crate nornir_testmatrix 

Source
Expand description

§nornir-testmatrix

The portable core of nornir’s multi-aspect test matrix — extracted from nornir (EPIC L) so any leaf repo (znippy, skade, lbzip2-rs …) can run the same matrix with a tiny dep set: std + serde/serde_json + anyhow. No iceberg, arrow, eframe, tantivy, or skade.

§What it does

  1. Runner (runner) — wrap a repo’s native Rust test framework (cargo nextest run --message-format libtest-json if nextest is on PATH, else plain cargo test), parse each test’s pass/fail + duration, enforce a stall watchdog. Pure subprocess driving — no test registration.
  2. Multi-aspect engine (aspect) — beyond unit tests, run MANY aspects of a repo’s health (Aspect): build, doctest, clippy, fmt, audit, bench-smoke, coverage, feature-powerset, msrv, examples. Each shells the right cargo subcommand, parses its result, and emits TestResultRows carrying an aspect tag + a numeric metric (coverage %, warning count, advisory count …). A missing tool is a skip, never a hard fail.
  3. Model (model) — the pure row/summary types (TestResultRow, RunSummary, TestSelector, the status tags) + the renderers (render_matrix, summarize_runs, rows_to_json).
  4. Sinks (sink) — the TestSink trait + built-in JsonFileSink and NullSink so a leaf repo with no warehouse can still persist its matrix. nornir implements TestSink over its Iceberg warehouse.
  5. Discovery (discover) — the autonom (AUT2) anti-drift core: pure enumerators that build the testable Surface from data (facett components, viz tabs × {thin,fat}, CLI subcommands, MCP tools, and the unreached-function set from symbol_facts − test-reachable(call_edges)), then compute_gap differences it against coverage so the gate can enforce Gap == ∅. No warehouse here — the caller feeds the rows.
  6. Functional-status mode (functional) — a component reports whether it actually works (functional_status(component, check, ok, detail)) from its own headless-render / self-test path. The Aspect::Functional runner drains those into rows so a broken render is a RED matrix row WITHOUT eyeballing a GUI. Gated behind the testmatrix cargo feature: release builds (feature off) strip the emit to a no-op.

§How a leaf repo uses it

use nornir_testmatrix::{run_full_matrix, Aspect, JsonFileSink, TestSink};
use std::path::Path;

let aspects = [Aspect::Build, Aspect::Unit, Aspect::Doctest, Aspect::Clippy, Aspect::Fmt];
let rows = run_full_matrix(Path::new("."), &aspects);
let sink = JsonFileSink::new("target/nornir-testmatrix.json");
sink.append(&rows).unwrap();

Re-exports§

pub use aspect::aspect_label;
pub use aspect::parse_aspect;
pub use aspect::parse_funnel_decompose;
pub use aspect::run_aspect;
pub use aspect::run_full_matrix;
pub use aspect::Aspect;
pub use aspect::AspectOutcome;
pub use coverage::rows_for;
pub use coverage::seed_allowlist;
pub use coverage::stale_allowlist_entries;
pub use coverage::AllowEntry;
pub use coverage::Allowlist;
pub use coverage::CoverageRow;
pub use coverage::CoverageSummary;
pub use coverage::GateReport;
pub use coverage::Verdict;
pub use discover::cli_commands;
pub use discover::compute_gap;
pub use discover::facett_components;
pub use discover::mcp_tools;
pub use discover::test_reachable;
pub use discover::unreached_functions;
pub use discover::viz_tabs;
pub use discover::CallEdge;
pub use discover::FacetRow;
pub use discover::Gap;
pub use discover::Mode;
pub use discover::Surface;
pub use discover::SurfaceKind;
pub use discover::SurfaceNode;
pub use discover::SymbolRow;
pub use functional::drain_functional_rows;
pub use functional::functional_row;
pub use functional::functional_status;
pub use model::listed_rows;
pub use model::new_run_id;
pub use model::parse_cargo_test_list;
pub use model::parse_nextest_list;
pub use model::render_matrix;
pub use model::rows_to_json;
pub use model::short_run;
pub use model::status;
pub use model::summarize_runs;
pub use model::RunSummary;
pub use model::TestResultRow;
pub use model::TestSelector;
pub use runner::detect_runner;
pub use runner::list_tests;
pub use runner::run_matrix;
pub use runner::stall_secs;
pub use runner::MatrixRun;
pub use runner::Runner;
pub use runner::TestCase;
pub use runner::DEFAULT_STALL_SECS;
pub use sink::JsonFileSink;
pub use sink::NullSink;
pub use sink::TestSink;

Modules§

aspect
The multi-aspect engine — test MANY aspects of a repo’s health, not just its unit tests. Each Aspect shells the right cargo subcommand, parses its result into an AspectOutcome, and emits TestResultRows carrying the aspect tag + a numeric metric (coverage %, warning count, advisory count …).
coverage
autonom coverage gate — the PURE verdict model (AUT2 / n-005)
discover
autonom self-discovery — the anti-drift core of the completeness gate
functional
Functional-status mode — a component reports whether it actually works.
model
The pure test-matrix model: rows, summaries, selectors, status tags, and the human/JSON renderers. Zero heavy deps — std only (no chrono, no uuid): a tiny RFC3339 formatter + a getrandom-free UUIDv4 keep the crate lean.
runner
Standardized test-matrix runner — wrap a repo’s native Rust test framework, parse per-test pass/fail + duration, and hand the rows back.
sink
Where a matrix run’s rows go. The TestSink trait is the durable seam: nornir implements it over its Iceberg warehouse; a leaf repo with no warehouse uses the built-in JsonFileSink (append-only JSON history file) or NullSink (drop, for dry-runs / tests).