mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Remove obsolete ignored tests (#34558)
## What changed Remove ignored tests for cloud-task composer rendering, delegated approval forwarding, and unified-exec session pruning, along with their unused imports. GitOrigin-RevId: 66ae0d3b672f6471a52ba0479bbd8119e12182f1
This commit is contained in:
@@ -2144,14 +2144,7 @@ mod tests {
|
||||
use codex_cloud_tasks_client::TaskStatus;
|
||||
use codex_cloud_tasks_client::TaskSummary;
|
||||
use codex_cloud_tasks_mock_client::MockClient;
|
||||
use codex_tui::ComposerAction;
|
||||
use codex_tui::ComposerInput;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyModifiers;
|
||||
use pretty_assertions::assert_eq;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
|
||||
struct StubGitInfo {
|
||||
default_branch: Option<String>,
|
||||
@@ -2377,33 +2370,4 @@ mod tests {
|
||||
assert_eq!(url.0, "task_i_123456");
|
||||
assert!(parse_task_id(" ").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "very slow"]
|
||||
fn composer_input_renders_typed_characters() {
|
||||
let mut composer = ComposerInput::new();
|
||||
let key = KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE);
|
||||
match composer.input(key) {
|
||||
ComposerAction::Submitted(_) => panic!("unexpected submission"),
|
||||
ComposerAction::None => {}
|
||||
}
|
||||
|
||||
let area = Rect::new(0, 0, 20, 5);
|
||||
let mut buf = Buffer::empty(area);
|
||||
composer.render_ref(area, &mut buf);
|
||||
|
||||
let found = buf.content().iter().any(|cell| cell.symbol() == "a");
|
||||
assert!(found, "typed character was not rendered: {buf:?}");
|
||||
|
||||
composer.set_hint_items(vec![("⌃O", "env"), ("⌃C", "quit")]);
|
||||
composer.render_ref(area, &mut buf);
|
||||
let footer = buf
|
||||
.content()
|
||||
.iter()
|
||||
.skip((area.width as usize) * (area.height as usize - 1))
|
||||
.map(ratatui::buffer::Cell::symbol)
|
||||
.collect::<Vec<_>>()
|
||||
.join("");
|
||||
assert!(footer.contains("⌃O env"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
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 core_test_support::responses::ev_apply_patch_custom_tool_call;
|
||||
use core_test_support::responses::ev_assistant_message;
|
||||
use core_test_support::responses::ev_completed;
|
||||
use core_test_support::responses::ev_function_call;
|
||||
use core_test_support::responses::ev_reasoning_item_added;
|
||||
use core_test_support::responses::ev_reasoning_summary_text_delta;
|
||||
use core_test_support::responses::ev_response_created;
|
||||
@@ -22,180 +14,6 @@ use core_test_support::test_codex::test_codex;
|
||||
use core_test_support::wait_for_event;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
/// Delegate should surface ExecApprovalRequest from sub-agent and proceed
|
||||
/// after parent submits an approval decision.
|
||||
#[ignore = "TODO once we have a delegate that can ask for approvals"]
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn codex_delegate_forwards_exec_approval_and_proceeds_on_approval() {
|
||||
skip_if_no_network!();
|
||||
|
||||
// Sub-agent turn 1: emit a shell_command function_call requiring approval, then complete.
|
||||
let call_id = "call-exec-1";
|
||||
let args = serde_json::json!({
|
||||
"command": "rm -rf delegated",
|
||||
"timeout_ms": 1000,
|
||||
"sandbox_permissions": SandboxPermissions::RequireEscalated,
|
||||
})
|
||||
.to_string();
|
||||
let sse1 = sse(vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_function_call(call_id, "shell_command", &args),
|
||||
ev_completed("resp-1"),
|
||||
]);
|
||||
|
||||
// Sub-agent turn 2: return structured review output and complete.
|
||||
let review_json = serde_json::json!({
|
||||
"findings": [],
|
||||
"overall_correctness": "ok",
|
||||
"overall_explanation": "delegate approved exec",
|
||||
"overall_confidence_score": 0.5
|
||||
})
|
||||
.to_string();
|
||||
let sse2 = sse(vec![
|
||||
ev_response_created("resp-2"),
|
||||
ev_assistant_message("msg-1", &review_json),
|
||||
ev_completed("resp-2"),
|
||||
]);
|
||||
|
||||
let server = start_mock_server().await;
|
||||
mount_sse_sequence(&server, vec![sse1, sse2]).await;
|
||||
|
||||
// Build a conversation configured to require approvals so the delegate
|
||||
// routes ExecApprovalRequest via the parent.
|
||||
let mut builder = test_codex().with_model("gpt-5.4").with_config(|config| {
|
||||
config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest);
|
||||
config
|
||||
.permissions
|
||||
.set_permission_profile(PermissionProfile::read_only())
|
||||
.expect("set permission profile");
|
||||
});
|
||||
let test = builder.build(&server).await.expect("build test codex");
|
||||
|
||||
// Kick off review (sub-agent starts internally).
|
||||
test.codex
|
||||
.submit(Op::Review {
|
||||
review_request: ReviewRequest {
|
||||
target: ReviewTarget::Custom {
|
||||
instructions: "Please review".to_string(),
|
||||
},
|
||||
user_facing_hint: None,
|
||||
},
|
||||
})
|
||||
.await
|
||||
.expect("submit review");
|
||||
|
||||
// Lifecycle: Entered -> ExecApprovalRequest -> Exited(Some) -> TurnComplete.
|
||||
wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::EnteredReviewMode(_))
|
||||
})
|
||||
.await;
|
||||
|
||||
// Expect parent-side approval request (forwarded by delegate).
|
||||
let approval_event = wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::ExecApprovalRequest(_))
|
||||
})
|
||||
.await;
|
||||
let EventMsg::ExecApprovalRequest(approval) = approval_event else {
|
||||
panic!("expected ExecApprovalRequest event");
|
||||
};
|
||||
|
||||
// Approve via parent using the emitted approval call ID.
|
||||
test.codex
|
||||
.submit(Op::ExecApproval {
|
||||
id: approval.effective_approval_id(),
|
||||
turn_id: None,
|
||||
decision: ReviewDecision::Approved,
|
||||
})
|
||||
.await
|
||||
.expect("submit exec approval");
|
||||
|
||||
wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::ExitedReviewMode(_))
|
||||
})
|
||||
.await;
|
||||
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
|
||||
}
|
||||
|
||||
/// Delegate should surface ApplyPatchApprovalRequest and honor parent decision
|
||||
/// so the sub-agent can proceed to completion.
|
||||
#[ignore = "TODO once we have a delegate that can ask for approvals"]
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn codex_delegate_forwards_patch_approval_and_proceeds_on_decision() {
|
||||
skip_if_no_network!();
|
||||
|
||||
let call_id = "call-patch-1";
|
||||
let patch = "*** Begin Patch\n*** Add File: delegated.txt\n+hello\n*** End Patch\n";
|
||||
let sse1 = sse(vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_apply_patch_custom_tool_call(call_id, patch),
|
||||
ev_completed("resp-1"),
|
||||
]);
|
||||
let review_json = serde_json::json!({
|
||||
"findings": [],
|
||||
"overall_correctness": "ok",
|
||||
"overall_explanation": "delegate patch handled",
|
||||
"overall_confidence_score": 0.5
|
||||
})
|
||||
.to_string();
|
||||
let sse2 = sse(vec![
|
||||
ev_response_created("resp-2"),
|
||||
ev_assistant_message("msg-1", &review_json),
|
||||
ev_completed("resp-2"),
|
||||
]);
|
||||
|
||||
let server = start_mock_server().await;
|
||||
mount_sse_sequence(&server, vec![sse1, sse2]).await;
|
||||
|
||||
let mut builder = test_codex().with_model("gpt-5.4").with_config(|config| {
|
||||
config.permissions.approval_policy = Constrained::allow_any(AskForApproval::OnRequest);
|
||||
// Use a restricted sandbox so patch approval is required
|
||||
config
|
||||
.permissions
|
||||
.set_permission_profile(PermissionProfile::read_only())
|
||||
.expect("set permission profile");
|
||||
});
|
||||
let test = builder.build(&server).await.expect("build test codex");
|
||||
|
||||
test.codex
|
||||
.submit(Op::Review {
|
||||
review_request: ReviewRequest {
|
||||
target: ReviewTarget::Custom {
|
||||
instructions: "Please review".to_string(),
|
||||
},
|
||||
user_facing_hint: None,
|
||||
},
|
||||
})
|
||||
.await
|
||||
.expect("submit review");
|
||||
|
||||
wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::EnteredReviewMode(_))
|
||||
})
|
||||
.await;
|
||||
let approval_event = wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::ApplyPatchApprovalRequest(_))
|
||||
})
|
||||
.await;
|
||||
let EventMsg::ApplyPatchApprovalRequest(approval) = approval_event else {
|
||||
panic!("expected ApplyPatchApprovalRequest event");
|
||||
};
|
||||
|
||||
// Deny via parent so delegate can continue, using the emitted approval call ID.
|
||||
test.codex
|
||||
.submit(Op::PatchApproval {
|
||||
id: approval.call_id,
|
||||
decision: ReviewDecision::denied("rejected by user"),
|
||||
})
|
||||
.await
|
||||
.expect("submit patch approval");
|
||||
|
||||
wait_for_event(&test.codex, |ev| {
|
||||
matches!(ev, EventMsg::ExitedReviewMode(_))
|
||||
})
|
||||
.await;
|
||||
wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn codex_delegate_ignores_legacy_deltas() {
|
||||
skip_if_no_network!();
|
||||
|
||||
@@ -3484,154 +3484,6 @@ async fn write_stdin_calls_run_in_parallel_across_sessions() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
#[ignore]
|
||||
async fn unified_exec_prunes_exited_sessions_first() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
skip_if_sandbox!(Ok(()));
|
||||
skip_if_host_windows!(Ok(()));
|
||||
|
||||
let server = start_mock_server().await;
|
||||
|
||||
let mut builder = test_codex().with_config(|config| {
|
||||
config.use_experimental_unified_exec_tool = true;
|
||||
config
|
||||
.features
|
||||
.enable(Feature::UnifiedExec)
|
||||
.expect("test config should allow feature update");
|
||||
});
|
||||
let test = builder.build_with_auto_env(&server).await?;
|
||||
|
||||
const MAX_SESSIONS_FOR_TEST: i32 = 64;
|
||||
const FILLER_SESSIONS: i32 = MAX_SESSIONS_FOR_TEST - 1;
|
||||
|
||||
let keep_call_id = "uexec-prune-keep";
|
||||
let keep_args = serde_json::json!({
|
||||
"cmd": "/bin/cat",
|
||||
"yield_time_ms": 250,
|
||||
"tty": true,
|
||||
});
|
||||
|
||||
let prune_call_id = "uexec-prune-target";
|
||||
// Give the sleeper time to exit before the filler sessions trigger pruning.
|
||||
let prune_args = serde_json::json!({
|
||||
"cmd": "sleep 1",
|
||||
"yield_time_ms": 1_250,
|
||||
"tty": true,
|
||||
});
|
||||
|
||||
let mut events = vec![ev_response_created("resp-prune-1")];
|
||||
events.push(ev_function_call(
|
||||
keep_call_id,
|
||||
"exec_command",
|
||||
&serde_json::to_string(&keep_args)?,
|
||||
));
|
||||
events.push(ev_function_call(
|
||||
prune_call_id,
|
||||
"exec_command",
|
||||
&serde_json::to_string(&prune_args)?,
|
||||
));
|
||||
|
||||
for idx in 0..FILLER_SESSIONS {
|
||||
let filler_args = serde_json::json!({
|
||||
"cmd": format!("echo filler {idx}"),
|
||||
"yield_time_ms": 250,
|
||||
});
|
||||
let call_id = format!("uexec-prune-fill-{idx}");
|
||||
events.push(ev_function_call(
|
||||
&call_id,
|
||||
"exec_command",
|
||||
&serde_json::to_string(&filler_args)?,
|
||||
));
|
||||
}
|
||||
|
||||
let keep_write_call_id = "uexec-prune-keep-write";
|
||||
let keep_write_args = serde_json::json!({
|
||||
"chars": "still alive\n",
|
||||
"session_id": 1000,
|
||||
"yield_time_ms": 500,
|
||||
});
|
||||
events.push(ev_function_call(
|
||||
keep_write_call_id,
|
||||
"write_stdin",
|
||||
&serde_json::to_string(&keep_write_args)?,
|
||||
));
|
||||
|
||||
let probe_call_id = "uexec-prune-probe";
|
||||
let probe_args = serde_json::json!({
|
||||
"chars": "should fail\n",
|
||||
"session_id": 1001,
|
||||
"yield_time_ms": 500,
|
||||
});
|
||||
events.push(ev_function_call(
|
||||
probe_call_id,
|
||||
"write_stdin",
|
||||
&serde_json::to_string(&probe_args)?,
|
||||
));
|
||||
|
||||
events.push(ev_completed("resp-prune-1"));
|
||||
let first_response = sse(events);
|
||||
let completion_response = sse(vec![
|
||||
ev_response_created("resp-prune-2"),
|
||||
ev_assistant_message("msg-prune", "done"),
|
||||
ev_completed("resp-prune-2"),
|
||||
]);
|
||||
let response_mock =
|
||||
mount_sse_sequence(&server, vec![first_response, completion_response]).await;
|
||||
|
||||
submit_unified_exec_turn(&test, "fill session cache", PermissionProfile::Disabled).await?;
|
||||
|
||||
wait_for_event(&test.codex, |event| {
|
||||
matches!(event, EventMsg::TurnComplete(_))
|
||||
})
|
||||
.await;
|
||||
|
||||
let requests = response_mock.requests();
|
||||
assert!(
|
||||
!requests.is_empty(),
|
||||
"expected at least one response request"
|
||||
);
|
||||
|
||||
let keep_start = requests
|
||||
.iter()
|
||||
.find_map(|req| req.function_call_output_text(keep_call_id))
|
||||
.expect("missing initial keep session output");
|
||||
let keep_start_output = parse_unified_exec_output(&keep_start)?;
|
||||
assert!(keep_start_output.process_id.is_some());
|
||||
assert!(keep_start_output.exit_code.is_none());
|
||||
|
||||
let prune_start = requests
|
||||
.iter()
|
||||
.find_map(|req| req.function_call_output_text(prune_call_id))
|
||||
.expect("missing initial prune process output");
|
||||
let prune_start_output = parse_unified_exec_output(&prune_start)?;
|
||||
assert!(prune_start_output.process_id.is_some());
|
||||
assert!(prune_start_output.exit_code.is_none());
|
||||
|
||||
let keep_write = requests
|
||||
.iter()
|
||||
.find_map(|req| req.function_call_output_text(keep_write_call_id))
|
||||
.expect("missing keep write output");
|
||||
let keep_write_output = parse_unified_exec_output(&keep_write)?;
|
||||
assert!(keep_write_output.process_id.is_some());
|
||||
assert!(
|
||||
keep_write_output.output.contains("still alive"),
|
||||
"expected cat process to echo input, got {:?}",
|
||||
keep_write_output.output
|
||||
);
|
||||
|
||||
let pruned_probe = requests
|
||||
.iter()
|
||||
.find_map(|req| req.function_call_output_text(probe_call_id))
|
||||
.expect("missing probe output");
|
||||
assert!(
|
||||
pruned_probe.contains("UnknownProcessId") || pruned_probe.contains("Unknown process id"),
|
||||
"expected probe to fail after pruning, got {pruned_probe:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn assert_command(command: &[String], expected_args: &str, expected_cmd: &str) {
|
||||
assert_eq!(command.len(), 3);
|
||||
let shell_path = &command[0];
|
||||
|
||||
Reference in New Issue
Block a user