Stabilize subagent and unified exec test fixtures (#43936)

## What changed

- Match parent follow-up responses by tool call IDs in the grandchild context baseline test, and assert that the grandchild completes with `done`.
- Drive delayed terminal output with newline-delimited stdin instead of sleeps, keeping the process alive across three `write_stdin` calls and updating the expected stdin events.

GitOrigin-RevId: 433954e5ed5ecce920cf198d1bf1264e58178ba6
This commit is contained in:
Tamir Duberstein
2026-09-08 22:31:49 +00:00
committed by copyberry
parent fba22e9a2a
commit 6ab3ae5323
2 changed files with 29 additions and 17 deletions
@@ -67,7 +67,10 @@ use tokio::time::sleep;
use tokio::time::timeout;
use tracing::Level;
use tracing_test::internal::MockWriter;
use wiremock::Mock;
use wiremock::MockServer;
use wiremock::matchers::method;
use wiremock::matchers::path;
const SPAWN_CALL_ID: &str = "spawn-call-1";
const MULTI_AGENT_V1_NAMESPACE: &str = "multi_agent_v1";
@@ -1264,14 +1267,17 @@ async fn grandchild_full_fork_preserves_context_baseline(
]),
)
.await;
let _parent_followups = mount_sse_sequence(
&server,
vec![
sse(vec![ev_completed("baseline-parent-finished-1")]),
sse(vec![ev_completed("baseline-parent-finished-2")]),
],
)
.await;
Mock::given(method("POST"))
.and(path("/v1/responses"))
.and(|req: &wiremock::Request| {
body_contains(req, ROOT_CALL) || body_contains(req, CHILD_CALL)
})
.respond_with(sse_response(sse(vec![ev_completed(
"baseline-parent-finished",
)])))
.with_priority(/*p*/ 6)
.mount(&server)
.await;
let test = test_codex()
.with_history_mode(history_mode)
.with_config(move |config| {
@@ -1337,6 +1343,12 @@ async fn grandchild_full_fork_preserves_context_baseline(
}
})
.await?;
if agent_name == "/root/child/grandchild" {
assert_eq!(
thread.agent_status().await,
AgentStatus::Completed(Some("done".to_string()))
);
}
descendant_requests.push(request);
}
let context_counts = [
+9 -9
View File
@@ -1588,8 +1588,8 @@ async fn unified_exec_emits_terminal_interaction_for_write_stdin(
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn unified_exec_terminal_interaction_captures_delayed_output() -> Result<()> {
// TODO(anp): Remove after timing fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX sleep/echo timing fixture");
// TODO(anp): Remove after interactive fixtures use target-native commands.
skip_if_target_windows!(Ok(()), "uses a POSIX read/printf fixture");
skip_if_no_network!(Ok(()));
skip_if_sandbox!(Ok(()));
@@ -1600,30 +1600,30 @@ async fn unified_exec_terminal_interaction_captures_delayed_output() -> Result<(
let open_call_id = "uexec-delayed-open";
let open_args = json!({
"cmd": "sleep 3 && echo MARKER1 && sleep 3 && echo MARKER2",
"cmd": r#"/bin/sh -c 'read -r input && read -r input && printf "MARKER1\n" && read -r input && printf "MARKER2\n"'"#,
"yield_time_ms": 10,
"tty": true,
});
// Poll stdin three times: first for no output, second after the first marker,
// and a final long poll to capture the second marker.
// The second and third input lines produce the markers. Waiting for the third
// line keeps the process alive across all three write_stdin calls.
let first_poll_call_id = "uexec-delayed-poll-1";
let first_poll_args = json!({
"chars": "x",
"chars": "x\n",
"session_id": 1000,
"yield_time_ms": 10,
});
let second_poll_call_id = "uexec-delayed-poll-2";
let second_poll_args = json!({
"chars": "x",
"chars": "x\n",
"session_id": 1000,
"yield_time_ms": 4000,
});
let third_poll_call_id = "uexec-delayed-poll-3";
let third_poll_args = json!({
"chars": "x",
"chars": "x\n",
"session_id": 1000,
"yield_time_ms": 6000,
});
@@ -1734,7 +1734,7 @@ async fn unified_exec_terminal_interaction_captures_delayed_output() -> Result<(
.iter()
.map(|ev| ev.stdin.as_str())
.collect::<Vec<_>>(),
vec!["x", "x", "x"],
vec!["x\n", "x\n", "x\n"],
"terminal interactions should reflect the three stdin polls"
);