use super::*;
#[test]
fn the_start_slot_is_claimable_exactly_once() {
let started = AtomicBool::new(false);
claim_start_slot(&started, false).expect("the first claim takes the slot");
let err = claim_start_slot(&started, false).expect_err("the second is refused");
let msg = format!("{err:#}");
assert!(msg.contains("already started a server"), "{msg}");
assert!(
msg.contains("one benchmark per invocation"),
"says what to do instead: {msg}"
);
}
#[test]
fn an_already_requested_shutdown_refuses_before_the_wait() {
let started = AtomicBool::new(false);
let err = claim_start_slot(&started, true).expect_err("refused");
let msg = format!("{err:#}");
assert!(msg.contains("shutdown has already been requested"), "{msg}");
assert!(
!started.load(Ordering::SeqCst),
"and the slot is not spent by a claim that never started anything"
);
}
#[test]
fn a_clean_box_serves_at_the_recipes_utilisation() {
let line =
headroom_verdict(121.0, 114.0, 0.90, "qwen3.6/27b", 0.85).expect("a clean box passes");
assert!(line.contains("0.90"), "{line}");
assert!(line.contains("94 %"), "{line}");
}
#[test]
fn a_co_tenanted_box_is_refused_with_the_remedies() {
let err = headroom_verdict(121.0, 98.0, 0.90, "qwen3.6/27b", 0.85).expect_err("refused");
let msg = format!("{err:#}");
assert!(msg.contains("qwen3.6/27b"), "names the recipe: {msg}");
assert!(msg.contains("docker ps"), "names a remedy: {msg}");
assert!(msg.contains("nvidia-smi"), "and the other one: {msg}");
assert!(
msg.contains("not a judgement on the recipe"),
"and says what it is NOT refusing: {msg}"
);
}
#[test]
fn the_threshold_itself_is_inclusive() {
let total = 100.0;
assert!(headroom_verdict(total, total * 0.85, 0.9, "r", 0.85).is_ok());
assert!(headroom_verdict(total, total * 0.85 - 0.1, 0.9, "r", 0.85).is_err());
}
fn runtime() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.expect("a current-thread runtime")
}
fn served_forever() -> (SelfServed, tokio::sync::oneshot::Receiver<()>) {
let (tx, rx) = tokio::sync::oneshot::channel::<()>();
let server = tokio::spawn(async move {
let _tx = tx;
std::future::pending::<()>().await;
Ok(())
});
let served = SelfServed {
target: TargetEndpoint::local(1, "m"),
recipe_id: "r".to_string(),
recipe_sha256: String::new(),
overrides: Default::default(),
resolved: Default::default(),
serve_env: Default::default(),
baseline_entry: Default::default(),
server: Some(server),
};
(served, rx)
}
#[test]
fn a_declared_lever_this_process_lacks_is_refused_with_the_export_line() {
use metrale_bench::serve_env::Reconciled;
let declared: BTreeMap<String, String> = [
("METRALE_FP8_ROWWISE", "1"),
("METRALE_MTP_DCUT_RATIO", "1.0"),
]
.into_iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
let err = refuse_unapplied_levers(
"qwen3.8/qwen3.8-27b-nvfp4-unsloth",
&Reconciled {
env: declared.clone(),
missing: declared.clone(),
},
)
.expect_err("refused");
let msg = format!("{err:#}");
assert!(msg.contains("2 serve lever(s)"), "{msg}");
assert!(
msg.contains("env METRALE_FP8_ROWWISE=1 METRALE_MTP_DCUT_RATIO=1.0 met benchmark run"),
"the export line is verbatim: {msg}"
);
assert!(msg.contains("--serve-reuse"), "names the child path: {msg}");
assert!(msg.contains("qwen3.8/qwen3.8-27b-nvfp4-unsloth"), "{msg}");
refuse_unapplied_levers(
"r",
&Reconciled {
env: declared,
missing: BTreeMap::new(),
},
)
.expect("nothing missing, nothing refused");
}
#[test]
fn dropping_a_self_served_tears_the_server_down() {
runtime().block_on(async {
let (served, rx) = served_forever();
drop(served);
let waited = tokio::time::timeout(Duration::from_secs(5), rx).await;
assert!(
matches!(waited, Ok(Err(_))),
"the server task must be aborted, not detached: {waited:?}"
);
});
}
#[test]
fn a_torn_down_server_is_not_torn_down_twice() {
runtime().block_on(async {
let (mut served, rx) = served_forever();
let handle = served.server.take().expect("constructed as Some");
handle.abort();
drop(served);
let waited = tokio::time::timeout(Duration::from_secs(5), rx).await;
assert!(matches!(waited, Ok(Err(_))), "{waited:?}");
});
}
#[test]
fn baseline_pins_are_applied_and_the_operator_wins_a_clash() {
let baseline = BTreeMap::from([
("ssm_cache_slots".to_string(), "256".to_string()),
("kv_cache_dtype".to_string(), "bf16".to_string()),
]);
let requested = BTreeMap::from([("kv_cache_dtype".to_string(), "fp8".to_string())]);
let merged = metrale_bench::gate::merge_serve_overrides(baseline, requested);
assert_eq!(
merged.get("ssm_cache_slots").map(String::as_str),
Some("256"),
"an unclashed pin survives the merge"
);
assert_eq!(
merged.get("kv_cache_dtype").map(String::as_str),
Some("fp8"),
"the operator's value wins the clash"
);
}
#[test]
fn a_baseline_declared_serve_pin_reaches_the_rendered_serve_args_without_cli_flags() {
let root = crate::cli::bench_run::repo_root().expect("inside the repo");
let baseline = gate::read_baseline(&root, "concurrency-sweep").expect("baseline assembles");
let resolved = crate::cli::bench_resolve::resolve(&baseline, "concurrency-sweep", None, None)
.expect("the default variant resolves");
assert_eq!(
Some(resolved.recipe_id.as_str()),
resolved.entry.recipe.as_deref(),
"resolution must serve the recipe the baseline declares"
);
let merged =
gate::merge_serve_overrides(resolved.entry.serve_overrides.clone(), BTreeMap::new());
assert!(
!merged.is_empty(),
"the baseline-declared serve pin was lost before the merge: with no CLI flags the \
gate would serve the recipe verbatim and print no OVERRIDES line"
);
let fixture = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/recipes/qwen3.6/qwen3.6-27b-nvfp4.yaml");
let text = std::fs::read_to_string(&fixture).expect("fixture recipe");
let mut recipe =
crate::recipe::Recipe::parse("qwen3.6/qwen3.6-27b-nvfp4", &text).expect("parses");
let served = crate::recipe::Recipe::parse(
resolved.recipe_id.clone(),
&gate::recipe_closure::read_in_tree(&root, &resolved.recipe_id).expect("in tree"),
)
.expect("the in-tree recipe parses");
recipe.defaults.insert(
"weight_quantization".to_string(),
served.defaults["weight_quantization"].clone(),
);
let args = recipe
.serve_args(&merged)
.expect("pins render to valid serve args");
assert_eq!(
args.max_batch_size.to_string(),
merged["max_batch_size"],
"the batching pin reached the serve"
);
assert_eq!(
args.kv_cache_dtype.as_deref(),
Some(merged["kv_cache_dtype"].as_str()),
"the KV pin reached the serve"
);
assert!(
!merged.contains_key("ssm_cache_slots"),
"the ladder inherits the recipe's pool; re-pinning it re-opens the last \
disagreement with the published leg"
);
assert_eq!(
args.ssm_cache_slots,
recipe.defaults["ssm_cache_slots"]
.parse::<usize>()
.expect("the fixture declares a numeric pool size"),
"an unpinned key must render the recipe's own value"
);
assert_eq!(
args.max_seq_len.to_string(),
merged["max_model_len"],
"the context pin reached the serve"
);
}