Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions crates/freshell-ws/tests/codex_locator_activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,22 @@ async fn send_create(ws: &mut common::TestWs, mode: &str) -> String {
.to_string()
}

/// Scan WS text frames until `pred` matches or the 30s budget elapses.
/// Scan WS text frames until `pred` matches or the 120s budget elapses.
/// Non-matching frames are simply skipped (no drop-on-mismatch semantics).
///
/// DEFLAKE (f3wp refresh): was 10s. Under workspace-level load (full
/// cargo-test parallelism alongside a parallel playwright e2e run) the
/// inotify-driven rollout read plus frame delivery was observed to exceed
/// 10s once (`/tmp/f3wp-refresh/cargo-runverify1.log`, "expected
/// terminal.turn.complete ... stamped by the locator adoption",
/// 15.43s total test time). The assertions are unchanged -- only the wait
/// budget grew; a genuinely missing frame still fails, 20s later.
/// DEFLAKE (f3wp refresh → pkvz): was 10s → 30s. Under workspace-level load
/// (full cargo-test parallelism on a 4-core CI runner) the inotify-driven
/// rollout read plus the locator adoption sweep latency was observed to
/// exceed 30s (kata pkvz, 3+ CI occurrences). Bumped to 120s to cover the
/// observed sweep latency under contention with margin. The assertions are
/// unchanged — only the wait budget grew; a genuinely missing frame still
/// fails, 120s later.
#[cfg(unix)]
async fn wait_for_frame(
ws: &mut common::TestWs,
pred: impl Fn(&serde_json::Value) -> bool,
) -> bool {
let deadline = tokio::time::Instant::now() + Duration::from_secs(30);
let deadline = tokio::time::Instant::now() + Duration::from_secs(120);
while tokio::time::Instant::now() < deadline {
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
match tokio::time::timeout(remaining.max(Duration::from_millis(1)), ws.next()).await {
Expand Down
30 changes: 24 additions & 6 deletions crates/freshell-ws/tests/pane_reconcile_freshagent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,15 +871,33 @@ async fn dead_session_verdict_is_warn_logged_with_claimed_identity() {
assert_eq!(verdicts[0]["verdict"], "dead_session");
assert_eq!(verdicts[0]["reason"], "session_not_on_disk");

let events = events.lock().expect("capture lock");
let hits: Vec<&CapturedEvent> = events
.iter()
.filter(|e| e.message.contains("pane_reconcile.dead_session"))
.collect();
// The WARN is emitted before the response frame is sent, but under CI
// contention the tracing layer's push can lag the client's read by a
// scheduling quantum. Bounded-poll the capture instead of asserting
// immediately so the test is resilient to that lag without masking a
// genuinely missing log (a 5s budget on a current-thread runtime).
let hits = tokio::time::timeout(std::time::Duration::from_secs(5), async {
loop {
let hits: Vec<CapturedEvent> = {
let events = events.lock().expect("capture lock");
events
.iter()
.filter(|e| e.message.contains("pane_reconcile.dead_session"))
.cloned()
.collect()
};
if hits.len() == 1 {
return hits;
}
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
}
})
.await
.expect("dead_session WARN was not captured within 5s");
assert_eq!(
hits.len(),
1,
"exactly one dead_session WARN per dead verdict; got {events:?}"
"exactly one dead_session WARN per dead verdict; got {hits:?}"
);
let fields = &hits[0].fields;
assert!(
Expand Down
Loading