Skip to content
Closed
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
1 change: 1 addition & 0 deletions codex-rs/app-server/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ codex_rust_crate(
integration_test_tags_extra_by_stem = {
"all": ["flaky"],
},
integration_test_args = ["--test-threads=2"],
integration_test_timeout = "long",
test_tags = ["no-sandbox"],
)
1 change: 1 addition & 0 deletions codex-rs/app-server/tests/common/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub use responses::create_final_assistant_message_sse_response;
pub use responses::create_request_permissions_sse_response;
pub use responses::create_request_user_input_sse_response;
pub use responses::create_shell_command_sse_response;
pub use responses::create_shell_command_sse_response_from_command;
pub use rollout::create_fake_rollout;
pub use rollout::create_fake_rollout_with_source;
pub use rollout::create_fake_rollout_with_text_elements;
Expand Down
32 changes: 29 additions & 3 deletions codex-rs/app-server/tests/common/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,37 @@ pub fn create_shell_command_sse_response(
) -> anyhow::Result<String> {
// The `arguments` for the `shell_command` tool is a serialized JSON object.
let command_str = shlex::try_join(command.iter().map(String::as_str))?;
let tool_call_arguments = serde_json::to_string(&json!({
"command": command_str,
create_shell_command_sse_response_from_command(
&command_str,
workdir,
timeout_ms,
call_id,
/*login*/ None,
)
}

pub fn create_shell_command_sse_response_from_command(
command: &str,
workdir: Option<&Path>,
timeout_ms: Option<u64>,
call_id: &str,
login: Option<bool>,
) -> anyhow::Result<String> {
// Use this when a test already has a shell command string. It fixes string
// quoting for those callers by avoiding a rebuild from argv with POSIX
// rules, which can change how Windows PowerShell parses the command; for
// sleep-based tests, nested parsing can add another PowerShell startup
// before the requested sleep even begins.
let mut tool_call_arguments = json!({
"command": command,
"workdir": workdir.map(|w| w.to_string_lossy()),
"timeout_ms": timeout_ms
}))?;
});
if let Some(login) = login {
tool_call_arguments["login"] = json!(login);
}

let tool_call_arguments = serde_json::to_string(&tool_call_arguments)?;
Ok(responses::sse(vec![
responses::ev_response_created("resp-1"),
responses::ev_function_call(call_id, "shell_command", &tool_call_arguments),
Expand Down
22 changes: 21 additions & 1 deletion codex-rs/app-server/tests/suite/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,32 @@ use codex_login::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
use pretty_assertions::assert_eq;
use std::path::Path;
use tempfile::TempDir;
use tokio::time::sleep;
use tokio::time::timeout;
use wiremock::Mock;
use wiremock::MockServer;
use wiremock::ResponseTemplate;
use wiremock::matchers::method;
use wiremock::matchers::path;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

async fn wait_for_received_requests(server: &MockServer, expected: usize) -> Result<()> {
timeout(DEFAULT_READ_TIMEOUT, async {
loop {
let received = server
.received_requests()
.await
.map_or(0, |requests| requests.len());
if received >= expected {
break;
}
sleep(std::time::Duration::from_millis(25)).await;
}
})
.await?;
Ok(())
}

fn create_config_toml_custom_provider(
codex_home: &Path,
Expand Down Expand Up @@ -373,6 +391,7 @@ async fn get_auth_status_omits_token_after_proactive_refresh_failure() -> Result
)
.await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
wait_for_received_requests(&server, /*expected*/ 1).await?;

let request_id = mcp
.send_get_auth_status_request(GetAuthStatusParams {
Expand Down Expand Up @@ -440,6 +459,7 @@ async fn get_auth_status_returns_token_after_proactive_refresh_recovery() -> Res
)
.await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
wait_for_received_requests(&server, /*expected*/ 1).await?;

let failed_request_id = mcp
.send_get_auth_status_request(GetAuthStatusParams {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/conversation_summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::path::PathBuf;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
const FILENAME_TS: &str = "2025-01-02T12-00-00";
const META_RFC3339: &str = "2025-01-02T12:00:00Z";
const UPDATED_AT_RFC3339: &str = "2025-01-02T12:00:00.000Z";
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/fuzzy_file_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
const SHORT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(500);
const STOP_GRACE_PERIOD: std::time::Duration = std::time::Duration::from_millis(250);
const SESSION_UPDATED_METHOD: &str = "fuzzyFileSearch/sessionUpdated";
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/app_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn list_apps_returns_empty_when_connectors_disabled() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/client_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test]
async fn turn_start_forwards_client_metadata_to_responses_request_v2() -> Result<()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use pretty_assertions::assert_eq;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

/// Confirms the server returns the default collaboration mode presets in a stable order.
#[tokio::test]
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/compaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use std::collections::BTreeMap;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
const AUTO_COMPACT_LIMIT: i64 = 1_000;
const COMPACT_PROMPT: &str = "Summarize the conversation.";
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/config_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use serde_json::json;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

fn write_config(codex_home: &TempDir, contents: &str) -> Result<()> {
Ok(std::fs::write(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use tokio_tungstenite::tungstenite::http::HeaderValue;
use tokio_tungstenite::tungstenite::http::header::AUTHORIZATION;
use tokio_tungstenite::tungstenite::http::header::ORIGIN;

pub(super) const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
pub(super) const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);

pub(super) type WsClient = WebSocketStream<MaybeTlsStream<tokio::net::TcpStream>>;
type HmacSha256 = Hmac<Sha256>;
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/dynamic_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use tempfile::TempDir;
use tokio::time::timeout;
use wiremock::MockServer;

const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);

/// Ensures dynamic tool specs are serialized into the model request payload.
#[tokio::test]
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/experimental_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::time::Duration;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn mock_experimental_method_requires_experimental_api_capability() -> Result<()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::collections::BTreeMap;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn experimental_feature_list_returns_feature_metadata_with_stage() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::os::unix::fs::symlink;
#[cfg(unix)]
use std::process::Command;

const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);

async fn initialized_mcp(codex_home: &TempDir) -> Result<McpProcess> {
let mut mcp = McpProcess::new(codex_home.path()).await?;
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::time::Duration;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test]
async fn initialize_uses_client_info_name_as_originator() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/marketplace_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tempfile::TempDir;
use tokio::time::Duration;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn marketplace_add_local_directory_source() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/mcp_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use tempfile::TempDir;
use tokio::net::TcpListener;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);
const TEST_RESOURCE_URI: &str = "test://codex/resource";
const TEST_BLOB_RESOURCE_URI: &str = "test://codex/resource.bin";
const TEST_RESOURCE_BLOB: &str = "YmluYXJ5LXJlc291cmNl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
const CONNECTOR_ID: &str = "calendar";
const CONNECTOR_NAME: &str = "Calendar";
const TOOL_NAMESPACE: &str = "mcp__codex_apps__calendar";
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/mcp_server_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn mcp_server_status_list_returns_raw_server_and_tool_names() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/mcp_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(30);
const TEST_SERVER_NAME: &str = "tool_server";
const TEST_TOOL_NAME: &str = "echo_tool";

Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/memory_reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use tempfile::TempDir;
use tokio::time::timeout;
use uuid::Uuid;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test]
async fn memory_reset_clears_memory_files_and_rows_preserves_threads() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/model_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use pretty_assertions::assert_eq;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;

fn model_from_preset(preset: &ModelPreset) -> Model {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/output_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test]
async fn turn_start_accepts_output_schema_v2() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/plan_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use tokio::time::sleep;
use tokio::time::timeout;
use wiremock::MockServer;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn plan_mode_uses_proposed_plan_block_for_plan_item() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/plugin_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use wiremock::matchers::header;
use wiremock::matchers::method;
use wiremock::matchers::path;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn plugin_install_rejects_relative_marketplace_paths() -> Result<()> {
Expand Down
12 changes: 10 additions & 2 deletions codex-rs/app-server/tests/suite/v2/plugin_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use wiremock::matchers::method;
use wiremock::matchers::path;
use wiremock::matchers::query_param;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
const TEST_CURATED_PLUGIN_SHA: &str = "0123456789abcdef0123456789abcdef01234567";
const STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE: &str = ".tmp/app-server-remote-plugin-sync-v1";

Expand Down Expand Up @@ -733,10 +733,18 @@ async fn plugin_list_accepts_legacy_string_default_prompt() -> Result<()> {
#[tokio::test]
async fn plugin_list_force_remote_sync_returns_remote_sync_error_on_fail_open() -> Result<()> {
let codex_home = TempDir::new()?;
write_plugin_sync_config(codex_home.path(), "https://chatgpt.com/backend-api/")?;
let server = MockServer::start().await;
write_plugin_sync_config(codex_home.path(), &format!("{}/backend-api/", server.uri()))?;
write_openai_curated_marketplace(codex_home.path(), &["linear"])?;
write_installed_plugin(&codex_home, "openai-curated", "linear")?;

Mock::given(method("GET"))
.and(path("/backend-api/plugins/featured"))
.and(query_param("platform", "codex"))
.respond_with(ResponseTemplate::new(200).set_body_string("[]"))
.mount(&server)
.await;

let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;

Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/plugin_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle;
use tokio::time::timeout;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn plugin_read_returns_plugin_details_with_bundle_contents() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/plugin_uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use wiremock::matchers::header;
use wiremock::matchers::method;
use wiremock::matchers::path;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);

#[tokio::test]
async fn plugin_uninstall_removes_plugin_cache_and_config_entry() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/rate_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use wiremock::matchers::header;
use wiremock::matchers::method;
use wiremock::matchers::path;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;

#[tokio::test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ use wiremock::matchers::method;
use wiremock::matchers::path;
use wiremock::matchers::path_regex;

const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
const STARTUP_CONTEXT_HEADER: &str = "Startup context from Codex.";
const V2_STEERING_ACKNOWLEDGEMENT: &str =
"This was sent to steer the previous background agent task.";
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/request_permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use codex_app_server_protocol::TurnStartResponse;
use codex_app_server_protocol::UserInput as V2UserInput;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn request_permissions_round_trip() -> Result<()> {
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/tests/suite/v2/request_user_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use codex_protocol::config_types::Settings;
use codex_protocol::openai_models::ReasoningEffort;
use tokio::time::timeout;

const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn request_user_input_round_trip() -> Result<()> {
Expand Down
Loading
Loading