fix(auto-repair): prefer exact playbooks and fail failed steps
This commit is contained in:
@@ -298,9 +298,6 @@ async def test_auto_repair_failure_does_not_call_verifier(monkeypatch):
|
||||
pb_service = FailingPlaybookService()
|
||||
pb_service.add_playbook(playbook)
|
||||
|
||||
# 讓 _execute_step 拋例外以觸發失敗路徑
|
||||
original_execute_step = AutoRepairService._execute_step
|
||||
|
||||
async def _always_fail(self_inner, incident_arg, step_arg) -> str:
|
||||
raise RuntimeError("強制測試失敗")
|
||||
|
||||
@@ -323,6 +320,40 @@ async def test_auto_repair_failure_does_not_call_verifier(monkeypatch):
|
||||
assert len(stub_learning.verification_calls) == 0, "執行失敗時不應呼叫 record_verification_result"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_auto_repair_failed_step_string_marks_execution_failure(monkeypatch):
|
||||
"""Executor returned FAILED text must not be stored as successful repair."""
|
||||
stub_verifier = StubVerifier(result="success")
|
||||
stub_learning = StubLearningService()
|
||||
|
||||
import src.services.post_execution_verifier as _pev_mod
|
||||
monkeypatch.setattr(_pev_mod, "_verifier", stub_verifier)
|
||||
|
||||
import src.services.learning_service as _ls_mod
|
||||
monkeypatch.setattr(_ls_mod, "_learning_service", stub_learning)
|
||||
|
||||
playbook = _make_playbook()
|
||||
pb_service = StubPlaybookService()
|
||||
pb_service.add_playbook(playbook)
|
||||
|
||||
async def _returns_failed(self_inner, incident_arg, step_arg) -> str:
|
||||
return "FAILED: simulated executor failure"
|
||||
|
||||
monkeypatch.setattr(AutoRepairService, "_execute_step", _returns_failed)
|
||||
|
||||
service = AutoRepairService(
|
||||
playbook_service=pb_service,
|
||||
cooldown_checker=_no_cooldown,
|
||||
)
|
||||
|
||||
result = await service.execute_auto_repair(_make_incident(), playbook)
|
||||
|
||||
assert result.success is False
|
||||
assert "simulated executor failure" in (result.error or "")
|
||||
assert len(stub_verifier.calls) == 0
|
||||
assert len(stub_learning.verification_calls) == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_record_verification_result_no_playbook_id_does_not_crash():
|
||||
"""
|
||||
@@ -330,7 +361,6 @@ async def test_record_verification_result_no_playbook_id_does_not_crash():
|
||||
驗證 learning_service 對 None playbook_id 的防禦性。
|
||||
"""
|
||||
from src.services.learning_service import LearningService
|
||||
from src.repositories.interfaces import ILearningRepository, ITrustRepository
|
||||
|
||||
class NullLearningRepo:
|
||||
async def record_repair(self, **kwargs) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user