aps-agent/tests/golden/test_preference_upgrade.py

66 lines
3.0 KiB
Python
Raw Permalink 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.

# ============================================================
# 偏好学习升级黄金测试(plan.md §8.3 / 矩阵 66 行)
# 覆盖:项目隔离、解释(得分明细+冷启动/不确定度)、重置、向后兼容。
# ============================================================
from __future__ import annotations
from pathlib import Path
from server.knowledge.preferences import PreferenceStore
def _store(tmp_path: Path) -> PreferenceStore:
return PreferenceStore(path=str(tmp_path / "pref.json"))
def test_preference_project_isolation(tmp_path: Path):
"""项目隔离:不同项目各算各的分,个人全局不受项目样本影响。"""
ps = _store(tmp_path)
ps.record("DELIVERY_FIRST", source="schedule.run", actor="u1", project_id="p1")
ps.record("DELIVERY_FIRST", source="schedule.run", actor="u1", project_id="p1")
ps.record("CAPACITY_BALANCE", source="scenario.apply", actor="u1", project_id="p2")
ps.record("CAPACITY_BALANCE", source="scenario.apply", actor="u1", project_id="p2")
d1, s1 = ps.preferred_strategy(project_id="p1")
d2, s2 = ps.preferred_strategy(project_id="p2")
assert d1 == "DELIVERY_FIRST" and s1["DELIVERY_FIRST"] == 2
assert d2 == "CAPACITY_BALANCE" and s2["CAPACITY_BALANCE"] == 4
d0, s0 = ps.preferred_strategy() # 个人全局(无项目)
assert d0 == "COMPREHENSIVE" and s0 == {}
def test_preference_explain_cold_and_high(tmp_path: Path):
"""解释:无样本 → cold;样本充足 → high 且带得分明细与依据条数。"""
ps = _store(tmp_path)
cold = ps.explain()
assert cold["confidence"] == "cold"
assert cold["sampleCount"] == 0
for _ in range(4):
ps.record("DELIVERY_FIRST", source="scenario.apply", actor="u1", project_id="p1")
warm = ps.explain(project_id="p1")
assert warm["confidence"] == "high"
assert warm["strategy"] == "DELIVERY_FIRST"
assert warm["sampleCount"] == 4
assert warm["scores"]["DELIVERY_FIRST"] == 8
def test_preference_explain_tie_is_medium(tmp_path: Path):
"""不确定度:并列最高分 → medium(偏好尚不明确)。"""
ps = _store(tmp_path)
ps.record("DELIVERY_FIRST", source="scenario.apply", actor="u1", project_id="p1")
ps.record("CAPACITY_BALANCE", source="scenario.apply", actor="u1", project_id="p1")
ex = ps.explain(project_id="p1")
assert ex["confidence"] == "medium"
def test_preference_reset_by_project(tmp_path: Path):
"""重置:只清指定项目样本,其他项目与个人全局保留。"""
ps = _store(tmp_path)
ps.record("DELIVERY_FIRST", source="schedule.run", actor="u1", project_id="p1")
ps.record("CAPACITY_BALANCE", source="schedule.run", actor="u1", project_id="p2")
ps.record("FIFO", source="schedule.run", actor="u1")
removed = ps.reset(project_id="p1")
assert removed == 1
assert len(ps._samples_for("p1")) == 0
assert len(ps._samples_for("p2")) == 1
assert len(ps._samples_for(None)) == 1 # 个人全局保留