From 082420b5bb873c7e32727a72fe4f902fbf49e363 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Fri, 30 Oct 2026 14:01:52 +0800 Subject: [PATCH] test(agent): finish pending permission turns before runtime teardown (#364) Three ide-agent tests occasionally hung forever (about 1 in 40 runs under parallel load). Their fake agent answers a turn by requesting permission from a blocking thread and waits for the reply; the tests ended while that request was pending, and dropping the Tokio runtime waits for its blocking pool, which never finished. The tests now cancel the pending turn and wait for the task to settle before shutting down. Test-only: in the app, shutdown kills agent processes rather than waiting on them. --- crates/ide-agent/src/tests.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/ide-agent/src/tests.rs b/crates/ide-agent/src/tests.rs index 21215f844..c769e42c0 100644 --- a/crates/ide-agent/src/tests.rs +++ b/crates/ide-agent/src/tests.rs @@ -227,6 +227,8 @@ async fn commands_are_remembered_per_project_and_merged_with_skills_on_disk() { assert_eq!(names(mgr_a.commands("claude", Some(&task.id)).await.unwrap()), ["review", "triage"]); // Other agents get only what they offered. assert!(mgr_a.commands("codex", None).await.unwrap().is_empty()); + mgr_a.cancel(&task.id, None).unwrap(); + wait_for(&mgr_a, &task.id, AgentStatus::Ready).await; mgr_a.shutdown(); // Another project shares the settings but not the commands. @@ -272,6 +274,9 @@ async fn builtin_commands_only_fill_verified_gaps_and_preserve_advertised_metada assert_eq!(commands[0].name, advertised.name); assert_eq!(commands[0].description, advertised.description); assert_eq!(commands[0].hint, advertised.hint); + // Finish the in-process agent before Tokio stops driving its permission response. + mgr.cancel(&task.id, None).unwrap(); + wait_for(&mgr, &task.id, AgentStatus::Ready).await; mgr.shutdown(); } @@ -797,6 +802,8 @@ async fn cursor_approval_switch_resolves_pending_and_survives_restart() { // An unrelated new conversation still asks, even after the cache was updated. let other = mgr.create(new()).await.unwrap(); wait_for(&mgr, &other.id, AgentStatus::NeedsInput).await; + mgr.cancel(&other.id, None).unwrap(); + wait_for(&mgr, &other.id, AgentStatus::Ready).await; mgr.shutdown(); }