tests: fast host suites

The timing rules are in two tests (upgrade_and_discovery_deadlines,
stop_deadlines). All other tests use a grace period of 0 or core.stop,
poll with deadlines instead of sleeping, and use the persistent cache in
CARGO_TARGET_TMPDIR. The 128-cycle singleton test is an ignored stress
test that nix flake check runs; the normal run has a 4-cycle sample.
Warm, the activation suite takes 12 s (was 47 s), and cargo test
--workspace takes 65 s.
This commit is contained in:
2026-10-23 08:20:49 +01:00
parent 1386acc924
commit 41818107a2
7 changed files with 134 additions and 73 deletions
+9 -13
View File
@@ -18,7 +18,6 @@ fn chat(params: &Value) -> Value {
send(json!({"jsonrpc":"2.0", "method":"core.notify", "params":{
"name":"text", "params":{"text":"interim"}
}}));
std::thread::sleep(std::time::Duration::from_millis(30));
json!({"text":params["text"]})
}
fn discover(params: &Value) -> Value {
@@ -65,12 +64,13 @@ fn notification(params: &Value) -> Value {
"method": "probe.write",
"params": params
}));
for _ in 0..200 {
let before = std::time::Instant::now();
loop {
let contents = std::fs::read_to_string(params["path"].as_str().unwrap()).ok();
if contents.as_deref() == params["text"].as_str() {
break;
}
std::thread::sleep(std::time::Duration::from_millis(10));
assert!(before.elapsed() < std::time::Duration::from_secs(10));
}
json!({})
}
@@ -82,6 +82,7 @@ fn unknown_id() {
}));
}
fn wait_eof(lines: &mut Lines) {
std::fs::write("/state/waiting", "yes").unwrap();
for _ in lines {}
std::fs::write("/state/stopped", "yes").unwrap();
}
@@ -90,11 +91,6 @@ fn busy() -> Value {
std::hint::spin_loop();
}
}
fn sleep(params: &Value) -> Value {
let duration = std::time::Duration::from_millis(params["ms"].as_u64().unwrap_or(100));
std::thread::sleep(duration);
json!({})
}
fn exit_without_answer() {
eprintln!("last line");
}
@@ -140,7 +136,6 @@ fn notify() -> Value {
"params": {"n": 1}
}
}));
std::thread::sleep(std::time::Duration::from_millis(30));
json!({})
}
fn serve(request: &Value, lines: &mut Lines) {
@@ -288,7 +283,7 @@ fn locked_write(lines: &mut Lines) -> Value {
json!({"held":true})
);
std::fs::write("/state/loop", "new").unwrap();
std::thread::sleep(std::time::Duration::from_millis(100));
outgoing_call(&json!({"method":"probe.echo","params":{}}), lines);
assert_eq!(std::fs::read_to_string("/state/loop").unwrap(), "new");
json!({})
}
@@ -305,11 +300,12 @@ fn unlock_answer(request: &Value, lines: &mut Lines) {
}
fn notification_child(lines: &mut Lines) -> Value {
send(json!({"jsonrpc":"2.0","method":"probe.orphan_notify","params":{}}));
let before = std::time::Instant::now();
let pid = loop {
if let Ok(pid) = std::fs::read_to_string("/state/orphan") {
break pid;
}
std::thread::sleep(std::time::Duration::from_millis(1));
assert!(before.elapsed() < std::time::Duration::from_secs(10));
};
send(json!({"jsonrpc":"2.0","id":7,"method":"core.stop","params":{"pid":pid}}));
let mut count = 0;
@@ -351,8 +347,9 @@ fn forget(lines: &mut Lines) -> Value {
send(
json!({"jsonrpc":"2.0","method":"core.call","params":{"method":"probe.forgotten","params":{},"detach":true}}),
);
let before = std::time::Instant::now();
while !std::path::Path::new("/state/forgotten").exists() {
std::thread::sleep(std::time::Duration::from_millis(1));
assert!(before.elapsed() < std::time::Duration::from_secs(10));
}
send(json!({"jsonrpc":"2.0","id":"barrier","method":"probe.echo","params":{}}));
let response = receive(lines);
@@ -438,7 +435,6 @@ fn dispatch(request: &Value, lines: &mut Lines) -> Option<Value> {
return None;
}
"busy" => busy(),
"sleep" => sleep(params),
"exit" => {
exit_without_answer();
return None;