test(runtime): wait for the suspend checkpoint before reading the run state
deploy / test (push) Successful in 5m2s
deploy / build (push) Successful in 5m48s

RunSuspended is journaled before the run row is checkpointed, so the
event can arrive milliseconds before the state; CI run 6485 read Running
in that window. Poll up to 2 s.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WZb5A2kfVfjpdwSochkuHz
This commit is contained in:
Omar Sobh
2026-09-21 10:36:39 -05:00
co-authored by Claude Opus 5
parent 2ebba77f7f
commit ffaab117ef
+12 -1
View File
@@ -153,7 +153,18 @@ async fn start_gated_run(
// Blocked: nothing executed, run suspended, approval queued. // Blocked: nothing executed, run suspended, approval queued.
assert_eq!(outbox_count(pool).await, 0); assert_eq!(outbox_count(pool).await, 0);
let run = cm_db::repo::runs::get(pool, started.run_id).await.unwrap(); // The loop journals `RunSuspended` BEFORE it checkpoints the run row
// (deliberately — resume must continue from the right sequence number),
// so the event can arrive a few milliseconds before the state does. CI
// run 6485 read `Running` in that window; a loaded runner widens it.
let mut run = cm_db::repo::runs::get(pool, started.run_id).await.unwrap();
for _ in 0..50 {
if run.state == RunState::AwaitingApproval {
break;
}
tokio::time::sleep(std::time::Duration::from_millis(40)).await;
run = cm_db::repo::runs::get(pool, started.run_id).await.unwrap();
}
assert_eq!( assert_eq!(
run.state, run.state,
RunState::AwaitingApproval, RunState::AwaitingApproval,