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

nordisk/dwarves

crates/nornir-warehouse-embed/tests/bench_history.rs

//! **The `Bench.History` READ leg, proven on the wire.**
//!
//! The forge measures and the warehouse keeps the numbers; until now reading them
//! back was `nornir bench history-show`. The doc-book MASHUP renderer moving into
//! dwarves needs its own read-back leg (`fetch_bench_history`), and what has to be
//! true of it is a ROUND TRIP: the run that crossed the wire IN over `Bench.Submit`
//! comes back OUT over `Bench.History` carrying the same numbers, mapped back onto
//! the same `nornir_bench::BenchRun` the rest of the codebase holds.
//!
//! The zero-equals-zero identity trap (see dwarves' `dupes_thin_fat_parity`): an
//! assertion over two empty lists proves nothing, so the round-trip test asserts a
//! NON-empty history field-for-field — and the empty case is its own test, proving
//! "no runs yet" is an EMPTY VEC (a normal state the mashup renders), never an
//! error, while a dead or refusing server IS an error, never a silent empty.

use nornir_warehouse_embed::{
    bench_run_from_pb, bench_run_to_pb, fetch_bench_history, pb, submit_bench_run, testkit,
};

fn measured_run() -> nornir_bench::BenchRun {
    let mut metrics = serde_json::Map::new();
    metrics.insert("paths_per_sec".into(), serde_json::json!(1234.5));
    // The telemetry metric the `core_saturation` gate reads — per-arm, riding the
    // free-form map, so it only comes back if the WHOLE map round-trips.
    metrics.insert("telem_proc_cores_max".into(), serde_json::json!(0.56));
    // A NON-numeric metric: `KVF.value` is a double, so it cannot cross. Present so
    // the loss stays a measured property of the RPC, in the read leg too.
    metrics.insert("note".into(), serde_json::json!("not a number"));
    nornir_bench::BenchRun {
        // The producer mints its own id; the round trip must bring the SAME one
        // back, which is what makes a re-submit idempotent rather than a second row.
        id: nornir_bench::BenchRun::new_id(),
        machine_facts: None,
        date: "2026-08-18".into(),
        timestamp: Some("2026-08-18T09:00:00Z".into()),
        version: "0.6.1".into(),
        machine: "oden".into(),
        cores: 32,
        results: vec![nornir_bench::BenchResult::measured(
            "gunnar.walk_1m",
            metrics,
        )],
        tests: vec![
            nornir_bench::TestOutcome {
                name: "gunnar.smoke".into(),
                passed: true,
                duration_ms: Some(12.5),
                message: None,
            },
            nornir_bench::TestOutcome {
                name: "gunnar.red_case".into(),
                passed: false,
                duration_ms: None,
                message: Some("assertion left != right".into()),
            },
        ],
    }
}

/// ★ Submit → History is a genuine round trip: the run the server received over
/// the wire comes back as a `nornir_bench::BenchRun`, field-for-field.
#[test]
fn a_submitted_run_reads_back_over_history_field_for_field() {
    let (srv, _log) = testkit::spawn_mock_bench();
    let sent = measured_run();

    submit_bench_run(&srv.endpoint, "", "nordisk", "gunnar", &sent)
        .expect("submit against the live mock Bench server");

    let hist = fetch_bench_history(&srv.endpoint, "", "nordisk", "gunnar")
        .expect("history against the live mock Bench server");

    // NOT the identity trap: exactly one run, and it is the one that was sent.
    assert_eq!(
        hist.len(),
        1,
        "the submitted run came back, and nothing else"
    );
    let got = &hist[0];
    assert_eq!(got.date, sent.date);
    assert_eq!(
        got.timestamp, sent.timestamp,
        "RFC3339 timestamp survives as Some"
    );
    assert_eq!(got.version, sent.version, "the SUBJECT version stamp");
    assert_eq!(
        got.machine, sent.machine,
        "the host that partitions the row"
    );
    assert_eq!(got.cores, sent.cores);

    // The measured numbers — the payload the mashup actually renders.
    assert_eq!(got.results.len(), 1);
    let r = &got.results[0];
    assert_eq!(r.name, "gunnar.walk_1m");
    assert_eq!(
        r.metrics.get("paths_per_sec"),
        Some(&serde_json::json!(1234.5))
    );
    assert_eq!(
        r.metrics.get("telem_proc_cores_max"),
        Some(&serde_json::json!(0.56)),
        "the free-form map round-trips whole"
    );
    // The documented loss, still documented on the read leg: KVF.value is a
    // double, so the non-numeric metric never crossed.
    assert_eq!(
        r.metrics.get("note"),
        None,
        "non-numeric metrics do not cross the wire"
    );

    // Test outcomes, including the Option flattening coming back honest.
    assert_eq!(got.tests.len(), 2);
    assert_eq!(got.tests[0].name, "gunnar.smoke");
    assert!(got.tests[0].passed);
    assert_eq!(got.tests[0].duration_ms, Some(12.5));
    assert_eq!(
        got.tests[0].message, None,
        "an empty wire message maps back to None"
    );
    assert_eq!(got.tests[1].name, "gunnar.red_case");
    assert!(!got.tests[1].passed);
    assert_eq!(
        got.tests[1].duration_ms, None,
        "has_duration=false maps back to None, not Some(0.0)"
    );
    assert_eq!(
        got.tests[1].message.as_deref(),
        Some("assertion left != right")
    );
}

