From 37644cabe0d0f8c96f3ae7cc2a985f54d631adff Mon Sep 17 00:00:00 2001 From: akbash Date: Fri, 14 Aug 2026 00:18:35 +0300 Subject: fix: wait for new pane shell readiness (#2774) * fix: wait for new pane shell readiness refs #2773 * refactor: share agent startup bounds refs #2773 * fix: reconcile agent names after startup timeout refs #2773 * fix: cover agent cleanup scheduling skew refs #2773 * fix: bound pane shell readiness retries refs #2773 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: Ogulcan Celik --- tests/cli/agent_transport.rs | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) (limited to 'tests/cli/agent_transport.rs') diff --git a/tests/cli/agent_transport.rs b/tests/cli/agent_transport.rs index 85419e90..a052f697 100644 --- a/tests/cli/agent_transport.rs +++ b/tests/cli/agent_transport.rs @@ -8,6 +8,24 @@ fn agent_start_waits_through_unknown_then_rejects_blocked() { let listener = UnixListener::bind(&socket_path).unwrap(); let server = thread::spawn(move || { + let (mut pane_stream, pane_line) = accept_fake_cli_operation(&listener); + let pane: serde_json::Value = serde_json::from_str(&pane_line).unwrap(); + assert_eq!(pane["method"], "pane.get"); + assert_eq!(pane["params"]["pane_id"], "w1:p1"); + writeln!( + pane_stream, + "{}", + serde_json::json!({ + "id": pane["id"], + "result": { + "type": "pane_info", + "pane": { "terminal_id": "term_1" } + } + }) + ) + .unwrap(); + pane_stream.flush().unwrap(); + let (mut start_stream, start_line) = accept_fake_cli_operation(&listener); let start: serde_json::Value = serde_json::from_str(&start_line).unwrap(); assert_eq!(start["method"], "agent.start"); @@ -98,6 +116,106 @@ fn agent_start_waits_through_unknown_then_rejects_blocked() { cleanup_test_base(&base); } +#[test] +fn agent_start_does_not_retry_after_the_target_terminal_changes() { + let base = unique_test_dir(); + fs::create_dir_all(&base).unwrap(); + let socket_path = base.join("herdr.sock"); + let listener = UnixListener::bind(&socket_path).unwrap(); + + let server = thread::spawn(move || { + for _ in 0..2 { + let (mut stream, line) = accept_fake_cli_operation(&listener); + let request: serde_json::Value = serde_json::from_str(&line).unwrap(); + assert_eq!(request["method"], "pane.get"); + writeln!( + stream, + "{}", + serde_json::json!({ + "id": request["id"], + "result": { + "type": "pane_info", + "pane": { "terminal_id": "term_1" } + } + }) + ) + .unwrap(); + stream.flush().unwrap(); + + let (mut stream, line) = accept_fake_cli_operation(&listener); + let request: serde_json::Value = serde_json::from_str(&line).unwrap(); + if request["method"] == "agent.start" { + writeln!( + stream, + "{}", + serde_json::json!({ + "id": request["id"], + "error": { + "code": "agent_pane_busy", + "message": "agent target pane w1:p1 is not an available shell" + } + }) + ) + .unwrap(); + stream.flush().unwrap(); + } else { + assert_eq!(request["method"], "pane.process_info"); + writeln!( + stream, + "{}", + serde_json::json!({ + "id": request["id"], + "result": { + "type": "pane_process_info", + "process_info": { + "pane_id": "w1:p1", + "shell_pid": 10, + "foreground_process_group_id": 10, + "foreground_processes": [ + { "pid": 10, "name": "bash" }, + { "pid": 11, "name": "startup-helper" } + ] + } + } + }) + ) + .unwrap(); + stream.flush().unwrap(); + } + } + + let (mut stream, line) = accept_fake_cli_operation(&listener); + let request: serde_json::Value = serde_json::from_str(&line).unwrap(); + assert_eq!(request["method"], "pane.get"); + writeln!( + stream, + "{}", + serde_json::json!({ + "id": request["id"], + "result": { + "type": "pane_info", + "pane": { "terminal_id": "term_2" } + } + }) + ) + .unwrap(); + stream.flush().unwrap(); + }); + + let started = run_cli( + &socket_path, + &[ + "agent", "start", "reviewer", "--kind", "pi", "--pane", "w1:p1", + ], + ); + assert_eq!(started.status.code(), Some(1)); + let error: serde_json::Value = serde_json::from_slice(&started.stderr).unwrap(); + assert_eq!(error["error"]["code"], "agent_pane_busy"); + + server.join().unwrap(); + cleanup_test_base(&base); +} + #[test] fn prompt_wait_is_sent_as_one_agent_request() { let base = unique_test_dir(); -- cgit v1.2.3