Files
KiloStar/tests/unit/test_workflow_engine.py
T
zhaoxi 99520c69d7 feat(system):优化后端
1.新增后端测试
2.增加了后端的加密
3.增加了i18n(国际化)
2026-05-31 15:39:34 +00:00

150 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""``ConsciousnessNode.start_workflow_design`` fire workflow ray task 的提交逻辑。
历史上这里有一个常驻的 ``WorkflowRunningEngine`` actor 做中转,现已删除:
workflow 是一次性、有头有尾的执行,更适合直接以 ray task 形式触发。
本测试保证 ConsciousnessNode 在工作流生成后正确 fire ``run_workflow_task``
并通过 ``put_pending`` 推送 SSE 进度(节点端写 pending → API 端 SSE 读 pending)。
"""
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock
import pytest
from kilostar.core.work.workflow import workflow_engine as engine_module
from kilostar.core.work.workflow.workflow import KiloStarWorkflow
from kilostar.core.work.workflow.model import WorkflowMetadata
@pytest.fixture
def consciousness_instance():
from kilostar.core.individual.consciousness_node.consciousness_node import (
ConsciousnessNode,
)
from kilostar.utils.logger import get_logger
cls = ConsciousnessNode.__ray_actor_class__
obj = cls.__new__(cls)
obj.logger = get_logger("consciousness_node")
obj.agent = None
return obj
class _FakeActorRef:
"""模拟 ``ray_actor_hook("name").<name>`` 的链式取属性返回值。"""
def __init__(self, target):
self._target = target
def __getattr__(self, item):
return getattr(self._target, item)
@pytest.mark.asyncio
async def test_start_workflow_design_fires_run_workflow_task(
consciousness_instance, monkeypatch
):
"""快乐路径:working 返回 ForWorkflowEngine,应 fire run_workflow_task 且推送 pending。"""
from kilostar.core.individual.consciousness_node.template import (
ForWorkflowEngine,
)
wf = KiloStarWorkflow(
title="t",
work_link=[],
workflow_metadata=WorkflowMetadata(),
)
consciousness_instance.working = AsyncMock(
return_value=ForWorkflowEngine(workflow=wf, reasoning="r")
)
postgres = MagicMock()
postgres.get_all_worker_individual = MagicMock()
postgres.get_all_worker_individual.remote = AsyncMock(return_value=[])
postgres.update_workflow_status = MagicMock()
postgres.update_workflow_status.remote = AsyncMock()
pending_writes: list[tuple[str, str]] = []
gwm = MagicMock()
gwm.put_pending = MagicMock()
gwm.put_pending.remote = AsyncMock(
side_effect=lambda tid, msg: pending_writes.append((tid, msg))
)
def _fake_hook(name):
if name == "postgres_database":
return SimpleNamespace(postgres_database=_FakeActorRef(postgres))
if name == "global_workflow_manager":
return SimpleNamespace(global_workflow_manager=_FakeActorRef(gwm))
raise KeyError(name)
import kilostar.core.individual.consciousness_node.consciousness_node as cmod
monkeypatch.setattr(cmod, "ray_actor_hook", _fake_hook)
captured: dict = {}
def _fake_task_remote(workflow_dict, trace_id):
captured["workflow_dict"] = workflow_dict
captured["trace_id"] = trace_id
return MagicMock()
monkeypatch.setattr(engine_module.run_workflow_task, "remote", _fake_task_remote)
await consciousness_instance.start_workflow_design("trace-123", "do something")
assert captured["trace_id"] == "trace-123"
assert captured["workflow_dict"]["title"] == "t"
# SSE 推送方向必须是 pendingput_pending
assert any("正在为您构建" in msg for _, msg in pending_writes)
assert any("即将开始执行" in msg for _, msg in pending_writes)
@pytest.mark.asyncio
async def test_start_workflow_design_failed_path_marks_failed(
consciousness_instance, monkeypatch
):
"""working 返回 None / 不匹配类型时应推送失败提示并把 workflow 状态置为 failed。"""
consciousness_instance.working = AsyncMock(return_value=None)
postgres = MagicMock()
postgres.get_all_worker_individual = MagicMock()
postgres.get_all_worker_individual.remote = AsyncMock(return_value=[])
postgres.update_workflow_status = MagicMock()
postgres.update_workflow_status.remote = AsyncMock()
pending_writes: list[tuple[str, str]] = []
gwm = MagicMock()
gwm.put_pending = MagicMock()
gwm.put_pending.remote = AsyncMock(
side_effect=lambda tid, msg: pending_writes.append((tid, msg))
)
def _fake_hook(name):
if name == "postgres_database":
return SimpleNamespace(postgres_database=_FakeActorRef(postgres))
if name == "global_workflow_manager":
return SimpleNamespace(global_workflow_manager=_FakeActorRef(gwm))
raise KeyError(name)
import kilostar.core.individual.consciousness_node.consciousness_node as cmod
monkeypatch.setattr(cmod, "ray_actor_hook", _fake_hook)
fired: list = []
monkeypatch.setattr(
engine_module.run_workflow_task,
"remote",
lambda *a, **kw: fired.append((a, kw)),
)
await consciousness_instance.start_workflow_design("trace-x", "cmd")
assert fired == [] # 没有 fire ray task
postgres.update_workflow_status.remote.assert_awaited_with("trace-x", "failed")
assert any("生成失败" in msg for _, msg in pending_writes)