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.
This commit is contained in:
Michael Bolin
2026-02-13 09:51:22 -08:00
committed by GitHub
parent f687b074ca
commit 2383978a2c

View File

@@ -932,9 +932,16 @@ async fn mount_second_compact_flow(server: &MockServer) -> Vec<ResponseMock> {
]);
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<CodexThread>) {
.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");
};