Files
awoooi/apps/api/tests/test_approval_execution_auto_approved_finalize.py
Your Name 596f2f6820
All checks were successful
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / tests (push) Successful in 1m17s
CD Pipeline / build-and-deploy (push) Successful in 3m42s
CD Pipeline / post-deploy-checks (push) Successful in 1m21s
fix(awooop): link auto approved execution evidence
2026-05-13 19:14:17 +08:00

131 lines
3.9 KiB
Python

from types import SimpleNamespace
from unittest.mock import AsyncMock
import pytest
from src.models.approval import RiskLevel
from src.services.approval_execution import ApprovalExecutionService
class _FakeAutoRepairRepo:
def __init__(self) -> None:
self.created: list[dict] = []
async def list_by_incident(self, incident_id: str) -> list:
return []
async def create(self, **kwargs):
self.created.append(kwargs)
return SimpleNamespace(id="are-1", **kwargs)
@pytest.mark.asyncio
async def test_finalize_auto_approved_execution_persists_incident_link(monkeypatch):
repo = _FakeAutoRepairRepo()
timeline = SimpleNamespace(add_event=AsyncMock())
incident_service = SimpleNamespace(resolve_incident=AsyncMock())
write_km = AsyncMock()
run_verify = AsyncMock()
monkeypatch.setattr(
"src.repositories.audit_log_repository.get_auto_repair_execution_repository",
lambda: repo,
)
monkeypatch.setattr(
"src.services.approval_execution.get_timeline_service",
lambda: timeline,
)
monkeypatch.setattr(
"src.services.incident_service.get_incident_service",
lambda: incident_service,
)
monkeypatch.setattr(
"src.core.feature_flags.aiops_flags",
SimpleNamespace(is_sub_flag_enabled=lambda _: True),
)
monkeypatch.setattr(
ApprovalExecutionService,
"write_execution_result_to_km",
write_km,
)
monkeypatch.setattr(
ApprovalExecutionService,
"_run_post_execution_verify",
run_verify,
)
approval = SimpleNamespace(
id="11111111-1111-1111-1111-111111111111",
incident_id="INC-20260513-001",
action="kubectl rollout restart deployment/api -n awoooi-prod",
requested_by="auto_approve_rule_engine",
matched_playbook_id="pb-auto-001",
risk_level=RiskLevel.LOW,
)
await ApprovalExecutionService().finalize_auto_approved_execution(
approval,
success=True,
)
assert repo.created == [
{
"incident_id": "INC-20260513-001",
"playbook_id": "pb-auto-001",
"playbook_name": "approval_auto_execute:RESTART_DEPLOYMENT:api",
"success": True,
"executed_steps": ["kubectl rollout restart deployment/api -n awoooi-prod"],
"error_message": None,
"triggered_by": "auto_approve_rule_engine",
"risk_level": "low",
}
]
timeline.add_event.assert_awaited_once()
write_km.assert_awaited_once_with(approval, True, None)
run_verify.assert_awaited_once()
assert run_verify.await_args.kwargs["action_taken"].startswith(
"auto_repair_playbook:pb-auto-001:RESTART_DEPLOYMENT:api"
)
incident_service.resolve_incident.assert_awaited_once_with("INC-20260513-001")
@pytest.mark.asyncio
async def test_finalize_auto_approved_execution_skips_no_action(monkeypatch):
repo = _FakeAutoRepairRepo()
write_km = AsyncMock()
run_verify = AsyncMock()
monkeypatch.setattr(
"src.repositories.audit_log_repository.get_auto_repair_execution_repository",
lambda: repo,
)
monkeypatch.setattr(
ApprovalExecutionService,
"write_execution_result_to_km",
write_km,
)
monkeypatch.setattr(
ApprovalExecutionService,
"_run_post_execution_verify",
run_verify,
)
approval = SimpleNamespace(
id="22222222-2222-2222-2222-222222222222",
incident_id="INC-20260513-002",
action="NO_ACTION: observe only",
requested_by="auto_approve_rule_engine",
matched_playbook_id="pb-auto-002",
risk_level=RiskLevel.LOW,
)
await ApprovalExecutionService().finalize_auto_approved_execution(
approval,
success=True,
)
assert repo.created == []
write_km.assert_not_awaited()
run_verify.assert_not_awaited()