aps-agent/tests/conftest.py

117 lines
4.0 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.

# ============================================================
# 测试默认启用演示种子,并把所有持久化状态隔离到进程级临时目录
# ============================================================
from __future__ import annotations
import os
from datetime import datetime
import tempfile
from pathlib import Path
import pytest
# conftest 在测试模块收集前导入:这里必须立即覆盖持久化环境,避免模块级
# 单例在 session fixture 执行前连接仓库内 server/data 或现场数据库。
_SESSION_TEMP = tempfile.TemporaryDirectory(prefix="aps-agent-tests-")
_SESSION_ROOT = Path(_SESSION_TEMP.name).resolve()
_SESSION_HOME = _SESSION_ROOT / "home"
_SESSION_DATA = _SESSION_HOME / "data"
_PERSISTENCE_ENV = {
"APS_HOME": _SESSION_HOME,
"APS_DATA_DIR": _SESSION_DATA,
"APS_DB_PATH": _SESSION_DATA / "master.db",
"APS_WORLD_PATH": _SESSION_DATA / "world.json",
"APS_PROJECTS_PATH": _SESSION_HOME / "sessions" / "workspace.json",
"APS_KNOWLEDGE_PATH": _SESSION_DATA / "knowledge.json",
"APS_CHECKPOINT_PATH": _SESSION_DATA / "checkpoints.json",
"APS_PREFERENCE_PATH": _SESSION_DATA / "preferences.json",
"APS_EMBEDDINGS_PATH": _SESSION_DATA / "embeddings.json",
"APS_APPROVAL_PATH": _SESSION_DATA / "approvals.json",
"APS_AUDIT_LEDGER_DIR": _SESSION_DATA / "audit-ledger",
"APS_AUDIT_MIRROR_DIR": _SESSION_DATA / "audit-mirror",
"APS_AUTOMATION_STATE_PATH": _SESSION_DATA / "automation.json",
"APS_MCP_BUS_PATH": _SESSION_DATA / "mcp-bus.json",
"APS_BRANCH_PATH": _SESSION_DATA / "branches.json",
"APS_BRANCH_DIR": _SESSION_DATA / "branches",
"APS_GOLDEN_CACHE": _SESSION_DATA / "golden-tests.json",
}
for _name, _path in _PERSISTENCE_ENV.items():
os.environ[_name] = str(_path)
# 任何外部数据库 URL 都会绕过 APS_DB_PATH;测试默认必须 fail-closed。
os.environ.pop("APS_DATABASE_URL", None)
os.environ["APS_APPROVAL_BACKEND"] = "file"
os.environ.setdefault("APS_MODE", "web")
# 黄金测试依赖 build_demo_world 的自洽数据;生产默认 APS_SEED_DEMO 关闭。
os.environ.setdefault("APS_SEED_DEMO", "1")
# 本轮系统验收日期固定为 2026-08-02;黄金测试不得因宿主机跨午夜漂移。
import server.timeutil as _timeutil
def _fixed_today0() -> datetime:
return datetime(2026, 8, 2)
_timeutil.today0 = _fixed_today0
def _reset_runtime_caches() -> None:
"""丢弃所有依赖持久化路径的进程级缓存,防止测试间串目录。"""
from server.db.database import reset_engine
reset_engine()
from server.state import store as world_store
with world_store._stores_lock:
world_store._stores.clear()
from server.state.branches import reset_branch_stores
reset_branch_stores()
from server.agent_core.plan_runtime import reset_plan_stores
reset_plan_stores()
from server.agent_core.mcp_bus import reset_mcp_bus
reset_mcp_bus()
from server.knowledge import assets, embedding, preferences
with assets._stores_lock:
assets._stores.clear()
with preferences._stores_lock:
preferences._stores.clear()
with embedding._stores_lock:
embedding._stores.clear()
embedding._provider = None
@pytest.fixture(scope="session", autouse=True)
def _isolated_persistence_session():
"""保证整个 pytest session 只在临时 APS_HOME 下持久化。"""
for path in _PERSISTENCE_ENV.values():
assert Path(path).resolve().is_relative_to(_SESSION_ROOT)
assert not os.environ.get("APS_DATABASE_URL")
_reset_runtime_caches()
yield _SESSION_ROOT
_reset_runtime_caches()
_SESSION_TEMP.cleanup()
@pytest.fixture(autouse=True)
def _isolated_approval_store(tmp_path):
"""每条用例隔离审批状态,并在前后清空所有路径相关缓存。"""
from server.agent_core import harness
_reset_runtime_caches()
store = harness.configure_approval_store(str(tmp_path / "approvals.json"))
yield
store.clear()
_reset_runtime_caches()