auto-sync: 2026-05-18 19:28:55

This commit is contained in:
cfdaily
2026-05-18 19:28:55 +08:00
parent 4d1ae4fff3
commit 8d0ead6913
+35 -21
View File
@@ -716,21 +716,12 @@ class TestE9RealAgentDispatch:
self.data_root = data_root
def _make_ticker(self):
"""创建含 Dispatcher + Spawner 的 Ticker隔离 registry,只含当前项目"""
"""创建含 Dispatcher + Spawner 的 Ticker真实 spawn"""
from src.blackboard.registry import ProjectRegistry
from src.daemon.dispatcher import Dispatcher
from src.daemon.spawner import AgentSpawner
import tempfile
self._tmp = Path(tempfile.mkdtemp(prefix="e2e-ticker-"))
registry = ProjectRegistry(self._tmp)
import shutil
src_dir = self.data_root / self.pid
dst_dir = self._tmp / self.pid
if src_dir.exists():
shutil.copytree(src_dir, dst_dir)
registry.create_project(self.pid, f"E9-{self.pid}")
self._spawner = AgentSpawner(dry_run=True)
registry = ProjectRegistry(self.data_root)
self._spawner = AgentSpawner(dry_run=False)
dispatcher = Dispatcher(
registered_agents=["zhangfei-dev", "jiangwei-infra", "simayi-challenger", "pangtong-fujunshi"],
spawner=self._spawner,
@@ -744,12 +735,12 @@ class TestE9RealAgentDispatch:
)
def test_e91_simple_task_agent_execute(self, client):
"""简单任务 → dispatch + spawn 成功(dry_run 模式)"""
"""简单任务 → 真实 Agent 执行 → 等待完成"""
tid = _tid()
resp = client.post(f"/api/projects/{self.pid}/tasks", json={
"id": tid,
"title": "E2E简单任务:echo hello",
"description": "请执行:echo hello",
"description": "请执行:echo hello,然后把输出写入黑板。这是E2E测试,完成后标记done。",
"status": "pending",
"assignee": "zhangfei-dev",
"task_type": "coding",
@@ -757,25 +748,36 @@ class TestE9RealAgentDispatch:
})
assert resp.status_code == 200
# 手动触发 tick(走调度 + dry_run spawn
# 手动触发 tick(走调度 + 真实 spawn
ticker = self._make_ticker()
result = asyncio.run(ticker.tick())
# 验证 dispatch 成功(从 tick 结果 + spawner sessions
# 验证 dispatch 成功
proj = result.get("projects", {}).get(self.pid, {})
assert proj.get("status") == "ok"
dispatched = proj.get("dispatched", [])
assert tid in dispatched, f"Task {tid} not dispatched, dispatched={dispatched}"
# 验证 dry_run spawn 有 session
assert len(self._spawner.active_sessions) > 0 or len(self._spawner._sessions) > 0
# 等待 Agent 完成(最多 180 秒)
db_path = self.data_root / self.pid / "blackboard.db"
bb = Blackboard(db_path)
for _ in range(36):
time.sleep(5)
t = bb.get_task(tid)
if t and t.status in ("done", "failed", "review"):
break
t = bb.get_task(tid)
assert t is not None
assert t.status != "pending", f"Agent 未被调度,状态仍为 pending"
def test_e92_review_task_dispatch(self, client):
"""review 任务 → dispatch + spawn 成功(dry_run 模式)"""
"""review 任务 → 真实 Agent 执行 → 等待完成"""
tid = _tid()
resp = client.post(f"/api/projects/{self.pid}/tasks", json={
"id": tid,
"title": "E2E Review:检查代码",
"description": "请查看任务描述并回复你的评审意见。",
"description": "请查看任务描述并回复你的评审意见。这是E2E测试,简单回复即可。",
"status": "pending",
"assignee": "jiangwei-infra",
"task_type": "review",
@@ -789,7 +791,19 @@ class TestE9RealAgentDispatch:
proj = result.get("projects", {}).get(self.pid, {})
dispatched = proj.get("dispatched", [])
assert tid in dispatched, f"Review task {tid} not dispatched, dispatched={dispatched}"
assert len(self._spawner.active_sessions) > 0 or len(self._spawner._sessions) > 0
# 等待 Agent 完成(最多 180 秒)
db_path = self.data_root / self.pid / "blackboard.db"
bb = Blackboard(db_path)
for _ in range(36):
time.sleep(5)
t = bb.get_task(tid)
if t and t.status in ("done", "failed", "review", "working", "claimed"):
break
t = bb.get_task(tid)
assert t is not None
assert t.status != "pending", f"Review Agent 未被调度,状态仍为 pending"
# ===================================================================