mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Fix remote environment test fixtures (#22572)
## Why The Docker remote-env coverage was failing before it reached the behavior those tests are meant to exercise. The remote-aware test fixture only registered the remote environment, so tests that intentionally select both `local` and `remote` could not start a turn. After that was fixed, two tests exposed stale fixtures: the approval test was auto-approving under workspace-write, and the remote `view_image` test was writing invalid PNG bytes. ## What Changed - Added `EnvironmentManager::create_for_tests_with_local(...)` so tests can keep the provider default while also selecting `local` explicitly. - Updated `build_remote_aware()` to use that test-only manager when a remote exec-server URL is present. - Changed the remote apply-patch approval helper to use `SandboxPolicy::new_read_only_policy()` so the test actually exercises approval caching per environment. - Replaced the hardcoded remote `view_image` PNG blob with the existing `png_bytes(...)` helper so the test uses a valid image fixture. ## Validation Ran these isolated Docker remote-env tests on the devbox with `$remote-tests` setup: - `suite::remote_env::apply_patch_freeform_routes_to_selected_remote_environment` - `suite::remote_env::apply_patch_approvals_are_remembered_per_environment` - `suite::remote_env::apply_patch_intercepted_exec_command_routes_to_selected_remote_environment` - `suite::remote_env::exec_command_routes_to_selected_remote_environment` - `suite::view_image::view_image_routes_to_selected_remote_environment` All five pass.
This commit is contained in:
committed by
GitHub
Unverified
parent
e8969d940d
commit
255748638c
@@ -296,11 +296,14 @@ impl TestCodexBuilder {
|
||||
};
|
||||
let base_url = format!("{}/v1", server.uri());
|
||||
let test_env = TestEnv::local().await?;
|
||||
Box::pin(self.build_with_home_and_base_url(base_url, home, /*resume_from*/ None, test_env))
|
||||
.await
|
||||
Box::pin(self.build_with_home_and_base_url(
|
||||
base_url, home, /*resume_from*/ None, test_env,
|
||||
/*include_local_environment*/ false,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn build_remote_aware(
|
||||
pub async fn build_with_remote_env(
|
||||
&mut self,
|
||||
server: &wiremock::MockServer,
|
||||
) -> anyhow::Result<TestCodex> {
|
||||
@@ -310,8 +313,28 @@ impl TestCodexBuilder {
|
||||
};
|
||||
let base_url = format!("{}/v1", server.uri());
|
||||
let test_env = test_env().await?;
|
||||
Box::pin(self.build_with_home_and_base_url(base_url, home, /*resume_from*/ None, test_env))
|
||||
.await
|
||||
Box::pin(self.build_with_home_and_base_url(
|
||||
base_url, home, /*resume_from*/ None, test_env,
|
||||
/*include_local_environment*/ false,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn build_with_remote_and_local_env(
|
||||
&mut self,
|
||||
server: &wiremock::MockServer,
|
||||
) -> anyhow::Result<TestCodex> {
|
||||
let home = match self.home.clone() {
|
||||
Some(home) => home,
|
||||
None => Arc::new(TempDir::new()?),
|
||||
};
|
||||
let base_url = format!("{}/v1", server.uri());
|
||||
let test_env = test_env().await?;
|
||||
Box::pin(self.build_with_home_and_base_url(
|
||||
base_url, home, /*resume_from*/ None, test_env,
|
||||
/*include_local_environment*/ true,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn build_with_streaming_server(
|
||||
@@ -329,6 +352,7 @@ impl TestCodexBuilder {
|
||||
home,
|
||||
/*resume_from*/ None,
|
||||
test_env,
|
||||
/*include_local_environment*/ false,
|
||||
))
|
||||
.await
|
||||
}
|
||||
@@ -350,8 +374,11 @@ impl TestCodexBuilder {
|
||||
config.realtime.version = RealtimeWsVersion::V1;
|
||||
}));
|
||||
let test_env = TestEnv::local().await?;
|
||||
Box::pin(self.build_with_home_and_base_url(base_url, home, /*resume_from*/ None, test_env))
|
||||
.await
|
||||
Box::pin(self.build_with_home_and_base_url(
|
||||
base_url, home, /*resume_from*/ None, test_env,
|
||||
/*include_local_environment*/ false,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn resume(
|
||||
@@ -362,8 +389,14 @@ impl TestCodexBuilder {
|
||||
) -> anyhow::Result<TestCodex> {
|
||||
let base_url = format!("{}/v1", server.uri());
|
||||
let test_env = TestEnv::local().await?;
|
||||
Box::pin(self.build_with_home_and_base_url(base_url, home, Some(rollout_path), test_env))
|
||||
.await
|
||||
Box::pin(self.build_with_home_and_base_url(
|
||||
base_url,
|
||||
home,
|
||||
Some(rollout_path),
|
||||
test_env,
|
||||
/*include_local_environment*/ false,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn build_with_home_and_base_url(
|
||||
@@ -372,6 +405,7 @@ impl TestCodexBuilder {
|
||||
home: Arc<TempDir>,
|
||||
resume_from: Option<PathBuf>,
|
||||
test_env: TestEnv,
|
||||
include_local_environment: bool,
|
||||
) -> anyhow::Result<TestCodex> {
|
||||
let (config, fallback_cwd) = self
|
||||
.prepare_config(base_url, &home, test_env.cwd().clone())
|
||||
@@ -391,13 +425,19 @@ impl TestCodexBuilder {
|
||||
std::env::current_exe()?,
|
||||
codex_linux_sandbox_exe,
|
||||
)?;
|
||||
let environment_manager = Arc::new(
|
||||
let environment_manager = Arc::new(if include_local_environment {
|
||||
codex_exec_server::EnvironmentManager::create_for_tests_with_local(
|
||||
exec_server_url,
|
||||
local_runtime_paths,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
codex_exec_server::EnvironmentManager::create_for_tests(
|
||||
exec_server_url,
|
||||
local_runtime_paths,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
.await
|
||||
});
|
||||
let file_system = test_env.environment().get_filesystem();
|
||||
let mut workspace_setups = vec![];
|
||||
swap(&mut self.workspace_setups, &mut workspace_setups);
|
||||
@@ -788,9 +828,9 @@ impl TestCodexHarness {
|
||||
Ok(Self { server, test })
|
||||
}
|
||||
|
||||
pub async fn with_remote_aware_builder(mut builder: TestCodexBuilder) -> Result<Self> {
|
||||
pub async fn with_remote_env_builder(mut builder: TestCodexBuilder) -> Result<Self> {
|
||||
let server = start_mock_server().await;
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
Ok(Self { server, test })
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ async fn agents_instructions(mut builder: TestCodexBuilder) -> Result<String> {
|
||||
)
|
||||
.await;
|
||||
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
test.submit_turn("hello").await?;
|
||||
|
||||
let request = resp_mock.single_request();
|
||||
|
||||
@@ -64,7 +64,7 @@ async fn apply_patch_harness_with(
|
||||
});
|
||||
// Box harness construction so apply_patch_cli tests do not inline the
|
||||
// full test-thread startup path into each test future.
|
||||
Box::pin(TestCodexHarness::with_remote_aware_builder(builder)).await
|
||||
Box::pin(TestCodexHarness::with_remote_env_builder(builder)).await
|
||||
}
|
||||
|
||||
async fn submit_without_wait(harness: &TestCodexHarness, prompt: &str) -> Result<()> {
|
||||
|
||||
@@ -32,7 +32,7 @@ async fn hierarchical_agents_appends_to_project_doc_in_user_instructions() {
|
||||
Ok::<(), anyhow::Error>(())
|
||||
});
|
||||
let test = builder
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await
|
||||
.expect("build test codex");
|
||||
|
||||
@@ -76,7 +76,7 @@ async fn hierarchical_agents_emits_when_no_project_doc() {
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await
|
||||
.expect("build test codex");
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ async fn unified_exec_test(server: &wiremock::MockServer) -> Result<TestCodex> {
|
||||
"unified exec should enable for test: {result:?}",
|
||||
);
|
||||
});
|
||||
builder.build_remote_aware(server).await
|
||||
builder.build_with_remote_and_local_env(server).await
|
||||
}
|
||||
|
||||
async fn submit_turn_with_approval_and_environments(
|
||||
@@ -77,7 +77,7 @@ async fn submit_turn_with_approval_and_environments(
|
||||
cwd: test.cwd.path().to_path_buf(),
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
approvals_reviewer: Some(ApprovalsReviewer::User),
|
||||
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
permission_profile: None,
|
||||
model: test.session_configured.model.clone(),
|
||||
effort: None,
|
||||
@@ -350,7 +350,7 @@ async fn apply_patch_freeform_routes_to_selected_remote_environment() -> Result<
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.include_apply_patch_tool = true;
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_and_local_env(&server).await?;
|
||||
let local_cwd = TempDir::new()?;
|
||||
let file_name = "apply_patch_remote_freeform.txt";
|
||||
let remote_cwd = PathBuf::from(format!(
|
||||
@@ -439,7 +439,7 @@ async fn apply_patch_approvals_are_remembered_per_environment() -> Result<()> {
|
||||
config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest);
|
||||
config.approvals_reviewer = ApprovalsReviewer::User;
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_and_local_env(&server).await?;
|
||||
let local_cwd = TempDir::new()?;
|
||||
let remote_cwd = PathBuf::from(format!(
|
||||
"/tmp/codex-remote-apply-patch-approval-cwd-{}",
|
||||
|
||||
@@ -480,7 +480,7 @@ async fn stdio_server_round_trip() -> anyhow::Result<()> {
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
fixture
|
||||
.codex
|
||||
@@ -603,7 +603,7 @@ async fn stdio_server_uses_configured_cwd_before_runtime_fallback() -> anyhow::R
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
let expected_cwd = expected_cwd
|
||||
@@ -656,7 +656,7 @@ async fn remote_stdio_server_uses_runtime_fallback_cwd_when_config_omits_cwd() -
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
let expected_cwd = expected_cwd
|
||||
@@ -775,7 +775,7 @@ async fn stdio_mcp_tool_call_includes_sandbox_state_meta() -> anyhow::Result<()>
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
wait_for_mcp_server(&fixture, server_name).await?;
|
||||
@@ -873,7 +873,7 @@ async fn stdio_mcp_parallel_tool_calls_default_false_runs_serially() -> anyhow::
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
fixture
|
||||
.codex
|
||||
@@ -990,7 +990,7 @@ async fn stdio_mcp_parallel_tool_calls_opt_in_runs_concurrently() -> anyhow::Res
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
fixture
|
||||
.codex
|
||||
@@ -1071,7 +1071,7 @@ async fn stdio_image_responses_round_trip() -> anyhow::Result<()> {
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
wait_for_mcp_server(&fixture, server_name).await?;
|
||||
|
||||
@@ -1203,7 +1203,7 @@ async fn stdio_image_responses_preserve_original_detail_metadata() -> anyhow::Re
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
wait_for_mcp_server(&fixture, server_name).await?;
|
||||
|
||||
@@ -1338,7 +1338,7 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
fixture
|
||||
@@ -1440,7 +1440,7 @@ async fn stdio_server_propagates_whitelisted_env_vars() -> anyhow::Result<()> {
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
fixture
|
||||
.codex
|
||||
@@ -1558,7 +1558,7 @@ async fn stdio_server_propagates_explicit_local_env_var_source() -> anyhow::Resu
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
fixture
|
||||
@@ -1650,7 +1650,7 @@ async fn remote_stdio_env_var_source_does_not_copy_local_env() -> anyhow::Result
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
|
||||
fixture
|
||||
@@ -1833,7 +1833,7 @@ async fn streamable_http_tool_call_round_trip() -> anyhow::Result<()> {
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
// Phase 4: submit the user turn that should trigger the MCP tool call.
|
||||
fixture
|
||||
@@ -2019,7 +2019,7 @@ async fn streamable_http_with_oauth_round_trip_impl() -> anyhow::Result<()> {
|
||||
},
|
||||
);
|
||||
})
|
||||
.build_remote_aware(&server)
|
||||
.build_with_remote_env(&server)
|
||||
.await?;
|
||||
// Phase 5: wait for MCP startup before the turn is submitted, which keeps
|
||||
// failures tied to server startup/discovery.
|
||||
|
||||
@@ -50,7 +50,7 @@ async fn user_turn_includes_skill_instructions() -> Result<()> {
|
||||
let mut builder = test_codex().with_workspace_setup(move |cwd, fs| async move {
|
||||
write_repo_skill(cwd, fs, "demo", "demo skill", skill_body).await
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let skill_path = test
|
||||
.config
|
||||
|
||||
@@ -379,7 +379,7 @@ async fn unified_exec_emits_exec_command_begin_event() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let cwd = test.config.cwd.to_path_buf();
|
||||
|
||||
let call_id = "uexec-begin-event";
|
||||
@@ -438,7 +438,7 @@ async fn unified_exec_resolves_relative_workdir() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let workdir_rel = std::path::PathBuf::from("uexec_relative_workdir");
|
||||
let workdir = create_workspace_directory(&test, &workdir_rel).await?;
|
||||
@@ -507,7 +507,7 @@ async fn unified_exec_respects_workdir_override() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let workdir = create_workspace_directory(&test, "uexec_workdir_test").await?;
|
||||
|
||||
@@ -572,7 +572,7 @@ async fn unified_exec_emits_exec_command_end_event() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-end-event";
|
||||
let args = json!({
|
||||
@@ -645,7 +645,7 @@ async fn unified_exec_emits_output_delta_for_exec_command() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-delta-1";
|
||||
let args = json!({
|
||||
@@ -703,7 +703,7 @@ async fn unified_exec_full_lifecycle_with_background_end_event() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-full-lifecycle";
|
||||
// This timing force the long-standing PTY
|
||||
@@ -910,7 +910,7 @@ allow_local_binding = true
|
||||
PermissionProfile::from_legacy_sandbox_policy(&sandbox_policy_for_config),
|
||||
);
|
||||
});
|
||||
let test = builder.build_remote_aware(server).await?;
|
||||
let test = builder.build_with_remote_env(server).await?;
|
||||
assert!(
|
||||
test.config.permissions.network.is_some(),
|
||||
"expected managed network proxy config to be present"
|
||||
@@ -991,7 +991,7 @@ async fn unified_exec_emits_terminal_interaction_for_write_stdin() -> Result<()>
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let open_call_id = "uexec-open";
|
||||
let open_args = json!({
|
||||
@@ -1074,7 +1074,7 @@ async fn unified_exec_terminal_interaction_captures_delayed_output() -> Result<(
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let open_call_id = "uexec-delayed-open";
|
||||
let open_args = json!({
|
||||
@@ -1253,7 +1253,7 @@ async fn unified_exec_emits_one_begin_and_one_end_event() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let open_call_id = "uexec-open-session";
|
||||
let open_args = json!({
|
||||
@@ -1367,7 +1367,7 @@ async fn exec_command_reports_chunk_and_exit_metadata() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-metadata";
|
||||
let args = serde_json::json!({
|
||||
@@ -1462,7 +1462,7 @@ async fn exec_command_clamps_model_requested_max_output_tokens_to_policy() -> Re
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-clamped-max-output";
|
||||
let args = serde_json::json!({
|
||||
@@ -1524,7 +1524,7 @@ async fn write_stdin_clamps_model_requested_max_output_tokens_to_policy() -> Res
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let start_call_id = "uexec-stdin-clamp-start";
|
||||
let start_args = serde_json::json!({
|
||||
@@ -1611,7 +1611,7 @@ async fn unified_exec_defaults_to_pipe() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-default-pipe";
|
||||
let args = serde_json::json!({
|
||||
@@ -1680,7 +1680,7 @@ async fn unified_exec_can_enable_tty() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-tty-enabled";
|
||||
let args = serde_json::json!({
|
||||
@@ -1746,7 +1746,7 @@ async fn unified_exec_respects_early_exit_notifications() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec-early-exit";
|
||||
let args = serde_json::json!({
|
||||
@@ -1829,7 +1829,7 @@ async fn write_stdin_returns_exit_metadata_and_clears_session() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let start_call_id = "uexec-cat-start";
|
||||
let send_call_id = "uexec-cat-send";
|
||||
@@ -1983,7 +1983,7 @@ async fn unified_exec_emits_end_event_when_session_dies_via_stdin() -> Result<()
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let start_call_id = "uexec-end-on-exit-start";
|
||||
let start_args = serde_json::json!({
|
||||
@@ -2266,7 +2266,7 @@ async fn unified_exec_reuses_session_via_stdin() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let first_call_id = "uexec-start";
|
||||
let first_args = serde_json::json!({
|
||||
@@ -2365,7 +2365,7 @@ async fn unified_exec_streams_after_lagged_output() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let script = r#"python3 - <<'PY'
|
||||
import sys
|
||||
@@ -2485,7 +2485,7 @@ async fn unified_exec_timeout_and_followup_poll() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let first_call_id = "uexec-timeout";
|
||||
let first_args = serde_json::json!({
|
||||
@@ -2574,7 +2574,7 @@ async fn unified_exec_formats_large_output_summary() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let script = r#"python3 - <<'PY'
|
||||
import sys
|
||||
@@ -3002,7 +3002,7 @@ async fn unified_exec_runs_on_all_platforms() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
let call_id = "uexec";
|
||||
let args = serde_json::json!({
|
||||
@@ -3066,7 +3066,7 @@ async fn unified_exec_prunes_exited_sessions_first() -> Result<()> {
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
|
||||
const MAX_SESSIONS_FOR_TEST: i32 = 64;
|
||||
const FILLER_SESSIONS: i32 = MAX_SESSIONS_FOR_TEST - 1;
|
||||
|
||||
@@ -174,7 +174,7 @@ async fn assert_user_turn_local_image_resizes_to(
|
||||
let server = start_mock_server().await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -266,7 +266,7 @@ async fn view_image_tool_attaches_local_image() -> anyhow::Result<()> {
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -562,7 +562,7 @@ async fn view_image_routes_to_selected_remote_environment() -> anyhow::Result<()
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_and_local_env(&server).await?;
|
||||
let local_cwd = TempDir::new()?;
|
||||
fs::write(local_cwd.path().join("remote.png"), b"not a remote image")?;
|
||||
let local_selection = TurnEnvironmentSelection {
|
||||
@@ -582,9 +582,7 @@ async fn view_image_routes_to_selected_remote_environment() -> anyhow::Result<()
|
||||
/*sandbox*/ None,
|
||||
)
|
||||
.await?;
|
||||
let png = BASE64_STANDARD.decode(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=",
|
||||
)?;
|
||||
let png = png_bytes(/*width*/ 1, /*height*/ 1, [0, 255, 0, 255])?;
|
||||
test.fs()
|
||||
.write_file(&image_path, png, /*sandbox*/ None)
|
||||
.await?;
|
||||
@@ -664,7 +662,7 @@ async fn view_image_tool_can_preserve_original_resolution_when_requested_on_gpt5
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex().with_model("gpt-5.3-codex");
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -755,7 +753,7 @@ async fn view_image_tool_errors_clearly_for_unsupported_detail_values() -> anyho
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex().with_model("gpt-5.3-codex");
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -833,7 +831,7 @@ async fn view_image_tool_treats_null_detail_as_omitted() -> anyhow::Result<()> {
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex().with_model("gpt-5.3-codex");
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -923,7 +921,7 @@ async fn view_image_tool_resizes_when_model_lacks_original_detail_support() -> a
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex().with_model("gpt-5.2");
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -1017,7 +1015,7 @@ async fn view_image_tool_does_not_force_original_resolution_with_capability_only
|
||||
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex().with_model("gpt-5.3-codex");
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -1108,7 +1106,7 @@ async fn view_image_tool_errors_when_path_is_directory() -> anyhow::Result<()> {
|
||||
let server = start_mock_server().await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -1178,7 +1176,7 @@ async fn view_image_tool_errors_for_non_image_files() -> anyhow::Result<()> {
|
||||
let server = start_mock_server().await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
@@ -1255,7 +1253,7 @@ async fn view_image_tool_errors_when_file_missing() -> anyhow::Result<()> {
|
||||
let server = start_mock_server().await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
config,
|
||||
@@ -1385,7 +1383,7 @@ async fn view_image_tool_returns_unsupported_message_for_text_only_model() -> an
|
||||
.with_config(|config| {
|
||||
config.model = Some(model_slug.to_string());
|
||||
});
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex { codex, .. } = &test;
|
||||
|
||||
let rel_path = "assets/example.png";
|
||||
@@ -1472,7 +1470,7 @@ async fn replaces_invalid_local_image_after_bad_request() -> anyhow::Result<()>
|
||||
let completion_mock = responses::mount_sse_once(&server, success_response).await;
|
||||
|
||||
let mut builder = test_codex();
|
||||
let test = builder.build_remote_aware(&server).await?;
|
||||
let test = builder.build_with_remote_env(&server).await?;
|
||||
let TestCodex {
|
||||
codex,
|
||||
session_configured,
|
||||
|
||||
@@ -135,6 +135,20 @@ impl EnvironmentManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a test-only manager that keeps the provider default while also
|
||||
/// allowing tests to select the local environment explicitly.
|
||||
pub async fn create_for_tests_with_local(
|
||||
exec_server_url: Option<String>,
|
||||
local_runtime_paths: ExecServerRuntimePaths,
|
||||
) -> Self {
|
||||
let mut snapshot = DefaultEnvironmentProvider::new(exec_server_url).snapshot_inner();
|
||||
snapshot.include_local = true;
|
||||
match Self::from_provider_snapshot(snapshot, local_runtime_paths) {
|
||||
Ok(manager) => manager,
|
||||
Err(err) => panic!("test provider with local should create valid environments: {err}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a manager from a provider-supplied startup snapshot.
|
||||
pub async fn from_provider<P>(
|
||||
provider: &P,
|
||||
|
||||
Reference in New Issue
Block a user