From 2383978a2c1f99997f2960c522be7b984485cb89 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 13 Feb 2026 09:51:22 -0800 Subject: [PATCH] fix: reduce flakiness of compact_resume_after_second_compaction_preserves_history (#11663) ## Why `compact_resume_after_second_compaction_preserves_history` has been intermittently flaky in Windows CI. The test had two one-shot request matchers in the second compact/resume phase that could overlap, and it waited for the first `Warning` event after compaction. In practice, that made the test sensitive to platform/config-specific prompt shape and unrelated warning timing. ## What Changed - Hardened the second compaction matcher in `codex-rs/core/tests/suite/compact_resume_fork.rs` so it accepts expected compact-request variants while explicitly excluding the `AFTER_SECOND_RESUME` payload. - Updated `compact_conversation()` to wait for the specific compaction warning (`COMPACT_WARNING_MESSAGE`) rather than any `Warning` event. - Added an inline comment explaining why the matcher is intentionally broad but disjoint from the follow-up resume matcher. ## Test Plan - `cargo test -p codex-core --test all suite::compact_resume_fork::compact_resume_after_second_compaction_preserves_history -- --exact` - Repeated the same test in a loop (40 runs) to check for local nondeterminism. --- .../core/tests/suite/compact_resume_fork.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/codex-rs/core/tests/suite/compact_resume_fork.rs b/codex-rs/core/tests/suite/compact_resume_fork.rs index ff90d4baf..fc77a2621 100644 --- a/codex-rs/core/tests/suite/compact_resume_fork.rs +++ b/codex-rs/core/tests/suite/compact_resume_fork.rs @@ -932,9 +932,16 @@ async fn mount_second_compact_flow(server: &MockServer) -> Vec { ]); let sse7 = sse(vec![ev_completed("r7")]); + // Keep this matcher broad enough to survive prompt-shape differences across + // platforms/config (history may include either marker text or compact prompt + // fragments), but explicitly exclude the final resume turn so these two + // one-shot mocks cannot race for the same request. let match_second_compact = |req: &wiremock::Request| { let body = std::str::from_utf8(&req.body).unwrap_or(""); - body.contains("AFTER_FORK") + (body.contains("AFTER_FORK") + || body_contains_text(body, SUMMARIZATION_PROMPT) + || body.contains(&json_fragment(FIRST_REPLY))) + && !body.contains(&format!("\"text\":\"{AFTER_SECOND_RESUME}\"")) }; let second_compact = mount_sse_once_match(server, match_second_compact, sse6).await; @@ -984,7 +991,13 @@ async fn compact_conversation(conversation: &Arc) { .submit(Op::Compact) .await .expect("compact conversation"); - let warning_event = wait_for_event(conversation, |ev| matches!(ev, EventMsg::Warning(_))).await; + let warning_event = wait_for_event(conversation, |ev| { + matches!( + ev, + EventMsg::Warning(WarningEvent { message }) if message == COMPACT_WARNING_MESSAGE + ) + }) + .await; let EventMsg::Warning(WarningEvent { message }) = warning_event else { panic!("expected warning event after compact"); };