| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import hashlib
- import json
- from datetime import UTC, datetime
- from pathlib import Path
- from uuid import uuid4
- import pytest
- from pydantic import ValidationError
- from zhifu.evaluation import Dataset, Judgment, RetrievalManifest, Review, digest, write_report
- def test_agent_dataset_keeps_200_unique_cases_and_separate_groups():
- dataset = Dataset.model_validate_json(Path("evaluations/agent-scenarios.json").read_bytes())
- assert len(dataset.cases()) == 200
- assert sum(case["split"] == "holdout" for case in dataset.cases()) == 100
- invalid = dataset.model_dump()
- invalid["groups"][1]["prompts"][0] = invalid["groups"][0]["prompts"][0] + " "
- with pytest.raises(ValidationError, match="唯一"):
- Dataset.model_validate(invalid)
- invalid = dataset.model_dump()
- invalid["groups"][0]["split"] = "holdout"
- with pytest.raises(ValidationError, match="各需"):
- Dataset.model_validate(invalid)
- def test_review_requires_existing_unchanged_evidence():
- path = Path(".work") / f"review-validation-{uuid4().hex}.json"
- path.parent.mkdir(exist_ok=True)
- write_report(path, {"purpose": "审核字段校验测试资料"})
- try:
- review = Review(reviewer="测试审核字段", reviewed_at=datetime.now(UTC),
- evidence_path=str(path),
- evidence_sha256=hashlib.sha256(path.read_bytes()).hexdigest())
- review.verify()
- write_report(path, {"purpose": "内容变化校验"})
- with pytest.raises(ValueError, match="摘要"):
- review.verify()
- review.reviewed_at = datetime.now()
- with pytest.raises(ValueError, match="时区"):
- review.verify()
- finally:
- path.unlink()
- def test_judgment_rejects_passing_permission_or_duplicate_failures():
- body = {"reviewer": "测试审核字段", "reviewed_at": datetime.now(UTC),
- "evidence_path": "unused", "evidence_sha256": "a" * 64, "case_id": "case",
- "observation_sha256": "b" * 64, "verdict": "PASSED",
- "permission_violations": 1, "duplicate_external_operations": 0}
- with pytest.raises(ValidationError, match="不能登记为通过"):
- Judgment.model_validate(body)
- body.update(permission_violations=0, duplicate_external_operations=1)
- with pytest.raises(ValidationError, match="不能登记为通过"):
- Judgment.model_validate(body)
- def test_retrieval_requires_known_documents_and_production_review():
- identifier = str(uuid4())
- body = {"dataset_version": "schema-validation", "origin": "local_regression",
- "store_id": str(uuid4()), "documents": {identifier: 1},
- "queries": [{"query": "换货资料", "expected": [identifier], "category": "规则"}],
- "embedding_model": "BAAI/bge-m3", "embedding_revision": "pinned",
- "total_timeout_seconds": 10}
- assert RetrievalManifest.model_validate(body).origin == "local_regression"
- body["origin"] = "production_reviewed"
- with pytest.raises(ValidationError, match="人工相关性"):
- RetrievalManifest.model_validate(body)
- evidence = {"review_kind": "agent", "reviewer": "Agent审核", "reviewed_at": datetime.now(UTC),
- "evidence_path": "unused", "evidence_sha256": "a" * 64}
- body.update(review=evidence, deployment_review=evidence)
- with pytest.raises(ValidationError, match="人工相关性"):
- RetrievalManifest.model_validate(body)
- body["origin"] = "local_regression"
- body["queries"][0]["expected"] = [str(uuid4())]
- with pytest.raises(ValidationError, match="未登记资料"):
- RetrievalManifest.model_validate(body)
- def test_report_replacement_preserves_json_and_canonical_digest():
- path = Path(".work") / f"report-validation-{uuid4().hex}.json"
- try:
- write_report(path, {"cases": {"a": "NOT_RUN"}})
- write_report(path, {"cases": {"a": "REVIEW_REQUIRED"}})
- assert json.loads(path.read_text(encoding="utf-8"))["cases"]["a"] == "REVIEW_REQUIRED"
- assert digest({"a": 1, "b": 2}) == digest({"b": 2, "a": 1})
- assert not path.with_suffix(".json.pending").exists()
- finally:
- path.unlink(missing_ok=True)
|