From 348d20bf55076fdf7975b907bf17effd414996e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 1 Oct 2026 19:22:08 +0800 Subject: [PATCH] =?UTF-8?q?AGC=20=E5=A3=B3=E5=90=8E=E5=8F=B0=20Runtime=20?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E7=9A=84=E7=AD=89=E5=BE=85=E9=A2=84=E7=AE=97?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E5=88=86=E7=89=87=202=20=E7=9A=84=E5=81=87?= =?UTF-8?q?=E7=BA=A2=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tests/mod.rs 已有的 MOCK_PROVIDER_REQUEST_TIMEOUT / AGENT_RUNTIME_TERMINAL_WAIT_BUDGET 现向 runtime_actions 子模块导出(support.rs) - project_tools.rs:background_agent_runtime_can_create_checkpoint_before_file_write 的三处 mock provider 等待由 2s/2s/10s 改为统一预算 - action_execution.rs:background_agent_runtime_can_schedule_ready_manifest_tasks 的两处等待同上 - tool_planning.rs:background_agent_runtime_loads_same_agent_continuity_through_tool_observation 的五处等待同上 - task_lifecycle.rs:background_agent_runtime_can_cancel_active_task_and_retry_it 的取消收口轮询由固定 50×20ms 改为终态预算,并同步放宽首条请求等待 - 依据:origin/master 的 run 3143 与 run 3141 在同一 lane(分片 2/4)分别红了这四条用例,现场全是 2 秒预算或多轮轮询被 CI 分片并发放大,链路本身正常 - 验证:本机 4 条用例串行通过;两 lane 并发下连跑 6 次全绿;分片 1/2/3/4 全量 ok --- .../src-tauri/src/tests/project_tools.rs | 6 +++--- .../src/tests/runtime_actions/action_execution.rs | 4 ++-- .../runtime_actions/planning_strategy/tool_planning.rs | 10 +++++----- .../src-tauri/src/tests/runtime_actions/support.rs | 3 ++- .../src/tests/runtime_actions/task_lifecycle.rs | 7 +++++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/project_tools.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/project_tools.rs index 9835bbeed..765222225 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/project_tools.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/project_tools.rs @@ -2765,18 +2765,18 @@ async fn background_agent_runtime_can_create_checkpoint_before_file_write() { .expect("start background task"); let plan_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("plan llm request"); assert!(plan_request.contains("project.checkpoint")); assert!(plan_request.contains("file.write")); let final_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("final reply llm request"); assert!(final_request.contains("project.checkpoint")); assert!(final_request.contains("已创建 checkpoint checkpoint-")); assert!(final_request.contains("file.write")); let verified_final_request = receiver - .recv_timeout(Duration::from_secs(10)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("final request after checkpoint write verification"); assert!(verified_final_request.contains("project.verify")); assert!(verified_final_request.contains("AGENT_RUNTIME_CURRENT_REVISION_OK")); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs index 780f589d6..765402ad8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs @@ -721,12 +721,12 @@ async fn background_agent_runtime_can_schedule_ready_manifest_tasks() { .contains("处理 manifest ready 任务:拆解创作方向")); let plan_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("plan llm request"); assert!(plan_request.contains("处理 manifest ready 任务:拆解创作方向")); assert!(plan_request.contains("task.update")); let final_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("final reply llm request"); assert!(final_request.contains("任务 design-director 已更新为 completed")); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/tool_planning.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/tool_planning.rs index e418ff190..e7ec98340 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/tool_planning.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/tool_planning.rs @@ -904,11 +904,11 @@ async fn background_agent_runtime_loads_same_agent_continuity_through_tool_obser ) .expect("start first design task"); let first_plan_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("first design plan request"); assert!(first_plan_request.contains("首轮检查连续上下文")); let first_replan_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("first design replan request"); assert!(first_replan_request.contains("连续上下文笔记:第一轮已经确认月光厨房核心循环")); let first_runtime = wait_for_agent_runtime_idle(&root, "design-director"); @@ -930,7 +930,7 @@ async fn background_agent_runtime_loads_same_agent_continuity_through_tool_obser ) .expect("start art task"); let art_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("art plan request"); assert!(art_request.contains("美术无关任务")); assert!(!art_request.contains("design-continuity-first")); @@ -947,7 +947,7 @@ async fn background_agent_runtime_loads_same_agent_continuity_through_tool_obser ) .expect("start second design task"); let second_design_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("second design plan request"); assert!(second_design_request.contains("模板 taskId=design-director")); assert!(!second_design_request.contains("contextBoundary:")); @@ -958,7 +958,7 @@ async fn background_agent_runtime_loads_same_agent_continuity_through_tool_obser assert!(!second_design_request.contains("连续上下文笔记:第一轮已经确认月光厨房核心循环")); assert!(!second_design_request.contains("design-continuity-first [completed / completed]")); let second_design_replan_request = receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("second design replan request after runtime observation"); assert!(second_design_replan_request.contains("agent.run_status")); assert!(second_design_replan_request.contains("conversation.read")); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/support.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/support.rs index 6e0b772d8..1b6e5dbaa 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/support.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/support.rs @@ -3,7 +3,7 @@ pub(super) use std::{ fs, path::Path, sync::{mpsc, Arc, Condvar, Mutex as StdMutex}, - time::Duration, + time::{Duration, Instant}, }; pub(super) use serde_json::Value; @@ -28,6 +28,7 @@ pub(super) use super::super::{ wait_for_agent_runtime_terminal_and_lane_release, wait_for_captured_mock_request, write_agent_runtime_task_record_for_test, write_agent_runtime_verification_fixture, write_static_smoke_game_fixture_for_test, write_test_local_config, + AGENT_RUNTIME_TERMINAL_WAIT_BUDGET, MOCK_PROVIDER_REQUEST_TIMEOUT, }; pub(super) use crate::{ diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/task_lifecycle.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/task_lifecycle.rs index 09cf300b6..766d0fe5a 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/task_lifecycle.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/task_lifecycle.rs @@ -177,7 +177,7 @@ async fn background_agent_runtime_can_cancel_active_task_and_retry_it() { ) .expect("start active task"); let first_request = request_receiver - .recv_timeout(Duration::from_secs(2)) + .recv_timeout(MOCK_PROVIDER_REQUEST_TIMEOUT) .expect("first request"); assert!(first_request.contains("需要取消后重试的后台任务")); @@ -202,7 +202,10 @@ async fn background_agent_runtime_can_cancel_active_task_and_retry_it() { .expect("release first request"); let mut cancelled_result = read_game_creator_agent_runtime_at(&root, "design-director").expect("read cancelled"); - for _ in 0..50 { + // 取消收口同样要等后台 worker 真正停稳;CI 上分片并发放大会把它拖过 1 秒, + // 因此改用与其它终态等待一致的硬预算,而不是固定 50 × 20ms。 + let cancel_deadline = Instant::now() + AGENT_RUNTIME_TERMINAL_WAIT_BUDGET; + while Instant::now() < cancel_deadline { if game_creator_agent_runtime_task_lock_is_available(&root, "design-director") .expect("inspect cancelled runtime lock") && cancelled_result.state.status == "cancelled"