crates/nornir-warehouse-embed/tests/bench_submit.rs
//! **The `Bench.Submit` write leg, proven on the wire.**
//!
//! `dwarves bench run` measures and nornir persists; the seam between them is this
//! RPC. What has to be true is not "the client returned Ok" — it is that the row
//! nornir receives carries the numbers that were measured. A client asserting its
//! own struct round-tripped through itself would pass with a submit that sent
//! nothing, which is the exact shape of the four rounds ⚒ Build Thing came up empty
//! (a write path with no producer and no observable outcome).
//!
//! So these tests stand up a real tonic `Bench` server, run the real client against
//! it, and read the request back out of the server.
use nornir_warehouse_embed::{submit_bench_run, testkit};
fn run_with(metric: f64, cores: u32) -> nornir_bench::BenchRun {
let mut metrics = serde_json::Map::new();
metrics.insert("paths_per_sec".into(), serde_json::json!(metric));
// The telemetry field the `core_saturation` gate reads. It is a per-arm metric
// riding in the free-form map, so it only survives the hop if the mapping ships
// the WHOLE map — which is the thing worth asserting.
metrics.insert("telem_proc_cores_max".into(), serde_json::json!(0.56));
// A NON-numeric metric: `KVF.value` is a double, so this one cannot cross. It is
// here so the loss is a measured property of the RPC rather than a surprise.
metrics.insert("note".into(), serde_json::json!("not a number"));
nornir_bench::BenchRun {
id: nornir_bench::BenchRun::new_id(),
machine_facts: None,
date: "2026-08-03".into(),
timestamp: Some("2026-08-03T21:00:00Z".into()),
version: "0.5.0".into(),
machine: "oden".into(),
cores,
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,
}],
}
}
/// ★ The measured numbers reach the server, and the run id the caller reports is
/// the SERVER's.
#[test]
fn a_submitted_bench_run_arrives_with_its_metrics_and_returns_the_servers_run_id() {
let (srv, log) = testkit::spawn_mock_bench();
let id = submit_bench_run(
&srv.endpoint,
"",
"nordisk",
"gunnar",
&run_with(1234.5, 32),
)
.expect("submit must succeed against a live Bench server");
assert_eq!(
id,
testkit::MOCK_BENCH_RUN_ID,
"the receipt must be the server's id"
);
let got = log.submitted();
assert_eq!(got.len(), 1, "exactly one run crossed the wire");
let req = &got[0];
assert_eq!(req.repo, "gunnar", "the bench_runs partition key");
let run = req
.run
.as_ref()
.expect("the request must carry the run, not just the repo");
assert_eq!(
run.machine, "oden",
"the host that partitions the row in `dwarves coverage`"
);
assert_eq!(run.cores, 32);
assert_eq!(run.version, "0.5.0", "the SUBJECT version stamp");
assert_eq!(run.results.len(), 1);
assert_eq!(run.results[0].name, "gunnar.walk_1m");
let metrics: std::collections::BTreeMap<&str, f64> = run.results[0]
.metrics
.iter()
.map(|kv| (kv.key.as_str(), kv.value))
.collect();
assert_eq!(
metrics.get("paths_per_sec"),
Some(&1234.5),
"the arm's own number"
);
assert_eq!(
metrics.get("telem_proc_cores_max"),
Some(&0.56),
"the core_saturation input must survive the hop — it is what tells a \
single-threaded arm apart from a saturated one, and reading the host-wide \
figure instead reported a strictly single-threaded arm as 32/32",
);
assert!(
!metrics.contains_key("note"),
"a non-numeric metric cannot cross a `double` field — documented loss, asserted",
);
assert_eq!(run.tests.len(), 1);
assert!(run.tests[0].passed);
assert!(
run.tests[0].has_duration,
"a recorded 12.5ms must not read as `not recorded`"
);
assert_eq!(run.tests[0].duration_ms, 12.5);
}
/// ★ A reachable server that refuses is an ERROR, never a quiet success. The forge
/// turns this into `NOT SUBMITTED` + exit 2; a swallowed `Ok` would report a
/// measurement nobody can read as one that landed.
#[test]
fn a_refusing_server_is_an_error_not_a_silent_ok() {
let (srv, log) = testkit::spawn_mock_bench();
log.reject("catalog is locked");
let err = submit_bench_run(&srv.endpoint, "", "", "gunnar", &run_with(1.0, 4))
.expect_err("a refused submit must not read as success");
let msg = format!("{err:#}");
assert!(msg.contains("Bench.Submit"), "{msg}");
assert!(
msg.contains("catalog is locked"),
"the server's reason must survive: {msg}"
);
assert!(
log.submitted().is_empty(),
"nothing was recorded, and the caller was told"
);
}
/// A dead port is an error too — distinct from "no server configured", which the
/// forge never even attempts.
#[test]
fn an_unreachable_server_is_an_error() {
// Bind and immediately drop, so the port is one nothing is listening on.
let addr = {
let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
l.local_addr().unwrap()
};
let err = submit_bench_run(
&format!("http://{addr}"),
"",
"",
"gunnar",
&run_with(1.0, 4),
)
.expect_err("a dead port must not read as success");
assert!(
format!("{err:#}").contains("connect to nornir-server"),
"{err:#}"
);
}