mirror of
https://github.com/openai/codex.git
synced 2026-05-27 06:25:48 +00:00
## 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.
142 lines
4.9 KiB
Rust
142 lines
4.9 KiB
Rust
use anyhow::Result;
|
|
use codex_exec_server::CreateDirectoryOptions;
|
|
use core_test_support::responses::ev_completed;
|
|
use core_test_support::responses::ev_response_created;
|
|
use core_test_support::responses::mount_sse_once;
|
|
use core_test_support::responses::sse;
|
|
use core_test_support::responses::start_mock_server;
|
|
use core_test_support::test_codex::TestCodexBuilder;
|
|
use core_test_support::test_codex::test_codex;
|
|
|
|
async fn agents_instructions(mut builder: TestCodexBuilder) -> Result<String> {
|
|
let server = start_mock_server().await;
|
|
let resp_mock = mount_sse_once(
|
|
&server,
|
|
sse(vec![ev_response_created("resp1"), ev_completed("resp1")]),
|
|
)
|
|
.await;
|
|
|
|
let test = builder.build_with_remote_env(&server).await?;
|
|
test.submit_turn("hello").await?;
|
|
|
|
let request = resp_mock.single_request();
|
|
request
|
|
.message_input_texts("user")
|
|
.into_iter()
|
|
.find(|text| text.starts_with("# AGENTS.md instructions for "))
|
|
.ok_or_else(|| anyhow::anyhow!("instructions message not found"))
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn agents_override_is_preferred_over_agents_md() -> Result<()> {
|
|
let instructions =
|
|
agents_instructions(test_codex().with_workspace_setup(|cwd, fs| async move {
|
|
let agents_md = cwd.join("AGENTS.md");
|
|
let override_md = cwd.join("AGENTS.override.md");
|
|
fs.write_file(&agents_md, b"base doc".to_vec(), /*sandbox*/ None)
|
|
.await?;
|
|
fs.write_file(
|
|
&override_md,
|
|
b"override doc".to_vec(),
|
|
/*sandbox*/ None,
|
|
)
|
|
.await?;
|
|
Ok::<(), anyhow::Error>(())
|
|
}))
|
|
.await?;
|
|
|
|
assert!(
|
|
instructions.contains("override doc"),
|
|
"expected AGENTS.override.md contents: {instructions}"
|
|
);
|
|
assert!(
|
|
!instructions.contains("base doc"),
|
|
"expected AGENTS.md to be ignored when override exists: {instructions}"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn configured_fallback_is_used_when_agents_candidate_is_directory() -> Result<()> {
|
|
let instructions = agents_instructions(
|
|
test_codex()
|
|
.with_config(|config| {
|
|
config.project_doc_fallback_filenames = vec!["WORKFLOW.md".to_string()];
|
|
})
|
|
.with_workspace_setup(|cwd, fs| async move {
|
|
let agents_dir = cwd.join("AGENTS.md");
|
|
let fallback = cwd.join("WORKFLOW.md");
|
|
fs.create_directory(
|
|
&agents_dir,
|
|
CreateDirectoryOptions { recursive: true },
|
|
/*sandbox*/ None,
|
|
)
|
|
.await?;
|
|
fs.write_file(&fallback, b"fallback doc".to_vec(), /*sandbox*/ None)
|
|
.await?;
|
|
Ok::<(), anyhow::Error>(())
|
|
}),
|
|
)
|
|
.await?;
|
|
|
|
assert!(
|
|
instructions.contains("fallback doc"),
|
|
"expected fallback doc contents: {instructions}"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn agents_docs_are_concatenated_from_project_root_to_cwd() -> Result<()> {
|
|
let instructions = agents_instructions(
|
|
test_codex()
|
|
.with_config(|config| {
|
|
config.cwd = config.cwd.join("nested/workspace");
|
|
})
|
|
.with_workspace_setup(|cwd, fs| async move {
|
|
let nested = cwd.clone();
|
|
let root = nested
|
|
.parent()
|
|
.and_then(|parent| parent.parent())
|
|
.expect("nested workspace should have a project root ancestor");
|
|
let root_agents = root.join("AGENTS.md");
|
|
let git_marker = root.join(".git");
|
|
let nested_agents = nested.join("AGENTS.md");
|
|
|
|
fs.create_directory(
|
|
&nested,
|
|
CreateDirectoryOptions { recursive: true },
|
|
/*sandbox*/ None,
|
|
)
|
|
.await?;
|
|
fs.write_file(&root_agents, b"root doc".to_vec(), /*sandbox*/ None)
|
|
.await?;
|
|
fs.write_file(
|
|
&git_marker,
|
|
b"gitdir: /tmp/mock-git-dir\n".to_vec(),
|
|
/*sandbox*/ None,
|
|
)
|
|
.await?;
|
|
fs.write_file(&nested_agents, b"child doc".to_vec(), /*sandbox*/ None)
|
|
.await?;
|
|
Ok::<(), anyhow::Error>(())
|
|
}),
|
|
)
|
|
.await?;
|
|
|
|
let root_pos = instructions
|
|
.find("root doc")
|
|
.expect("expected root doc in AGENTS instructions");
|
|
let child_pos = instructions
|
|
.find("child doc")
|
|
.expect("expected child doc in AGENTS instructions");
|
|
assert!(
|
|
root_pos < child_pos,
|
|
"expected root doc before child doc: {instructions}"
|
|
);
|
|
|
|
Ok(())
|
|
}
|