From dc8896930ff35fdf13b7b4c5659cfe08921e2ce7 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Tue, 28 Apr 2026 17:06:06 -0700 Subject: [PATCH] core tests: configure profiles directly --- codex-rs/core/tests/suite/code_mode.rs | 13 ++++-- codex-rs/core/tests/suite/codex_delegate.rs | 12 +++--- .../core/tests/suite/model_visible_layout.rs | 40 +++++++++++++------ codex-rs/core/tests/suite/otel.rs | 7 ++-- codex-rs/core/tests/suite/tools.rs | 38 +++++++++--------- codex-rs/core/tests/suite/user_shell_cmd.rs | 16 +++++--- 6 files changed, 78 insertions(+), 48 deletions(-) diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index 413fd90bbb7..af94252c02a 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -11,10 +11,10 @@ use codex_models_manager::bundled_models_response; use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem; use codex_protocol::dynamic_tools::DynamicToolResponse; use codex_protocol::dynamic_tools::DynamicToolSpec; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::apps_test_server::AppsTestServer; use core_test_support::assert_regex_match; @@ -30,6 +30,7 @@ use core_test_support::skip_if_no_network; use core_test_support::stdio_server_bin; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use core_test_support::wait_for_event_match; use pretty_assertions::assert_eq; @@ -2607,6 +2608,10 @@ text( ) .await; + let cwd = test.cwd.path().to_path_buf(); + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); + test.codex .submit(Op::UserTurn { environments: None, @@ -2615,11 +2620,11 @@ text( text_elements: Vec::new(), }], final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), + cwd, approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: test.session_configured.model.clone(), effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/codex_delegate.rs b/codex-rs/core/tests/suite/codex_delegate.rs index 461b07284ce..2ccb6fecba4 100644 --- a/codex-rs/core/tests/suite/codex_delegate.rs +++ b/codex-rs/core/tests/suite/codex_delegate.rs @@ -1,12 +1,12 @@ use codex_core::config::Constrained; use codex_core::sandboxing::SandboxPermissions; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; use codex_protocol::protocol::ReviewDecision; use codex_protocol::protocol::ReviewRequest; use codex_protocol::protocol::ReviewTarget; -use codex_protocol::protocol::SandboxPolicy; use core_test_support::responses::ev_apply_patch_function_call; use core_test_support::responses::ev_assistant_message; use core_test_support::responses::ev_completed; @@ -65,8 +65,9 @@ async fn codex_delegate_forwards_exec_approval_and_proceeds_on_approval() { let mut builder = test_codex().with_model("gpt-5.4").with_config(|config| { config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest); config - .set_legacy_sandbox_policy(SandboxPolicy::new_read_only_policy()) - .expect("set sandbox policy"); + .permissions + .set_permission_profile(PermissionProfile::read_only()) + .expect("set permission profile"); }); let test = builder.build(&server).await.expect("build test codex"); @@ -149,8 +150,9 @@ async fn codex_delegate_forwards_patch_approval_and_proceeds_on_decision() { config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest); // Use a restricted sandbox so patch approval is required config - .set_legacy_sandbox_policy(SandboxPolicy::new_read_only_policy()) - .expect("set sandbox policy"); + .permissions + .set_permission_profile(PermissionProfile::read_only()) + .expect("set permission profile"); config.include_apply_patch_tool = true; }); let test = builder.build(&server).await.expect("build test codex"); diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 2f06d5af21f..7ae148788ef 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -6,10 +6,10 @@ use std::sync::Arc; use anyhow::Result; use codex_config::types::Personality; use codex_features::Feature; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::context_snapshot; use core_test_support::context_snapshot::ContextSnapshotOptions; @@ -24,6 +24,7 @@ use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; use core_test_support::skip_if_no_network; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use serde_json::json; @@ -111,6 +112,9 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { let test = builder.build(&server).await?; let preturn_context_diff_cwd = test.cwd_path().join(PRETURN_CONTEXT_DIFF_CWD); fs::create_dir_all(&preturn_context_diff_cwd)?; + let first_turn_cwd = test.cwd_path().to_path_buf(); + let (first_sandbox_policy, first_permission_profile) = + turn_permission_fields(PermissionProfile::read_only(), first_turn_cwd.as_path()); test.codex .submit(Op::UserTurn { @@ -120,11 +124,11 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { text_elements: Vec::new(), }], final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), + cwd: first_turn_cwd, approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy: first_sandbox_policy, + permission_profile: first_permission_profile, model: test.session_configured.model.clone(), effort: test.config.model_reasoning_effort, summary: None, @@ -138,6 +142,10 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { }) .await; + let (second_sandbox_policy, second_permission_profile) = turn_permission_fields( + PermissionProfile::read_only(), + preturn_context_diff_cwd.as_path(), + ); test.codex .submit(Op::UserTurn { environments: None, @@ -149,8 +157,8 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { cwd: preturn_context_diff_cwd, approval_policy: AskForApproval::OnRequest, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy: second_sandbox_policy, + permission_profile: second_permission_profile, model: test.session_configured.model.clone(), effort: test.config.model_reasoning_effort, summary: None, @@ -218,6 +226,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R cwd_two.join("AGENTS.md"), "# AGENTS two\n\n\nTurn two agents instructions.\n\n", )?; + let (first_sandbox_policy, first_permission_profile) = + turn_permission_fields(PermissionProfile::read_only(), cwd_one.as_path()); test.codex .submit(Op::UserTurn { @@ -230,8 +240,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R cwd: cwd_one.clone(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy: first_sandbox_policy, + permission_profile: first_permission_profile, model: test.session_configured.model.clone(), effort: test.config.model_reasoning_effort, summary: None, @@ -245,6 +255,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R }) .await; + let (second_sandbox_policy, second_permission_profile) = + turn_permission_fields(PermissionProfile::read_only(), cwd_two.as_path()); test.codex .submit(Op::UserTurn { environments: None, @@ -256,8 +268,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R cwd: cwd_two, approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy: second_sandbox_policy, + permission_profile: second_permission_profile, model: test.session_configured.model.clone(), effort: test.config.model_reasoning_effort, summary: None, @@ -358,6 +370,10 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul let resumed = resume_builder.resume(&server, home, rollout_path).await?; let resume_override_cwd = resumed.cwd_path().join(PRETURN_CONTEXT_DIFF_CWD); fs::create_dir_all(&resume_override_cwd)?; + let (sandbox_policy, permission_profile) = turn_permission_fields( + PermissionProfile::read_only(), + resume_override_cwd.as_path(), + ); resumed .codex .submit(Op::UserTurn { @@ -370,8 +386,8 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul cwd: resume_override_cwd, approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, + sandbox_policy, + permission_profile, model: resumed.session_configured.model.clone(), effort: resumed.config.model_reasoning_effort, summary: None, diff --git a/codex-rs/core/tests/suite/otel.rs b/codex-rs/core/tests/suite/otel.rs index 8d0d4d79a76..deeffcd855d 100644 --- a/codex-rs/core/tests/suite/otel.rs +++ b/codex-rs/core/tests/suite/otel.rs @@ -1,10 +1,10 @@ use codex_core::config::Constrained; use codex_features::Feature; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; use codex_protocol::protocol::ReviewDecision; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses::ev_assistant_message; use core_test_support::responses::ev_completed; @@ -1196,8 +1196,9 @@ async fn handle_container_exec_autoapprove_from_config_records_tool_decision() { .with_config(|config| { config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest); config - .set_legacy_sandbox_policy(SandboxPolicy::DangerFullAccess) - .expect("set sandbox policy"); + .permissions + .set_permission_profile(PermissionProfile::Disabled) + .expect("set permission profile"); }) .build(&server) .await diff --git a/codex-rs/core/tests/suite/tools.rs b/codex-rs/core/tests/suite/tools.rs index aff8755b110..46195e4dd0f 100644 --- a/codex-rs/core/tests/suite/tools.rs +++ b/codex-rs/core/tests/suite/tools.rs @@ -190,10 +190,10 @@ async fn custom_tool_unknown_returns_custom_output_error() -> Result<()> { ) .await; - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "invoke custom tool", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; @@ -408,10 +408,10 @@ async fn shell_escalated_permissions_rejected_then_ok() -> Result<()> { ) .await; - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "run the shell command", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; @@ -488,9 +488,9 @@ async fn sandbox_denied_shell_returns_original_output() -> Result<()> { let mock = mount_sse_sequence(&server, responses).await; fixture - .submit_turn_with_policy( + .submit_turn_with_permission_profile( "run a command that should be denied by the read-only sandbox", - SandboxPolicy::new_read_only_policy(), + PermissionProfile::read_only(), ) .await?; @@ -675,10 +675,10 @@ async fn collect_tools(use_unified_exec: bool) -> Result> { }); let test = builder.build(&server).await?; - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "list tools", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; @@ -746,10 +746,10 @@ async fn shell_timeout_includes_timeout_prefix_and_metadata() -> Result<()> { ) .await; - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "run a long command", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; @@ -791,8 +791,9 @@ async fn shell_timeout_handles_background_grandchild_stdout() -> Result<()> { let server = start_mock_server().await; let mut builder = test_codex().with_model("gpt-5.4").with_config(|config| { config - .set_legacy_sandbox_policy(SandboxPolicy::DangerFullAccess) - .expect("set sandbox policy"); + .permissions + .set_permission_profile(PermissionProfile::Disabled) + .expect("set permission profile"); }); let test = builder.build(&server).await?; @@ -837,10 +838,10 @@ time.sleep(60) let start = Instant::now(); let output_str = tokio::time::timeout(Duration::from_secs(10), async { - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "run a command with a detached grandchild", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; let timeout_item = second_mock.single_request().function_call_output(call_id); @@ -885,8 +886,9 @@ async fn shell_spawn_failure_truncates_exec_error() -> Result<()> { let server = start_mock_server().await; let mut builder = test_codex().with_config(|cfg| { - cfg.set_legacy_sandbox_policy(SandboxPolicy::DangerFullAccess) - .expect("set sandbox policy"); + cfg.permissions + .set_permission_profile(PermissionProfile::Disabled) + .expect("set permission profile"); }); let test = builder.build(&server).await?; @@ -922,10 +924,10 @@ async fn shell_spawn_failure_truncates_exec_error() -> Result<()> { ) .await; - test.submit_turn_with_policies( + test.submit_turn_with_approval_and_permission_profile( "spawn a missing binary", AskForApproval::Never, - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?; diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index 55263566932..1285b9f9251 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -8,7 +8,6 @@ use codex_protocol::protocol::ExecCommandEndEvent; use codex_protocol::protocol::ExecCommandSource; use codex_protocol::protocol::ExecOutputStream; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::TurnAbortReason; use codex_protocol::user_input::UserInput; use core_test_support::PathBufExt; @@ -23,6 +22,7 @@ use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; use core_test_support::skip_if_no_network; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use core_test_support::wait_for_event_match; use core_test_support::wait_for_event_with_timeout; @@ -168,6 +168,10 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> ]); let mock = responses::mount_sse_sequence(&server, vec![first, second]).await; + let cwd = fixture.cwd.path().to_path_buf(); + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); + fixture .codex .submit(Op::UserTurn { @@ -177,11 +181,11 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> text_elements: Vec::new(), }], final_output_json_schema: None, - cwd: fixture.cwd.path().to_path_buf(), + cwd, approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: fixture.session_configured.model.clone(), effort: None, summary: None, @@ -484,9 +488,9 @@ async fn user_shell_command_is_truncated_only_once() -> anyhow::Result<()> { .await; fixture - .submit_turn_with_policy( + .submit_turn_with_permission_profile( "trigger big shell_command output", - SandboxPolicy::DangerFullAccess, + PermissionProfile::Disabled, ) .await?;