test: use automatic environments in app-server integration tests (#29789)

## Why

Topology-neutral app-server integration tests should exercise automatic
environment selection so the same setup covers local and remote
executors.

## What

Migrate eligible tests to `TestAppServer::new_with_auto_env()` and
`send_thread_start_request_with_auto_env()`. Leave explicit-topology
tests unchanged, and skip the request-permissions case on Windows with a
TODO for cross-platform tool routing.

## Validation

- `just test -p codex-app-server`
- `bazel test //codex-rs/app-server:app-server-all-wine-exec-test
--test_output=errors`

Stacked on #29788.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-23 22:48:06 -07:00
committed by GitHub
Unverified
parent b17f30eb2a
commit c2b3e3b4f5
34 changed files with 197 additions and 189 deletions
@@ -292,11 +292,11 @@ async fn list_apps_uses_thread_feature_flag_when_thread_id_is_provided() -> Resu
AuthCredentialsStoreMode::File,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let start_request = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -59,11 +59,11 @@ async fn turn_start_forwards_client_metadata_to_responses_request_v2() -> Result
/*supports_websockets*/ false,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
thread_source: Some(ThreadSource::Feature("automation".to_string())),
..Default::default()
})
@@ -434,11 +434,11 @@ async fn turn_steer_updates_client_metadata_on_follow_up_responses_request_v2()
/*supports_websockets*/ false,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
@@ -559,11 +559,11 @@ async fn turn_start_forwards_client_metadata_to_responses_websocket_request_body
/*supports_websockets*/ true,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
thread_source: Some(ThreadSource::Feature("automation".to_string())),
..Default::default()
})
@@ -40,11 +40,11 @@ async fn current_time_read_round_trip_adds_reminder_to_model_input() -> Result<(
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut app_server = TestAppServer::new(codex_home.path()).await?;
let mut app_server = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, app_server.initialize()).await??;
let thread_request_id = app_server
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_response: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
@@ -171,7 +171,7 @@ async fn thread_start_rejects_hidden_dynamic_tools_without_namespace() -> Result
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec::Function(DynamicToolFunctionSpec {
@@ -186,7 +186,7 @@ async fn thread_start_rejects_hidden_dynamic_tools_without_namespace() -> Result
});
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
dynamic_tools: Some(vec![dynamic_tool]),
..Default::default()
})
@@ -352,7 +352,7 @@ async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let input_schema = json!({
@@ -392,7 +392,7 @@ async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Res
});
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
dynamic_tools: Some(vec![dynamic_tool]),
..Default::default()
})
@@ -579,7 +579,7 @@ async fn start_function_dynamic_tool_call(call_id: &str) -> Result<PendingDynami
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec::Function(DynamicToolFunctionSpec {
@@ -597,7 +597,7 @@ async fn start_function_dynamic_tool_call(call_id: &str) -> Result<PendingDynami
});
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
dynamic_tools: Some(vec![dynamic_tool]),
..Default::default()
})
@@ -200,7 +200,7 @@ async fn initialize_opt_out_notification_methods_filters_notifications() -> Resu
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
@@ -224,7 +224,7 @@ async fn initialize_opt_out_notification_methods_filters_notifications() -> Resu
};
let request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let response = timeout(DEFAULT_READ_TIMEOUT, async {
loop {
@@ -283,7 +283,7 @@ async fn turn_start_notify_payload_includes_initialize_client_name() -> Result<(
),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_client_info(ClientInfo {
@@ -295,7 +295,7 @@ async fn turn_start_notify_payload_includes_initialize_client_name() -> Result<(
.await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
@@ -422,7 +422,7 @@ impl ElicitationRoundTripFixture {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_capabilities(
@@ -441,7 +441,7 @@ impl ElicitationRoundTripFixture {
.await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -94,11 +94,11 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -212,11 +212,11 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
approval_policy: Some(codex_app_server_protocol::AskForApproval::UnlessTrusted),
..Default::default()
@@ -322,11 +322,11 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
approval_policy: Some(codex_app_server_protocol::AskForApproval::UnlessTrusted),
..Default::default()
@@ -442,11 +442,11 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -32,11 +32,11 @@ async fn turn_start_accepts_output_schema_v2() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
..Default::default()
})
.await?;
@@ -115,11 +115,11 @@ async fn turn_start_output_schema_is_per_turn_v2() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
..Default::default()
})
.await?;
@@ -53,7 +53,7 @@ async fn plan_mode_uses_proposed_plan_block_for_plan_item() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let turn = start_plan_mode_turn(&mut mcp).await?;
@@ -111,7 +111,7 @@ async fn plan_mode_without_proposed_plan_does_not_emit_plan_item() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let _turn = start_plan_mode_turn(&mut mcp).await?;
@@ -129,7 +129,7 @@ async fn plan_mode_without_proposed_plan_does_not_emit_plan_item() -> Result<()>
async fn start_plan_mode_turn(mcp: &mut TestAppServer) -> Result<codex_app_server_protocol::Turn> {
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -655,12 +655,12 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -946,12 +946,12 @@ async fn realtime_start_can_skip_startup_context() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -1044,12 +1044,12 @@ async fn realtime_text_output_modality_requests_text_output_and_final_transcript
StartupContextConfig::Generated,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -1225,12 +1225,12 @@ async fn realtime_conversation_stop_emits_closed_notification() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -1328,12 +1328,12 @@ async fn realtime_webrtc_start_emits_sdp_notification() -> Result<()> {
StartupContextConfig::Override("startup context"),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -2683,13 +2683,13 @@ async fn realtime_webrtc_start_surfaces_backend_error() -> Result<()> {
StartupContextConfig::Override("startup context"),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
// Phase 2: start a normal app-server thread and request realtime over WebRTC.
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -2751,11 +2751,11 @@ async fn realtime_conversation_requires_feature_flag() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread_start_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_start_response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -16,12 +16,19 @@ use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::TurnStartParams;
use codex_app_server_protocol::TurnStartResponse;
use codex_app_server_protocol::UserInput as V2UserInput;
use core_test_support::skip_if_wine_exec;
use tokio::time::timeout;
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn request_permissions_round_trip() -> Result<()> {
// TODO(anp): Remove after tool routing accepts a target-native cwd on a different host OS.
skip_if_wine_exec!(
Ok(()),
"request_permissions currently rejects the target-native Windows cwd on the Linux host"
);
let codex_home = tempfile::TempDir::new()?;
let responses = vec![
create_request_permissions_sse_response("call1")?,
@@ -30,11 +37,11 @@ async fn request_permissions_round_trip() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -62,11 +62,11 @@ async fn request_user_input_round_trip() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -30,11 +30,11 @@ async fn request_handlers_reject_remote_image_urls() -> Result<()> {
"http://localhost/unused",
"http://localhost/unused",
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_request_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let thread_response: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
+7 -7
View File
@@ -59,7 +59,7 @@ async fn review_start_runs_review_turn_and_emits_code_review_item() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -173,7 +173,7 @@ async fn review_start_exec_approval_item_id_matches_command_execution_item() ->
let codex_home = TempDir::new()?;
create_config_toml_with_approval_policy(codex_home.path(), &server.uri(), "untrusted")?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -256,7 +256,7 @@ async fn review_start_rejects_empty_base_branch() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -299,7 +299,7 @@ async fn review_start_with_detached_delivery_returns_new_thread_id() -> Result<(
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -377,7 +377,7 @@ async fn review_start_rejects_empty_commit_sha() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -412,7 +412,7 @@ async fn review_start_rejects_empty_custom_instructions() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -445,7 +445,7 @@ async fn review_start_rejects_empty_custom_instructions() -> Result<()> {
async fn start_default_thread(mcp: &mut TestAppServer) -> Result<String> {
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -49,11 +49,11 @@ async fn openai_model_header_mismatch_emits_model_rerouted_notification_v2() ->
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(REQUESTED_MODEL.to_string()),
..Default::default()
})
@@ -116,11 +116,11 @@ async fn cyber_policy_response_emits_typed_error_notification_v2() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(REQUESTED_MODEL.to_string()),
..Default::default()
})
@@ -193,11 +193,11 @@ async fn response_model_field_mismatch_emits_model_rerouted_notification_v2_when
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(REQUESTED_MODEL.to_string()),
..Default::default()
})
@@ -262,11 +262,11 @@ async fn model_verification_emits_typed_notification_and_warning_v2() -> Result<
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(REQUESTED_MODEL.to_string()),
..Default::default()
})
@@ -336,11 +336,11 @@ async fn turn_moderation_metadata_emits_typed_notification_v2() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(REQUESTED_MODEL.to_string()),
..Default::default()
})
+2 -2
View File
@@ -50,11 +50,11 @@ async fn sleep_emits_started_and_completed_items() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -38,12 +38,12 @@ async fn thread_archive_requires_materialized_rollout() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -499,11 +499,11 @@ async fn thread_archive_clears_stale_subscriptions_before_resume() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
let mut primary = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -539,7 +539,7 @@ async fn thread_archive_clears_stale_subscriptions_before_resume() -> Result<()>
.await??;
primary.clear_message_buffer();
let mut secondary = TestAppServer::new(codex_home.path()).await?;
let mut secondary = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, secondary.initialize()).await??;
let archive_id = primary
@@ -122,11 +122,11 @@ fn create_delete_test_rollout(codex_home: &Path, minute: u8, preview: &str) -> R
async fn thread_delete_handles_live_threads_before_rollout_exists() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let start_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
@@ -155,7 +155,7 @@ async fn thread_delete_handles_live_threads_before_rollout_exists() -> Result<()
let _: ThreadDeleteResponse = to_response::<ThreadDeleteResponse>(delete_resp)?;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
ephemeral: Some(true),
..Default::default()
})
@@ -507,11 +507,11 @@ async fn thread_fork_rejects_unmaterialized_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -36,11 +36,11 @@ async fn thread_inject_items_adds_raw_response_items_to_thread_history() -> Resu
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -153,11 +153,11 @@ async fn thread_inject_items_adds_raw_response_items_after_a_turn() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -21,7 +21,7 @@ async fn thread_loaded_list_returns_loaded_thread_ids() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -51,7 +51,7 @@ async fn thread_loaded_list_paginates() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let first = start_thread(&mut mcp).await?;
@@ -124,7 +124,7 @@ stream_max_retries = 0
async fn start_thread(mcp: &mut TestAppServer) -> Result<String> {
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.2".to_string()),
..Default::default()
})
@@ -27,11 +27,11 @@ async fn thread_memory_mode_set_updates_loaded_thread_state() -> Result<()> {
create_config_toml(codex_home.path(), &server.uri())?;
let state_db = init_state_db(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -41,11 +41,11 @@ async fn thread_metadata_update_patches_git_branch_and_returns_updated_thread()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -136,11 +136,11 @@ async fn thread_metadata_update_rejects_empty_git_info_patch() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -182,11 +182,11 @@ async fn thread_metadata_update_rejects_ephemeral_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
ephemeral: Some(true),
..Default::default()
@@ -830,11 +830,11 @@ async fn thread_read_loaded_thread_returns_precomputed_path_before_materializati
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1037,11 +1037,11 @@ async fn thread_read_include_turns_rejects_unmaterialized_loaded_thread() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1088,11 +1088,11 @@ async fn thread_turns_list_rejects_unmaterialized_loaded_thread() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1180,11 +1180,11 @@ async fn thread_read_reports_system_error_idle_flag_after_failed_turn() -> Resul
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -154,12 +154,12 @@ async fn thread_resume_rejects_unmaterialized_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.4".to_string()),
..Default::default()
})
@@ -201,11 +201,11 @@ async fn thread_resume_with_empty_path_uses_running_thread_id() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.4".to_string()),
..Default::default()
})
@@ -35,12 +35,12 @@ async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -63,12 +63,12 @@ async fn thread_start_creates_thread_and_emits_started() -> Result<()> {
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
// Start server and initialize.
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a v2 thread with an explicit model override.
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.2".to_string()),
thread_source: Some(ThreadSource::User),
..Default::default()
@@ -618,12 +618,12 @@ async fn thread_start_drops_unsupported_service_tier_id() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let service_tier_id = "experimental-tier-id".to_string();
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
service_tier: Some(Some(service_tier_id.clone())),
..Default::default()
})
@@ -648,11 +648,11 @@ async fn thread_start_accepts_default_service_tier() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
service_tier: Some(Some(SERVICE_TIER_DEFAULT_REQUEST_VALUE.to_string())),
..Default::default()
})
@@ -679,11 +679,11 @@ async fn thread_start_accepts_metrics_service_name() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
service_name: Some("my_app_server_client".to_string()),
..Default::default()
})
@@ -706,11 +706,11 @@ async fn thread_start_ephemeral_remains_pathless() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.2".to_string()),
ephemeral: Some(true),
..Default::default()
@@ -752,11 +752,11 @@ async fn thread_start_fails_when_required_mcp_server_fails_to_initialize() -> Re
let codex_home = TempDir::new()?;
create_config_toml_with_required_broken_mcp(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let err: JSONRPCError = timeout(
@@ -788,11 +788,11 @@ async fn thread_start_emits_mcp_server_status_updated_notifications() -> Result<
let codex_home = TempDir::new()?;
create_config_toml_with_optional_broken_mcp(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.send_thread_start_request_with_auto_env(ThreadStartParams::default())
.await?;
let start_response: ThreadStartResponse = to_response(
@@ -135,7 +135,7 @@ async fn thread_status_changed_can_be_opted_out() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_capabilities(
@@ -158,7 +158,7 @@ async fn thread_status_changed_can_be_opted_out() -> Result<()> {
};
let thread_start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -59,11 +59,11 @@ async fn thread_unarchive_moves_rollout_back_into_sessions_directory() -> Result
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -141,11 +141,11 @@ async fn turn_interrupt_rejects_completed_turn() -> Result<()> {
.await;
create_config_toml(&codex_home, &server.uri(), "never", "workspace-write")?;
let mut mcp = TestAppServer::new(&codex_home).await?;
let mut mcp = TestAppServer::new_with_auto_env(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -133,11 +133,11 @@ async fn run_local_image_turn(detail: Option<ImageDetail>) -> Result<Vec<Value>>
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -230,11 +230,11 @@ async fn turn_start_with_empty_input_runs_model_request() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
thread_source: Some(ThreadSource::User),
..Default::default()
@@ -332,11 +332,11 @@ async fn turn_start_additional_context_flows_to_model_input() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -409,7 +409,7 @@ async fn turn_start_sends_originator_header() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_client_info(ClientInfo {
@@ -421,7 +421,7 @@ async fn turn_start_sends_originator_header() -> Result<()> {
.await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
thread_source: Some(ThreadSource::User),
..Default::default()
@@ -486,11 +486,11 @@ async fn turn_start_emits_user_message_item_with_text_elements() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
thread_source: Some(ThreadSource::User),
..Default::default()
@@ -702,11 +702,11 @@ async fn turn_start_sends_service_tier_id_to_model_request() -> Result<()> {
.expect("bundled model catalog should include a picker model with service tiers");
let service_tier_id = service_tier_model.service_tiers[0].id.clone();
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some(service_tier_model.id.clone()),
..Default::default()
})
@@ -766,11 +766,11 @@ async fn thread_start_omits_empty_instruction_overrides_from_model_request() ->
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
// TODO(aibrahim): Replace empty string instruction overrides with explicit tri-state
// app-server semantics: omitted, explicitly none, or explicit value.
config: Some(HashMap::from([(
@@ -1093,11 +1093,11 @@ async fn turn_start_accepts_text_at_limit_with_mention_item() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1153,11 +1153,11 @@ async fn turn_start_rejects_combined_oversized_text_input() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1233,11 +1233,11 @@ async fn turn_start_rejects_invalid_permission_selection_before_starting_turn()
"sandbox_mode = \"read-only\"\n",
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1380,12 +1380,12 @@ async fn turn_start_emits_notifications_and_accepts_model_override() -> Result<(
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread (v2) and capture its id.
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1525,11 +1525,11 @@ async fn turn_start_accepts_collaboration_mode_override_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
..Default::default()
})
@@ -1611,11 +1611,11 @@ async fn turn_start_uses_thread_feature_overrides_for_request_user_input_tool_de
&BTreeMap::default(),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
config: Some(HashMap::from([(
"features.default_mode_request_user_input".to_string(),
@@ -1696,11 +1696,11 @@ async fn turn_start_accepts_personality_override_v2() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("exp-codex-personality".to_string()),
..Default::default()
})
@@ -1773,11 +1773,11 @@ async fn turn_start_accepts_multi_agent_mode_v2() -> Result<()> {
&BTreeMap::from([(Feature::MultiAgentV2, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
..Default::default()
})
@@ -1847,11 +1847,11 @@ async fn thread_start_multi_agent_mode_initializes_first_turn() -> Result<()> {
&BTreeMap::from([(Feature::MultiAgentV2, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
multi_agent_mode: Some(MultiAgentMode::Proactive),
..Default::default()
@@ -1938,10 +1938,10 @@ async fn thread_start_reports_multi_agent_mode() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never", &features)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("mock-model".to_string()),
multi_agent_mode: requested_multi_agent_mode,
..Default::default()
@@ -1985,11 +1985,11 @@ async fn turn_start_change_personality_mid_thread_v2() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("exp-codex-personality".to_string()),
..Default::default()
})
@@ -2101,7 +2101,7 @@ async fn turn_start_uses_migrated_pragmatic_personality_without_override_v2() ->
/*git_info*/ None,
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let persisted_toml: ConfigToml = toml::from_str(&std::fs::read_to_string(
@@ -2117,7 +2117,7 @@ async fn turn_start_uses_migrated_pragmatic_personality_without_override_v2() ->
);
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
..Default::default()
})
@@ -3452,11 +3452,11 @@ async fn turn_start_emits_spawn_agent_item_with_model_metadata_v2() -> Result<()
&BTreeMap::from([(Feature::Collab, true)]),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
..Default::default()
})
@@ -3670,11 +3670,11 @@ async fn direct_input_to_multi_agent_v2_subagent_is_rejected() -> Result<()> {
)?;
write_models_cache(codex_home.path())?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
..Default::default()
})
@@ -3848,11 +3848,11 @@ config_file = "./custom-role.toml"
),
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
.send_thread_start_request_with_auto_env(ThreadStartParams {
model: Some("gpt-5.3-codex".to_string()),
..Default::default()
})
+7 -6
View File
@@ -50,6 +50,7 @@ use core_test_support::skip_if_no_network;
use core_test_support::skip_if_no_remote_env;
use core_test_support::skip_if_remote;
use core_test_support::skip_if_target_windows;
use core_test_support::skip_if_wine_exec;
use core_test_support::test_codex::TestCodexBuilder;
use core_test_support::test_codex::TestCodexHarness;
use core_test_support::test_codex::local;
@@ -649,7 +650,7 @@ async fn apply_patch_cli_delete_directory_reports_verification_error() -> Result
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_cli_rejects_path_traversal_outside_workspace() -> Result<()> {
// TODO(anp): Remove after apply_patch path handling supports target-native Windows paths.
skip_if_target_windows!(Ok(()), "asserts POSIX path traversal behavior");
skip_if_wine_exec!(Ok(()), "asserts POSIX path traversal behavior");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness().await?;
@@ -979,7 +980,7 @@ async fn apply_patch_cli_verification_failure_has_no_side_effects() -> Result<()
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_shell_command_heredoc_with_cd_updates_relative_workdir() -> Result<()> {
// TODO(anp): Remove after apply_patch shell fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX shell heredoc and cd command");
skip_if_wine_exec!(Ok(()), "uses a POSIX shell heredoc and cd command");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness_with(|builder| builder.with_model("gpt-5.4")).await?;
@@ -1263,7 +1264,7 @@ async fn apply_patch_custom_tool_streaming_emits_updated_changes() -> Result<()>
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_shell_command_heredoc_with_cd_emits_turn_diff() -> Result<()> {
// TODO(anp): Remove after apply_patch shell fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX shell heredoc and cd command");
skip_if_wine_exec!(Ok(()), "uses a POSIX shell heredoc and cd command");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness_with(|builder| builder.with_model("gpt-5.4")).await?;
@@ -1327,7 +1328,7 @@ async fn apply_patch_shell_command_heredoc_with_cd_emits_turn_diff() -> Result<(
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_turn_diff_paths_stay_repo_relative_when_session_cwd_is_nested() -> Result<()> {
// TODO(anp): Remove after apply_patch diff fixtures use target-native paths.
skip_if_target_windows!(Ok(()), "asserts POSIX repository paths");
skip_if_wine_exec!(Ok(()), "asserts POSIX repository paths");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness_with(|builder| {
@@ -1400,7 +1401,7 @@ async fn apply_patch_turn_diff_paths_stay_repo_relative_when_session_cwd_is_nest
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_shell_command_failure_propagates_error_and_skips_diff() -> Result<()> {
// TODO(anp): Remove after apply_patch shell fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX shell heredoc");
skip_if_wine_exec!(Ok(()), "uses a POSIX shell heredoc");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness_with(|builder| builder.with_model("gpt-5.4")).await?;
@@ -1459,7 +1460,7 @@ async fn apply_patch_shell_command_failure_propagates_error_and_skips_diff() ->
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn apply_patch_shell_accepts_lenient_heredoc_wrapped_patch() -> Result<()> {
// TODO(anp): Remove after apply_patch shell fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX shell heredoc");
skip_if_wine_exec!(Ok(()), "uses a POSIX shell heredoc");
skip_if_no_network!(Ok(()));
let harness = apply_patch_harness().await?;
+2 -2
View File
@@ -31,7 +31,7 @@ use core_test_support::responses::sse;
use core_test_support::responses::sse_completed;
use core_test_support::responses::start_mock_server;
use core_test_support::skip_if_no_network;
use core_test_support::skip_if_target_windows;
use core_test_support::skip_if_wine_exec;
use core_test_support::test_codex::TestCodex;
use core_test_support::test_codex::local_selections;
use core_test_support::test_codex::test_codex;
@@ -797,7 +797,7 @@ async fn model_change_from_generated_image_to_text_preserves_prior_generated_ima
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn thread_rollback_after_generated_image_drops_entire_image_turn_history() -> Result<()> {
// TODO(anp): Remove after generated-image artifacts use target-native paths.
skip_if_target_windows!(Ok(()), "uses host-native generated-image artifact paths");
skip_if_wine_exec!(Ok(()), "uses host-native generated-image artifact paths");
skip_if_no_network!(Ok(()));
let server = MockServer::start().await;
+2 -2
View File
@@ -27,7 +27,7 @@ use core_test_support::responses::mount_sse_sequence;
use core_test_support::responses::namespace_child_tool;
use core_test_support::responses::sse;
use core_test_support::responses::start_mock_server;
use core_test_support::skip_if_target_windows;
use core_test_support::skip_if_wine_exec;
use core_test_support::test_codex::TestCodex;
use pretty_assertions::assert_eq;
use serde_json::Value;
@@ -186,7 +186,7 @@ async fn run_extract_turn(test: &TestCodex, server: &MockServer) -> Result<Respo
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn codex_apps_file_params_upload_environment_files_before_mcp_tool_call() -> Result<()> {
// TODO(anp): Remove after file-upload fixtures support target-native Windows paths.
skip_if_target_windows!(Ok(()), "uses a host-native file-upload path");
skip_if_wine_exec!(Ok(()), "uses a host-native file-upload path");
let server = start_mock_server().await;
let apps_server = AppsTestServer::mount(&server).await?;