diff --git a/apps/api/tests/test_governance_agent.py b/apps/api/tests/test_governance_agent.py index c9460f1b..edb59437 100644 --- a/apps/api/tests/test_governance_agent.py +++ b/apps/api/tests/test_governance_agent.py @@ -398,17 +398,19 @@ class TestRunSelfCheck: @pytest.mark.asyncio async def test_all_checks_fail_returns_all_errors(self): - """所有項目全部失敗 → 4 個 key 都有 error""" + """所有項目全部失敗 → 5 個 key 都有 error(2026-04-27 P3.4 加入 slo_compliance)""" agent = _make_agent() for attr in ["check_trust_drift", "check_knowledge_degradation", - "check_llm_hallucination", "check_execution_blast_radius"]: + "check_llm_hallucination", "check_execution_blast_radius", + "check_slo_compliance"]: setattr(agent, attr, AsyncMock(side_effect=Exception("mock failure"))) results = await agent.run_self_check() - assert len(results) == 4 - for key in ["trust_drift", "knowledge_degradation", "llm_hallucination", "execution_blast_radius"]: + assert len(results) == 5 + for key in ["trust_drift", "knowledge_degradation", "llm_hallucination", + "execution_blast_radius", "slo_compliance"]: assert "error" in results[key] @@ -514,13 +516,14 @@ class TestRunSelfCheckGlobalFailureAlert: @pytest.mark.asyncio async def test_all_four_checks_fail_triggers_alert_with_four_failed(self): - """4 項全失敗 → governance_self_failure 告警的 failed_checks 包含全部 4 個""" + """5 項全失敗 → governance_self_failure 告警的 failed_checks 包含全部 5 個(2026-04-27 P3.4 加 slo_compliance)""" alerter = AsyncMock() alerter.alert_governance = AsyncMock() agent = _make_agent(alerter=alerter) for attr in ["check_trust_drift", "check_knowledge_degradation", - "check_llm_hallucination", "check_execution_blast_radius"]: + "check_llm_hallucination", "check_execution_blast_radius", + "check_slo_compliance"]: setattr(agent, attr, AsyncMock(side_effect=Exception("all down"))) with patch("src.services.governance_agent.get_db_context") as mock_ctx: @@ -534,8 +537,8 @@ class TestRunSelfCheckGlobalFailureAlert: assert len(governance_failure_calls) >= 1 payload = governance_failure_calls[0][0][1] - assert payload["total_checks"] == 4 - assert len(payload["failed_checks"]) == 4 + assert payload["total_checks"] == 5 + assert len(payload["failed_checks"]) == 5 @pytest.mark.asyncio async def test_two_checks_fail_does_not_trigger_governance_self_failure(self): diff --git a/apps/api/tests/test_wave8_remaining_blockers.py b/apps/api/tests/test_wave8_remaining_blockers.py index cacb81e4..86e6ea5b 100644 --- a/apps/api/tests/test_wave8_remaining_blockers.py +++ b/apps/api/tests/test_wave8_remaining_blockers.py @@ -225,11 +225,12 @@ class TestB8GovernanceFailureAlert: from src.services.governance_agent import GovernanceAgent agent = GovernanceAgent() - # mock 四項 check:3 個 raise,1 個成功 + # 2026-04-27 P3.4: mock 五項 check(含 slo_compliance):3 raise,2 成功 agent.check_trust_drift = AsyncMock(side_effect=RuntimeError("DB down")) agent.check_knowledge_degradation = AsyncMock(side_effect=RuntimeError("KM error")) agent.check_llm_hallucination = AsyncMock(side_effect=RuntimeError("LLM error")) agent.check_execution_blast_radius = AsyncMock(return_value={"status": "ok"}) + agent.check_slo_compliance = AsyncMock(return_value={"status": "ok"}) agent._alert = AsyncMock() @@ -240,7 +241,7 @@ class TestB8GovernanceFailureAlert: call_args = agent._alert.await_args assert call_args[0][0] == "governance_self_failure" payload = call_args[0][1] - assert payload["total_checks"] == 4 + assert payload["total_checks"] == 5 assert len(payload["failed_checks"]) >= 3 @pytest.mark.asyncio @@ -249,10 +250,12 @@ class TestB8GovernanceFailureAlert: from src.services.governance_agent import GovernanceAgent agent = GovernanceAgent() + # 2026-04-27 P3.4: 加 slo_compliance(成功) agent.check_trust_drift = AsyncMock(side_effect=RuntimeError("err1")) agent.check_knowledge_degradation = AsyncMock(side_effect=RuntimeError("err2")) agent.check_llm_hallucination = AsyncMock(return_value={"status": "ok"}) agent.check_execution_blast_radius = AsyncMock(return_value={"status": "ok"}) + agent.check_slo_compliance = AsyncMock(return_value={"status": "ok"}) agent._alert = AsyncMock() @@ -267,10 +270,12 @@ class TestB8GovernanceFailureAlert: from src.services.governance_agent import GovernanceAgent agent = GovernanceAgent() + # 2026-04-27 P3.4: 5 項全失敗 agent.check_trust_drift = AsyncMock(side_effect=RuntimeError("e")) agent.check_knowledge_degradation = AsyncMock(side_effect=RuntimeError("e")) agent.check_llm_hallucination = AsyncMock(side_effect=RuntimeError("e")) agent.check_execution_blast_radius = AsyncMock(side_effect=RuntimeError("e")) + agent.check_slo_compliance = AsyncMock(side_effect=RuntimeError("e")) agent._alert = AsyncMock() @@ -278,4 +283,4 @@ class TestB8GovernanceFailureAlert: agent._alert.assert_awaited_once() payload = agent._alert.await_args[0][1] - assert len(payload["failed_checks"]) == 4 + assert len(payload["failed_checks"]) == 5