aps-agent/tests/golden/test_evidence_item.py

80 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.

# 统一 EvidenceItem 与可追溯链黄金测试(plan.md §3.4 / 矩阵 114 行)
# ============================================================
# 覆盖:构造/序列化、链确定性、元素变化断链、ref 解析、schedule-version 兼容。
from __future__ import annotations
import pytest
from server.agent_core.evidence import (
EvidenceItem, evidence_ref, parse_evidence_ref, trace_chain, verify_chain,
schedule_version_item,
)
def test_evidence_ref_roundtrip():
"""证据引用:<kind>:<id> 生成与解析往返。"""
ref = evidence_ref("schedule-version", 12)
assert ref == "schedule-version:12"
assert parse_evidence_ref(ref) == ("schedule-version", "12")
with pytest.raises(ValueError):
parse_evidence_ref("no-colon")
def test_evidence_ref_kind_whitelist():
"""未知 kind 拒绝(白名单防注入)。"""
with pytest.raises(ValueError):
evidence_ref("../../etc", "x")
with pytest.raises(ValueError):
EvidenceItem(kind="hack", ref="x")
def test_trace_chain_deterministic():
"""链确定性:同输入同哈希;数量变化断链。"""
items = [
EvidenceItem(kind="run", ref="run-1", engine="CP", seed=42),
EvidenceItem(kind="knowledge", ref="kb-1", knowledgeVersion="v3"),
EvidenceItem(kind="confirm", ref="c-1", confirmId="abc123"),
]
a = trace_chain(items)
b = trace_chain(items)
assert a["chainHash"] == b["chainHash"]
assert a["count"] == 3
assert verify_chain(items, a["chainHash"]) is True
assert verify_chain(items[:-1], a["chainHash"]) is False # 数量变化断链
def test_trace_chain_sensitive_to_content_and_order():
"""内容/顺序变化断链(可复算可追溯)。"""
items = [
EvidenceItem(kind="run", ref="run-1", engine="CP", seed=42),
EvidenceItem(kind="algorithm", ref="alg-1", version="1.2"),
]
base = trace_chain(items)["chainHash"]
# 内容变化(seed 改)
changed = [EvidenceItem(kind="run", ref="run-1", engine="CP", seed=99),
EvidenceItem(kind="algorithm", ref="alg-1", version="1.2")]
assert trace_chain(changed)["chainHash"] != base
# 顺序变化
swapped = list(reversed(items))
assert trace_chain(swapped)["chainHash"] != base
def test_schedule_version_item_compatible():
"""schedule-version 证据项与既有协议兼容。"""
item = schedule_version_item(7, runId="run-9")
assert item.kind == "schedule-version"
assert item.ref == "7"
assert item.version == "7"
ref = evidence_ref(item.kind, item.ref)
assert parse_evidence_ref(ref) == ("schedule-version", "7")
def test_trace_chain_serializes_items():
"""trace_chain 输出 items 为规范化 dict 列表(可复算输入)。"""
items = [EvidenceItem(kind="report", ref="rpt-1", meta={"x": 1})]
out = trace_chain(items)
assert out["items"][0]["kind"] == "report"
assert out["items"][0]["meta"] == {"x": 1}
# 用输出 dict 复算同链
assert trace_chain(out["items"])["chainHash"] == out["chainHash"]