Compare commits

...

6 Commits

Author SHA1 Message Date
Dylan Hurd
05890fc612 Trigger second CI verification run 2026-02-01 21:03:41 -08:00
Dylan Hurd
6ac6293460 Increase Windows timeout budget for v2 app-server tests 2026-02-01 20:45:17 -08:00
Dylan Hurd
1173d2ef93 Increase Windows shell test timeout budget 2026-02-01 20:29:49 -08:00
Dylan Hurd
f27ef275b2 Increase Windows timeout for app-server flow tests 2026-02-01 20:15:43 -08:00
Dylan Hurd
5ad8c4783e Stabilize flaky Windows integration tests 2026-02-01 19:53:03 -08:00
Dylan Hurd
803c8a02f0 Relax mock call count in jsonrpc flow test 2026-02-01 19:45:01 -08:00
26 changed files with 92 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::create_shell_command_sse_response;
use app_test_support::format_with_current_shell;
use app_test_support::to_response;
@@ -36,6 +36,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
@@ -65,7 +68,7 @@ async fn test_codex_jsonrpc_conversation_flow() -> Result<()> {
)?,
create_final_assistant_message_sse_response("Enjoy your new git repo!")?,
];
let server = create_mock_responses_server_sequence(responses).await;
let server = create_mock_responses_server_sequence_unchecked(responses).await;
create_config_toml(&codex_home, &server.uri())?;
// Start MCP server and initialize.
@@ -227,7 +230,7 @@ async fn test_send_user_turn_changes_approval_policy_behavior() -> Result<()> {
)?,
create_final_assistant_message_sse_response("done 2")?,
];
let server = create_mock_responses_server_sequence(responses).await;
let server = create_mock_responses_server_sequence_unchecked(responses).await;
create_config_toml(&codex_home, &server.uri())?;
// Start MCP server and initialize.
@@ -395,7 +398,7 @@ async fn test_send_user_turn_updates_sandbox_and_cwd_between_turns() -> Result<(
)?,
create_final_assistant_message_sse_response("done second")?,
];
let server = create_mock_responses_server_sequence(responses).await;
let server = create_mock_responses_server_sequence_unchecked(responses).await;
create_config_toml(&codex_home, &server.uri())?;
let mut mcp = McpProcess::new(&codex_home).await?;

View File

@@ -42,6 +42,9 @@ use tokio::time::timeout;
use wiremock::MockServer;
use wiremock::ResponseTemplate;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
// Helper to create a minimal config.toml for the app server

View File

@@ -38,6 +38,9 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
#[tokio::test]

View File

@@ -22,6 +22,9 @@ use pretty_assertions::assert_eq;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
/// Confirms the server returns the default collaboration mode presets in a stable order.

View File

@@ -36,6 +36,9 @@ use std::collections::BTreeMap;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const AUTO_COMPACT_LIMIT: i64 = 1_000;
const COMPACT_PROMPT: &str = "Summarize the conversation.";

View File

@@ -28,6 +28,9 @@ use serde_json::json;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
fn write_config(codex_home: &TempDir, contents: &str) -> Result<()> {

View File

@@ -25,6 +25,9 @@ use tempfile::TempDir;
use tokio::time::timeout;
use wiremock::MockServer;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
/// Ensures dynamic tool specs are serialized into the model request payload.

View File

@@ -10,6 +10,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -17,6 +17,9 @@ use pretty_assertions::assert_eq;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;

View File

@@ -15,6 +15,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -30,6 +30,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -24,6 +24,9 @@ use wiremock::matchers::header;
use wiremock::matchers::method;
use wiremock::matchers::path;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;

View File

@@ -18,6 +18,9 @@ use codex_protocol::config_types::Settings;
use codex_protocol::openai_models::ReasoningEffort;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]

View File

@@ -20,6 +20,9 @@ use serde_json::json;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;

View File

