From c4af304c7710059237133e6c597d25abd35428bd Mon Sep 17 00:00:00 2001 From: Celia Chen Date: Thu, 8 Jan 2026 10:17:05 -0800 Subject: [PATCH] [fix] app server flaky thread/resume tests (#8870) Fix flakiness of CI tests: https://github.com/openai/codex/actions/runs/20350530276/job/58473691443?pr=8282 This PR does two things: 1. test with responses API instead of chat completions API in thread_resume tests; 2. have a new responses API fixture that mocks out arbitrary numbers of responses API calls (including no calls) and have the same repeated response. Tested by CI --- codex-rs/app-server/tests/common/lib.rs | 1 + .../tests/common/mock_model_server.rs | 18 ++++++++++++++++++ .../app-server/tests/suite/v2/thread_resume.rs | 12 ++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/codex-rs/app-server/tests/common/lib.rs b/codex-rs/app-server/tests/common/lib.rs index f3950595b..38beab779 100644 --- a/codex-rs/app-server/tests/common/lib.rs +++ b/codex-rs/app-server/tests/common/lib.rs @@ -20,6 +20,7 @@ pub use core_test_support::test_tmp_path_buf; pub use mcp_process::McpProcess; pub use mock_model_server::create_mock_chat_completions_server; pub use mock_model_server::create_mock_chat_completions_server_unchecked; +pub use mock_model_server::create_mock_responses_server_repeating_assistant; pub use models_cache::write_models_cache; pub use models_cache::write_models_cache_with_models; pub use responses::create_apply_patch_sse_response; diff --git a/codex-rs/app-server/tests/common/mock_model_server.rs b/codex-rs/app-server/tests/common/mock_model_server.rs index 08765338a..77fa6b201 100644 --- a/codex-rs/app-server/tests/common/mock_model_server.rs +++ b/codex-rs/app-server/tests/common/mock_model_server.rs @@ -1,12 +1,14 @@ use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; +use core_test_support::responses; use wiremock::Mock; use wiremock::MockServer; use wiremock::Respond; use wiremock::ResponseTemplate; use wiremock::matchers::method; use wiremock::matchers::path; +use wiremock::matchers::path_regex; /// Create a mock server that will provide the responses, in order, for /// requests to the `/v1/chat/completions` endpoint. @@ -64,3 +66,19 @@ impl Respond for SeqResponder { } } } + +/// Create a mock responses API server that returns the same assistant message for every request. +pub async fn create_mock_responses_server_repeating_assistant(message: &str) -> MockServer { + let server = responses::start_mock_server().await; + let body = responses::sse(vec![ + responses::ev_response_created("resp-1"), + responses::ev_assistant_message("msg-1", message), + responses::ev_completed("resp-1"), + ]); + Mock::given(method("POST")) + .and(path_regex(".*/responses$")) + .respond_with(responses::sse_response(body)) + .mount(&server) + .await; + server +} diff --git a/codex-rs/app-server/tests/suite/v2/thread_resume.rs b/codex-rs/app-server/tests/suite/v2/thread_resume.rs index be8562e2f..483095a98 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_resume.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_resume.rs @@ -1,7 +1,7 @@ use anyhow::Result; use app_test_support::McpProcess; use app_test_support::create_fake_rollout; -use app_test_support::create_mock_chat_completions_server; +use app_test_support::create_mock_responses_server_repeating_assistant; use app_test_support::to_response; use codex_app_server_protocol::JSONRPCResponse; use codex_app_server_protocol::RequestId; @@ -23,7 +23,7 @@ const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs #[tokio::test] async fn thread_resume_returns_original_thread() -> Result<()> { - let server = create_mock_chat_completions_server(vec![]).await; + let server = create_mock_responses_server_repeating_assistant("Done").await; let codex_home = TempDir::new()?; create_config_toml(codex_home.path(), &server.uri())?; @@ -66,7 +66,7 @@ async fn thread_resume_returns_original_thread() -> Result<()> { #[tokio::test] async fn thread_resume_returns_rollout_history() -> Result<()> { - let server = create_mock_chat_completions_server(vec![]).await; + let server = create_mock_responses_server_repeating_assistant("Done").await; let codex_home = TempDir::new()?; create_config_toml(codex_home.path(), &server.uri())?; @@ -130,7 +130,7 @@ async fn thread_resume_returns_rollout_history() -> Result<()> { #[tokio::test] async fn thread_resume_prefers_path_over_thread_id() -> Result<()> { - let server = create_mock_chat_completions_server(vec![]).await; + let server = create_mock_responses_server_repeating_assistant("Done").await; let codex_home = TempDir::new()?; create_config_toml(codex_home.path(), &server.uri())?; @@ -174,7 +174,7 @@ async fn thread_resume_prefers_path_over_thread_id() -> Result<()> { #[tokio::test] async fn thread_resume_supports_history_and_overrides() -> Result<()> { - let server = create_mock_chat_completions_server(vec![]).await; + let server = create_mock_responses_server_repeating_assistant("Done").await; let codex_home = TempDir::new()?; create_config_toml(codex_home.path(), &server.uri())?; @@ -247,7 +247,7 @@ model_provider = "mock_provider" [model_providers.mock_provider] name = "Mock provider for test" base_url = "{server_uri}/v1" -wire_api = "chat" +wire_api = "responses" request_max_retries = 0 stream_max_retries = 0 "#