aps-agent/tests/golden/test_algolib.py

126 lines
5.3 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.

# ============================================================
# 内置算法库注册表黄金测试(矩阵 86 行 · 方向 E)
# 覆盖:注册/查询、元数据完整(A-E 分类)、健康检查、版本查询、随机种子
# ============================================================
from __future__ import annotations
import pytest
from server.agent_core.algolib import (
CATEGORY_LABELS,
AlgorithmManifest,
AlgorithmRegistry,
get_algolib,
reset_algolib_registry,
)
def _registry() -> AlgorithmRegistry:
reset_algolib_registry()
return get_algolib()
def test_register_query_roundtrip():
"""注册→查询→更新(upsert)→注销 全链路。"""
reg = _registry()
manifest = {
"algo_id": "opt.grid_search",
"name": "网格搜索调参",
"category": "C",
"description": "候选网格枚举(黄金测试资产)",
"scale_limit": "<=1k 工单",
"time_budget": "分钟级",
"input_schema": {"grid": "dict"},
"output_schema": {"best": "dict"},
"golden_tests": ["tests/golden/test_param_opt.py"],
"deterministic": True,
"version": "1.0",
}
reg.register(manifest)
got = reg.get("opt.grid_search")
assert got is not None
assert got["algo_id"] == "opt.grid_search"
assert got["category"] == "C"
# 查询:类别 + 关键词
hits = reg.query(category="C", keywords="网格")
assert any(h["algo_id"] == "opt.grid_search" for h in hits)
assert not reg.query(category="B", keywords="网格")
# 重复注册 = upsert(版本升级)
reg.register({**manifest, "version": "2.0"})
assert reg.get("opt.grid_search")["version"] == "2.0"
# 注销
assert reg.unregister("opt.grid_search") is True
assert reg.get("opt.grid_search") is None
assert reg.unregister("opt.grid_search") is False
def test_register_rejects_incomplete_metadata():
"""元数据不完整 / 非确定性缺种子 注册必须拒绝。"""
reg = _registry()
with pytest.raises(ValueError):
reg.register({"algo_id": "bad", "name": "缺类别"})
with pytest.raises(ValueError):
reg.register({"algo_id": "bad2", "name": "非确定性无种子",
"category": "C", "deterministic": False})
def test_builtin_catalog_metadata_complete_and_a_e_cover():
"""内置目录:A-E 五类齐全,每条元数据完整(名称/适用条件/schema/版本/测试/种子)。"""
reg = _registry()
items = reg.list()
assert len(items) >= 10
for m in items:
problems = AlgorithmManifest(**m).validate_manifest()
assert problems == [], f"{m['algo_id']} 元数据不完整: {problems}"
assert set(CATEGORY_LABELS) == {"A", "B", "C", "D", "E"}
for cat in "ABCDE":
assert any(x["category"] == cat for x in items), f"缺 {cat} 类资产"
ids = {x["algo_id"] for x in items}
# 关键内置资产在位:A 规则 / B 精确 / C 元启发 / D ML 目录 / E 集成与评估链
assert {"rule.delivery_first", "rule.comprehensive"} <= ids
assert "cp_sat" in ids
assert "ga" in ids
assert "ml.worktime_regression" in ids
assert {"hybrid", "eval.sensitivity_tornado", "opt.parameter_optimizer"} <= ids
# 非确定性算法都带随机种子(复现锚点)
for m in items:
if not m["deterministic"]:
assert m["random_seed"] is not None, m["algo_id"]
def test_health_check_ok_for_ready_and_fail_for_catalog_only():
"""健康检查:可用内置算法 ok,目录资产如实报未就绪,自定义探针生效。"""
reg = _registry()
by_id = {h["algo_id"]: h for h in reg.health()}
assert by_id["cp_sat"]["ok"] is True
assert by_id["rule.delivery_first"]["ok"] is True
assert by_id["eval.sensitivity_tornado"]["ok"] is True
assert by_id["milp"]["ok"] is False # 未落地资产如实报告
# 自定义健康探针(健康/不健康)
reg.register({"algo_id": "test.ok", "name": "健康算法", "category": "B",
"health_fn": lambda: {"ok": True, "detail": "ready"}})
reg.register({"algo_id": "test.flaky", "name": "易挂算法", "category": "B",
"health_fn": lambda: {"ok": False, "detail": "license expired"}})
assert reg.health("test.ok")[0]["ok"] is True
assert reg.health("test.flaky")[0]["ok"] is False
# 历史记录与未知 id
assert reg.history("test.ok")
assert reg.health("no.such.algo") == []
def test_version_query_and_random_seed_service():
"""版本查询 + 随机种子服务(GA 等非确定性算法复现锚点)。"""
reg = _registry()
v = reg.version("rule.delivery_first")
assert v is not None and v["version"] == "1.0"
assert v["regen_strategy"] in ("llm", "manual", "hybrid")
assert reg.version("no.such") is None
# 升级版本后查询到新版本
reg.register({"algo_id": "rule.delivery_first", "name": "EDD 最早交期",
"category": "A", "version": "2.1", "regen_strategy": "hybrid"})
assert reg.version("rule.delivery_first")["version"] == "2.1"
# 随机种子:确定性算法返回声明种子(缺省 0),非确定性返回稳定种子
assert reg.next_seed("ga") == 20260802
assert reg.next_seed("rule.delivery_first") == 0
assert isinstance(reg.next_seed("no.such"), int)