@@ -13,6 +13,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -18,6 +18,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -30,6 +30,9 @@ use tempfile::TempDir;
use tokio::time::timeout;
use uuid::Uuid;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
async fn init_mcp(codex_home: &Path) -> Result<McpProcess> {

View File

@@ -13,6 +13,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -19,6 +19,9 @@ use std::path::PathBuf;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -30,6 +30,9 @@ use std::path::PathBuf;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const CODEX_5_2_INSTRUCTIONS_TEMPLATE_DEFAULT: &str = "You are Codex, a coding agent based on GPT-5. You and the user share the same workspace and collaborate to achieve the user's goals.";

View File

@@ -18,6 +18,9 @@ use pretty_assertions::assert_eq;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -15,6 +15,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -20,6 +20,9 @@ use codex_app_server_protocol::UserInput as V2UserInput;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test]

View File

@@ -50,6 +50,9 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(25);
#[cfg(not(target_os = "windows"))]
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const TEST_ORIGINATOR: &str = "codex_vscode";
@@ -685,7 +688,7 @@ async fn turn_start_exec_approval_toggle_v2() -> Result<()> {
)?,
create_final_assistant_message_sse_response("done 2")?,
];
let server = create_mock_responses_server_sequence(responses).await;
let server = create_mock_responses_server_sequence_unchecked(responses).await;
// Default approval is untrusted to force elicitation on first turn.
create_config_toml(
codex_home.as_path(),

View File

@@ -185,8 +185,11 @@ pub async fn wait_for_event<F>(codex: &CodexThread, predicate: F) -> codex_core:
where
F: FnMut(&codex_core::protocol::EventMsg) -> bool,
{
use tokio::time::Duration;
wait_for_event_with_timeout(codex, predicate, Duration::from_secs(1)).await
#[cfg(target_os = "windows")]
let wait_time = tokio::time::Duration::from_secs(3);
#[cfg(not(target_os = "windows"))]
let wait_time = tokio::time::Duration::from_secs(1);
wait_for_event_with_timeout(codex, predicate, wait_time).await
}
pub async fn wait_for_event_match<T, F>(codex: &CodexThread, matcher: F) -> T
@@ -205,11 +208,14 @@ pub async fn wait_for_event_with_timeout<F>(
where
F: FnMut(&codex_core::protocol::EventMsg) -> bool,
{
use tokio::time::Duration;
use tokio::time::timeout;
#[cfg(target_os = "windows")]
let min_wait_time = tokio::time::Duration::from_secs(10);
#[cfg(not(target_os = "windows"))]
let min_wait_time = tokio::time::Duration::from_secs(5);
loop {
// Allow a bit more time to accommodate async startup work (e.g. config IO, tool discovery)
let ev = timeout(wait_time.max(Duration::from_secs(5)), codex.next_event())
let ev = timeout(wait_time.max(min_wait_time), codex.next_event())
.await
.expect("timeout waiting for event")
.expect("stream ended unexpectedly");

View File

@@ -20,6 +20,10 @@ use test_case::test_case;
/// Use this timeout if, empirically, a test seems to need more time than the
/// default.
const MEDIUM_TIMEOUT: Duration = Duration::from_secs(5);
#[cfg(target_os = "windows")]
const DEFAULT_SHELL_TIMEOUT_MS: i64 = 5_000;
#[cfg(not(target_os = "windows"))]
const DEFAULT_SHELL_TIMEOUT_MS: i64 = 2_000;
fn shell_responses_with_timeout(
call_id: &str,
@@ -50,7 +54,7 @@ fn shell_responses_with_timeout(
}
fn shell_responses(call_id: &str, command: &str, login: Option<bool>) -> Vec<String> {
shell_responses_with_timeout(call_id, command, login, 2_000)
shell_responses_with_timeout(call_id, command, login, DEFAULT_SHELL_TIMEOUT_MS)
}
async fn shell_command_harness_with(