/// ★ A repo nothing has measured is an EMPTY VEC — a normal state for the mashup
/// to render — never an error.
#[test]
fn an_unmeasured_repo_reads_back_as_an_empty_vec_not_an_error() {
    let (srv, _log) = testkit::spawn_mock_bench();
    // Something IS in the warehouse — just not for this repo — so an empty answer
    // here is a filtered read, not a server that returns nothing for everything.
    submit_bench_run(&srv.endpoint, "", "nordisk", "gunnar", &measured_run())
        .expect("seed a different repo's run");

    let hist = fetch_bench_history(&srv.endpoint, "", "nordisk", "never-benched")
        .expect("an unmeasured repo must be Ok, not an error");
    assert!(
        hist.is_empty(),
        "no runs for this repo ⇒ empty vec: {hist:?}"
    );
}

/// ★ The failure states stay LOUD: a dead port and a reachable-but-refusing
/// server are errors, never a silent empty history.
#[test]
fn a_dead_or_refusing_server_is_an_error_never_an_empty_history() {
    // Dead port: bind-then-drop so nothing listens there.
    let addr = {
        let l = std::net::TcpListener::bind("127.0.0.1:0").expect("probe port");
        l.local_addr().expect("probe addr")
    };
    let err = fetch_bench_history(&format!("http://{addr}"), "", "", "gunnar")
        .expect_err("a dead port must not read as an empty history");
    assert!(
        format!("{err:#}").contains("connect to nornir-server"),
        "{err:#}"
    );

    // Reachable but refusing (the reject knob): the RPC error surfaces.
    let (srv, log) = testkit::spawn_mock_bench();
    log.reject("warehouse is sealed");
    let err = fetch_bench_history(&srv.endpoint, "", "nordisk", "gunnar")
        .expect_err("a refusing server must not read as an empty history");
    assert!(format!("{err:#}").contains("Bench.History RPC"), "{err:#}");
}

/// The pure inverse mapping, pinned on a hand-built wire message — every mapped
/// field asserted, so the flattening rules cannot rot unobserved behind the
/// network tests above.
#[test]
fn bench_run_from_pb_maps_every_field_and_flattens_honestly() {
    let wire = pb::BenchRun {
        // Empty on the wire is the LEGACY case: `Uuid::nil`, "no identity", which
        // a consumer must join heuristically and must never deduplicate on.
        id: String::new(),
        machine_facts_json: String::new(),
        date: "2026-08-18".into(),
        timestamp: String::new(), // absent on the wire
        version: "1.2.3".into(),
        machine: "frigg".into(),
        cores: 8,
        results: vec![pb::BenchResult {
            name: "korp.ingest".into(),
            metrics: vec![
                pb::Kvf {
                    key: "rows_per_sec".into(),
                    value: 42.0,
                },
                pb::Kvf {
                    key: "not_a_json_number".into(),
                    value: f64::NAN,
                },
            ],
        }],
        tests: vec![pb::TestOutcome {
            name: "korp.smoke".into(),
            passed: true,
            duration_ms: 0.0,
            has_duration: true, // a REAL zero, distinct from "not recorded"
            message: "flaky on ci".into(),
        }],
    };

    let run = bench_run_from_pb(wire);
    assert_eq!(run.date, "2026-08-18");
    assert_eq!(
        run.timestamp, None,
        "empty wire timestamp is None, never Some(\"\")"
    );
    assert_eq!(run.version, "1.2.3");
    assert_eq!(run.machine, "frigg");
    assert_eq!(run.cores, 8);
    assert_eq!(run.results.len(), 1);
    assert_eq!(run.results[0].name, "korp.ingest");
    assert_eq!(
        run.results[0].source,
        nornir_bench::BenchSource::Measured,
        "the source tag has no proto field — every wire row reads back Measured"
    );
    assert_eq!(
        run.results[0].metrics.get("rows_per_sec"),
        Some(&serde_json::json!(42.0))
    );
    assert_eq!(
        run.results[0].metrics.get("not_a_json_number"),
        None,
        "a non-finite double has no JSON number — dropped, never smuggled as null"
    );
    assert_eq!(run.tests.len(), 1);
    assert_eq!(
        run.tests[0].duration_ms,
        Some(0.0),
        "a recorded 0 ms stays Some(0.0)"
    );
    assert_eq!(run.tests[0].message.as_deref(), Some("flaky on ci"));

    // And the two pure mappings compose: to_pb ∘ from_pb is the identity on
    // everything the wire can carry.
    let sent = measured_run();
    let back = bench_run_from_pb(bench_run_to_pb(&sent));
    assert_eq!(back.date, sent.date);
    assert_eq!(back.timestamp, sent.timestamp);
    assert_eq!(back.cores, sent.cores);
    assert_eq!(
        back.results[0].metrics.get("paths_per_sec"),
        Some(&serde_json::json!(1234.5))
    );
}