From 6e1d252944581862bb127c2fde154446b9ea45df Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Wed, 24 Jun 2026 16:19:45 +0000 Subject: [PATCH] test: enable bwrap-exec integration suites --- .codex/skills/remote-tests/SKILL.md | 28 +++++++++++++++++-- codex-rs/app-server/BUILD.bazel | 1 + .../app-server/tests/suite/v2/command_exec.rs | 6 ++++ codex-rs/core/BUILD.bazel | 1 + codex-rs/core/README.md | 7 +++++ codex-rs/core/tests/suite/apply_patch_cli.rs | 3 ++ .../core/tests/suite/extension_sandbox.rs | 3 ++ codex-rs/core/tests/suite/network_approval.rs | 6 ++++ codex-rs/core/tests/suite/openai_file_mcp.rs | 6 ++++ codex-rs/core/tests/suite/remote_env.rs | 24 ++++++++++++++++ codex-rs/core/tests/suite/rmcp_client.rs | 25 +++++++++++++++++ codex-rs/core/tests/suite/skills.rs | 3 ++ codex-rs/core/tests/suite/tools.rs | 3 ++ codex-rs/core/tests/suite/unified_exec.rs | 8 ++++++ codex-rs/core/tests/suite/view_image.rs | 3 ++ 15 files changed, 124 insertions(+), 3 deletions(-) diff --git a/.codex/skills/remote-tests/SKILL.md b/.codex/skills/remote-tests/SKILL.md index 9a5fcdff34..2cee0a0d71 100644 --- a/.codex/skills/remote-tests/SKILL.md +++ b/.codex/skills/remote-tests/SKILL.md @@ -6,10 +6,11 @@ description: Testing against remote executors in integration tests. Remote executor tests exercise the app-server/exec-server split to ensure that agent features work in both local and remote execution environments. -Remote executor tests currently require an x86_64 Linux host machine. There are two flavors: +Remote executor tests currently require an x86_64 Linux host machine. There are three flavors: -1. Docker (Linux exec-server) -2. Wine (Windows exec-server) +1. Docker (Linux exec-server nested inside a separate container) +2. bwrap-exec (Linux exec-server nested inside bubblewrap) +3. Wine (Windows exec-server) ## Test Fixtures @@ -39,6 +40,7 @@ Choose the skip macro by what causes the test to fail: - `skip_if_target_windows!`: Windows target behavior. - `skip_if_wine_exec!`: Wine-exec runner constraints. +- `skip_if_bwrap_exec!`: bwrap-exec runner constraints. - `skip_if_host_windows!`: Windows host constraints. - `skip_if_remote!`: Local-only test behavior. - `skip_if_no_remote_env!`: Remote-only test behavior. @@ -96,6 +98,26 @@ For app-server integration tests: bazel test //codex-rs/app-server:app-server-all-wine-exec-test ``` +## bwrap-exec + +These tests build a Linux exec-server and run it inside an outer bubblewrap namespace. Running them +requires one of the RBE configurations documented in `codex-rs/docs/bazel.md`. + +For core integration tests: + +```sh +bazel test //codex-rs/core:core-all-bwrap-exec-test +``` + +For app-server integration tests: + +```sh +bazel test //codex-rs/app-server:app-server-all-bwrap-exec-test +``` + +The production Linux sandbox runs inside the outer bubblewrap namespace. Namespace or procfs setup +failures are test failures, not reasons to weaken or skip the production sandbox. + ## Devboxes You can use a devbox to run these tests if you are running on a macOS machine. diff --git a/codex-rs/app-server/BUILD.bazel b/codex-rs/app-server/BUILD.bazel index e5ef8268e5..6678948dd1 100644 --- a/codex-rs/app-server/BUILD.bazel +++ b/codex-rs/app-server/BUILD.bazel @@ -12,6 +12,7 @@ codex_rust_crate( "//codex-rs/rmcp-client:test_stdio_server", ], integration_test_timeout = "long", + run_tests_with_bwrap_exec = True, run_tests_with_wine_exec = True, test_shard_counts = { # Note app-server-all-test has a large number of integration tests, so diff --git a/codex-rs/app-server/tests/suite/v2/command_exec.rs b/codex-rs/app-server/tests/suite/v2/command_exec.rs index edd704c9fb..0e9bf4ab73 100644 --- a/codex-rs/app-server/tests/suite/v2/command_exec.rs +++ b/codex-rs/app-server/tests/suite/v2/command_exec.rs @@ -19,6 +19,7 @@ use codex_app_server_protocol::RequestId; use codex_app_server_protocol::SandboxPolicy; use codex_exec_server::CODEX_EXEC_SERVER_URL_ENV_VAR; use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_READ_ONLY; +use core_test_support::skip_if_bwrap_exec; use pretty_assertions::assert_eq; use std::collections::HashMap; use std::path::Path; @@ -1045,6 +1046,11 @@ async fn command_exec_tty_supports_initial_size_and_resize() -> Result<()> { #[tokio::test] async fn command_exec_process_ids_are_connection_scoped_and_disconnect_terminates_process() -> Result<()> { + // TODO(anp): Package a target-native long-running fixture for bwrap-exec. + skip_if_bwrap_exec!( + Ok(()), + "relies on Python being installed in the remote environment" + ); let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await; let codex_home = TempDir::new()?; create_config_toml(codex_home.path(), &server.uri(), "never")?; diff --git a/codex-rs/core/BUILD.bazel b/codex-rs/core/BUILD.bazel index a3f0583b80..0c6fc57d62 100644 --- a/codex-rs/core/BUILD.bazel +++ b/codex-rs/core/BUILD.bazel @@ -23,6 +23,7 @@ codex_rust_crate( "//codex-rs/windows-sandbox-rs:codex-windows-sandbox-setup", ], integration_test_timeout = "long", + run_tests_with_bwrap_exec = True, run_tests_with_wine_exec = True, rustc_env = { # Keep manifest-root path lookups inside the Bazel execroot for code diff --git a/codex-rs/core/README.md b/codex-rs/core/README.md index 278c614dfd..336c5a48d3 100644 --- a/codex-rs/core/README.md +++ b/codex-rs/core/README.md @@ -2,6 +2,13 @@ This crate implements the business logic for Codex. It is designed to be used by the various Codex UIs written in Rust. +## Bwrap-exec integration tests + +On Linux RBE, run the shared suites against the bubblewrap-backed Linux exec server with +`bazel test --config=buildbuddy-openai-rbe +//codex-rs/core:core-all-bwrap-exec-test +//codex-rs/core:core-responses_headers-bwrap-exec-test`. + ## Wine-exec integration tests On x86-64 Linux, run the shared suite against the Windows exec server with diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index d8142723b4..80bd7ef9a7 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -46,6 +46,7 @@ use core_test_support::responses::ev_shell_command_call_with_args; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_no_remote_env; use core_test_support::skip_if_remote; @@ -1585,6 +1586,8 @@ async fn apply_patch_turn_diff_tracks_local_and_remote_environment_paths() -> Re Ok(()), "requires a cwd valid in local POSIX and remote Windows environments" ); + // TODO(anp): Cover multi-environment turn diffs in bwrap-exec with a dedicated fixture. + skip_if_bwrap_exec!(Ok(()), "uses a shared local and remote fixture path"); skip_if_no_network!(Ok(())); skip_if_no_remote_env!(Ok(())); diff --git a/codex-rs/core/tests/suite/extension_sandbox.rs b/codex-rs/core/tests/suite/extension_sandbox.rs index c8bef5de7c..4f851b082c 100644 --- a/codex-rs/core/tests/suite/extension_sandbox.rs +++ b/codex-rs/core/tests/suite/extension_sandbox.rs @@ -28,6 +28,7 @@ use codex_protocol::request_permissions::RequestPermissionsResponse; use codex_protocol::user_input::UserInput; use codex_utils_absolute_path::AbsolutePathBuf; use core_test_support::responses; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_sandbox; use core_test_support::test_codex::local_selections; @@ -62,6 +63,8 @@ fn image_generation_extensions( #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn extension_tool_receives_turn_environment_sandbox() -> Result<()> { skip_if_no_network!(Ok(())); + // TODO(anp): Make the local filesystem sandbox work in the bwrap-exec test configuration. + skip_if_bwrap_exec!(Ok(()), "exercises the local filesystem sandbox"); let server = responses::start_mock_server().await; let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); diff --git a/codex-rs/core/tests/suite/network_approval.rs b/codex-rs/core/tests/suite/network_approval.rs index 437155f325..9d11799814 100644 --- a/codex-rs/core/tests/suite/network_approval.rs +++ b/codex-rs/core/tests/suite/network_approval.rs @@ -32,6 +32,7 @@ use core_test_support::responses::mount_sse_once_match; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_host_windows; use core_test_support::skip_if_no_network; use core_test_support::skip_if_no_remote_env; @@ -234,6 +235,11 @@ async fn guardian_receives_exact_trigger_for_single_network_request() -> Result< #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn approved_network_host_for_one_environment_still_prompts_in_another() -> Result<()> { + // TODO(anp): Select the remote environment's advertised shell in this fixture. + skip_if_bwrap_exec!( + Ok(()), + "hard-codes /bin/sh for a bash-only remote environment" + ); skip_if_target_windows!(Ok(()), "uses the POSIX/Python network fixture"); skip_if_host_windows!(Ok(())); skip_if_no_network!(Ok(())); diff --git a/codex-rs/core/tests/suite/openai_file_mcp.rs b/codex-rs/core/tests/suite/openai_file_mcp.rs index 2390071ac9..554c1f4625 100644 --- a/codex-rs/core/tests/suite/openai_file_mcp.rs +++ b/codex-rs/core/tests/suite/openai_file_mcp.rs @@ -27,6 +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_bwrap_exec; use core_test_support::skip_if_wine_exec; use core_test_support::test_codex::TestCodex; use pretty_assertions::assert_eq; @@ -183,6 +184,11 @@ async fn run_extract_turn(test: &TestCodex, server: &MockServer) -> Result Result<()> { // TODO(anp): Remove after file-upload fixtures support target-native Windows paths. skip_if_wine_exec!(Ok(()), "uses a host-native file-upload path"); + // TODO(anp): Stream large workspace fixtures without exceeding the exec-server frame limit. + skip_if_bwrap_exec!( + Ok(()), + "the 13 MiB fixture exceeds the WebSocket frame limit" + ); let server = start_mock_server().await; let apps_server = AppsTestServer::mount(&server).await?; diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index 5f8c503496..9d7a3e6cf4 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -51,6 +51,7 @@ use core_test_support::responses::mount_sse_once; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_no_remote_env; use core_test_support::skip_if_target_windows; @@ -1100,6 +1101,11 @@ async fn exec_command_routing_output( #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn exec_command_routes_to_selected_remote_environment() -> Result<()> { skip_if_no_network!(Ok(())); + // TODO(anp): Select the remote environment's advertised shell in this fixture. + skip_if_bwrap_exec!( + Ok(()), + "hard-codes /bin/sh for a bash-only remote environment" + ); // TODO(anp): Remove after remote path fixtures use target-native paths. skip_if_target_windows!(Ok(()), "requires the Docker-backed POSIX executor"); skip_if_no_remote_env!(Ok(())); @@ -1175,6 +1181,11 @@ async fn exec_command_routes_to_selected_remote_environment() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn remote_request_permissions_grant_unblocks_later_remote_exec() -> Result<()> { skip_if_no_network!(Ok(())); + // TODO(anp): Select the remote environment's advertised shell in this fixture. + skip_if_bwrap_exec!( + Ok(()), + "hard-codes /bin/sh for a bash-only remote environment" + ); // TODO(anp): Remove after remote path fixtures use target-native paths. skip_if_target_windows!(Ok(()), "requires the Docker-backed POSIX executor"); skip_if_no_remote_env!(Ok(())); @@ -1468,6 +1479,8 @@ async fn apply_patch_approvals_are_remembered_per_environment() -> Result<()> { skip_if_no_network!(Ok(())); // TODO(anp): Remove after remote path fixtures use target-native paths. skip_if_target_windows!(Ok(()), "requires the Docker-backed POSIX executor"); + // TODO(anp): Add an isolated bwrap-exec fixture for per-environment approval paths. + skip_if_bwrap_exec!(Ok(()), "uses one absolute path in both environments"); skip_if_no_remote_env!(Ok(())); let server = start_mock_server().await; @@ -1655,6 +1668,11 @@ async fn apply_patch_approvals_are_remembered_per_environment() -> Result<()> { async fn apply_patch_intercepted_exec_command_routes_to_selected_remote_environment() -> Result<()> { skip_if_no_network!(Ok(())); + // TODO(anp): Select the remote environment's advertised shell in this fixture. + skip_if_bwrap_exec!( + Ok(()), + "hard-codes /bin/sh for a bash-only remote environment" + ); // TODO(anp): Remove after remote path fixtures use target-native paths. skip_if_target_windows!(Ok(()), "requires the Docker-backed POSIX executor"); skip_if_no_remote_env!(Ok(())); @@ -1798,6 +1816,8 @@ async fn remote_test_env_sandboxed_read_allows_readable_root() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn remote_test_env_sandboxed_read_rejects_symlink_parent_dotdot_escape() -> Result<()> { + // TODO(anp): Build symlink fixtures through exec-server instead of direct Docker access. + skip_if_bwrap_exec!(Ok(()), "fixture setup requires direct Docker access"); skip_if_target_windows!(Ok(()), "tests POSIX symlink and parent traversal semantics"); skip_if_no_network!(Ok(())); skip_if_no_remote_env!(Ok(())); @@ -1832,6 +1852,8 @@ async fn remote_test_env_sandboxed_read_rejects_symlink_parent_dotdot_escape() - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn remote_test_env_remove_removes_symlink_not_target() -> Result<()> { + // TODO(anp): Build symlink fixtures through exec-server instead of direct Docker access. + skip_if_bwrap_exec!(Ok(()), "fixture setup requires direct Docker access"); skip_if_target_windows!(Ok(()), "tests POSIX symlink removal semantics"); skip_if_no_network!(Ok(())); skip_if_no_remote_env!(Ok(())); @@ -1904,6 +1926,8 @@ async fn remote_test_env_remove_removes_symlink_not_target() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn remote_test_env_copy_preserves_symlink_source() -> Result<()> { + // TODO(anp): Build symlink fixtures through exec-server instead of direct Docker access. + skip_if_bwrap_exec!(Ok(()), "fixture setup requires direct Docker access"); skip_if_target_windows!(Ok(()), "tests POSIX symlink copy semantics"); skip_if_no_network!(Ok(())); skip_if_no_remote_env!(Ok(())); diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index cc16f3ead7..555e0f462b 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -56,6 +56,7 @@ use core_test_support::responses; use core_test_support::responses::mount_models_once; use core_test_support::responses::mount_sse_once; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_no_remote_env; use core_test_support::skip_if_wine_exec; @@ -538,6 +539,8 @@ fn assert_cwd_tool_output(structured: &Value, expected_cwd: &Path) { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_server_round_trip() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -870,6 +873,8 @@ async fn local_stdio_server_uses_runtime_fallback_cwd_when_config_omits_cwd() -> #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn stdio_mcp_tool_call_includes_sandbox_state_meta() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -959,6 +964,8 @@ async fn stdio_mcp_tool_call_includes_sandbox_state_meta() -> anyhow::Result<()> #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn stdio_mcp_parallel_tool_calls_default_false_runs_serially() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1079,6 +1086,8 @@ async fn stdio_mcp_parallel_tool_calls_default_false_runs_serially() -> anyhow:: #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn stdio_mcp_read_only_tool_calls_run_concurrently_without_server_opt_in() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1181,6 +1190,8 @@ async fn stdio_mcp_read_only_tool_calls_run_concurrently_without_server_opt_in() #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn stdio_mcp_parallel_tool_calls_opt_in_runs_concurrently() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1275,6 +1286,8 @@ async fn stdio_mcp_parallel_tool_calls_opt_in_runs_concurrently() -> anyhow::Res #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_image_responses_round_trip() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1423,6 +1436,8 @@ async fn stdio_image_responses_round_trip() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_image_responses_resize_large_image() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1525,6 +1540,8 @@ async fn stdio_image_responses_resize_large_image() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_image_responses_preserve_original_detail_metadata() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1616,6 +1633,8 @@ async fn stdio_image_responses_preserve_original_detail_metadata() -> anyhow::Re #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1778,6 +1797,8 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_test_value)] async fn stdio_server_propagates_whitelisted_env_vars() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1900,6 +1921,8 @@ async fn stdio_server_propagates_whitelisted_env_vars() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_env_source)] async fn stdio_server_propagates_explicit_local_env_var_source() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), @@ -1996,6 +2019,8 @@ async fn stdio_server_propagates_explicit_local_env_var_source() -> anyhow::Resu #[tokio::test(flavor = "multi_thread", worker_threads = 1)] #[serial(mcp_env_source)] async fn remote_stdio_env_var_source_does_not_copy_local_env() -> anyhow::Result<()> { + // TODO(anp): Make remote stdio MCP startup honor its fallback cwd under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "remote stdio MCP startup needs an explicit cwd"); // TODO(anp): Remove after packaging a Windows stdio test server for Wine exec. skip_if_wine_exec!( Ok(()), diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index a6a4716879..98b87e9049 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -16,6 +16,7 @@ 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::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_target_windows; use core_test_support::test_codex::local_selections; @@ -50,6 +51,8 @@ async fn write_repo_skill( async fn user_turn_includes_skill_instructions() -> Result<()> { // TODO(anp): Remove after skill-path helpers use target-native paths. skip_if_target_windows!(Ok(()), "requires native cross-OS skill paths"); + // TODO(anp): Make explicit local skill selection work in the bwrap-exec test configuration. + skip_if_bwrap_exec!(Ok(()), "selects the local skill environment explicitly"); skip_if_no_network!(Ok(())); let server = start_mock_server().await; diff --git a/codex-rs/core/tests/suite/tools.rs b/codex-rs/core/tests/suite/tools.rs index 5e47eae52e..824480a4d9 100644 --- a/codex-rs/core/tests/suite/tools.rs +++ b/codex-rs/core/tests/suite/tools.rs @@ -27,6 +27,7 @@ use core_test_support::responses::mount_sse_once; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_sandbox; use core_test_support::test_codex::local; @@ -438,6 +439,8 @@ async fn sandbox_denied_shell_command_returns_original_output() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn shell_command_enforces_glob_deny_read_policy() -> Result<()> { + // TODO(anp): Preserve the observable denial contract for masked reads under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "masked reads can currently exit successfully"); skip_if_no_network!(Ok(())); skip_if_sandbox!(Ok(())); diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index 42e0214fa1..5dd068260b 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -31,6 +31,7 @@ use core_test_support::responses::ev_response_created; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_host_windows; use core_test_support::skip_if_no_network; use core_test_support::skip_if_sandbox; @@ -2675,6 +2676,11 @@ async fn unified_exec_reuses_session_via_stdin() -> Result<()> { async fn unified_exec_streams_after_lagged_output() -> Result<()> { // TODO(anp): Remove after output fixtures use target-native commands. skip_if_target_windows!(Ok(()), "requires Python/Unix PTY support in the target"); + // TODO(anp): Make the original lagged-output timing fixture reliable under bwrap-exec. + skip_if_bwrap_exec!( + Ok(()), + "the timing-based fixture is unreliable through exec-server" + ); skip_if_no_network!(Ok(())); skip_if_sandbox!(Ok(())); @@ -3052,6 +3058,8 @@ async fn unified_exec_enforces_glob_deny_read_policy() -> Result<()> { use codex_protocol::permissions::FileSystemSandboxPolicy; use codex_protocol::permissions::NetworkSandboxPolicy; + // TODO(anp): Preserve the observable denial contract for masked reads under bwrap-exec. + skip_if_bwrap_exec!(Ok(()), "masked reads can currently exit successfully"); skip_if_no_network!(Ok(())); skip_if_sandbox!(Ok(())); diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index 38c2a7d771..0447f4aabe 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -40,6 +40,7 @@ use core_test_support::responses::mount_models_once; use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; +use core_test_support::skip_if_bwrap_exec; use core_test_support::skip_if_no_network; use core_test_support::skip_if_no_remote_env; use core_test_support::test_codex::TestCodex; @@ -494,6 +495,8 @@ async fn view_image_routes_to_selected_local_environment() -> anyhow::Result<()> #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn view_image_tool_applies_local_sandbox_read_denies() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); + // TODO(anp): Make the local filesystem sandbox work in the bwrap-exec test configuration. + skip_if_bwrap_exec!(Ok(()), "exercises the local filesystem sandbox"); let server = start_mock_server().await; let mut builder = test_codex();