Files
awoooi/apps/api/tests/test_sentry_ai_provider_route.py

93 lines
2.8 KiB
Python

from __future__ import annotations
import inspect
from unittest.mock import AsyncMock
import pytest
from src.services.ai_providers.interfaces import AIResult
from src.services.sentry_webhook_service import (
SentryWebhookService,
_sentry_ai_identity,
route_sentry_ai_analysis,
)
def test_sentry_recurrence_gets_new_run_but_stable_work_item() -> None:
first = _sentry_ai_identity(
{"project": "awoooi", "issue_id": "42", "count": 1}
)
recurrence = _sentry_ai_identity(
{"project": "awoooi", "issue_id": "42", "count": 2}
)
assert first["run_id"] != recurrence["run_id"]
assert first["trace_id"] != recurrence["trace_id"]
assert first["work_item_id"] == recurrence["work_item_id"]
def test_sentry_service_has_no_direct_host188_openclaw_call() -> None:
source = inspect.getsource(SentryWebhookService.analyze_with_openclaw)
assert "get_openclaw_http_service" not in source
assert "route_sentry_ai_analysis" in source
@pytest.mark.asyncio
async def test_sentry_analysis_uses_global_provider_order_and_correlation_ids(
monkeypatch: pytest.MonkeyPatch,
) -> None:
executor = type("Executor", (), {})()
executor.execute = AsyncMock(
return_value=AIResult(
raw_response=(
'{"root_cause":"database saturation","impact":"latency",'
'"fix_suggestion":"inspect pool","prevention":"capacity guard",'
'"confidence":0.8}'
),
success=True,
provider="ollama_gcp_a",
)
)
monkeypatch.setattr("src.services.ai_router.get_ai_executor", lambda: executor)
result = await route_sentry_ai_analysis(
{
"issue_id": "42",
"project": "awoooi",
"level": "error",
"culprit": "api",
}
)
assert result is not None
assert result["analyzed_by"] == "ollama_gcp_a"
call = executor.execute.await_args.kwargs
assert call["provider_order"] == [
"ollama_gcp_a",
"ollama_gcp_b",
"ollama_local",
"gemini",
]
assert call["require_local"] is False
context = call["context"]
assert all(context[key] for key in ("trace_id", "run_id", "work_item_id"))
assert context["alert_requires_ollama_before_cloud"] is True
@pytest.mark.asyncio
async def test_sentry_analysis_fails_closed_on_non_json_provider_response(
monkeypatch: pytest.MonkeyPatch,
) -> None:
executor = type("Executor", (), {})()
executor.execute = AsyncMock(
return_value=AIResult(
raw_response="not-json",
success=True,
provider="ollama_local",
)
)
monkeypatch.setattr("src.services.ai_router.get_ai_executor", lambda: executor)
assert await route_sentry_ai_analysis({"issue_id": "43"}) is None