mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-09 02:47:45 +08:00
174 lines
4.9 KiB
Python
174 lines
4.9 KiB
Python
from __future__ import annotations
|
|||
|
|
|
||
|
|
from datetime import datetime, timedelta, timezone
|
||
|
|
from types import SimpleNamespace
|
||
|
|
from typing import Any, cast
|
||
|
|
from unittest.mock import MagicMock
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from src.services.health.endpoint import EndpointHealthService
|
||
|
|
|
||
|
|
|
||
|
|
class _FakeQuery:
|
||
|
|
def __init__(self, rows: list[SimpleNamespace]) -> None:
|
||
|
|
self._rows = rows
|
||
|
|
|
||
|
|
def filter(self, *args: Any, **kwargs: Any) -> _FakeQuery:
|
||
|
|
return self
|
||
|
|
|
||
|
|
def group_by(self, *args: Any, **kwargs: Any) -> _FakeQuery:
|
||
|
|
return self
|
||
|
|
|
||
|
|
def all(self) -> list[SimpleNamespace]:
|
||
|
|
return self._rows
|
||
|
|
|
||
|
|
|
||
|
|
class _FakeDb:
|
||
|
|
def __init__(self, rows: list[SimpleNamespace]) -> None:
|
||
|
|
self._rows = rows
|
||
|
|
|
||
|
|
def query(self, *args: Any, **kwargs: Any) -> _FakeQuery:
|
||
|
|
return _FakeQuery(self._rows)
|
||
|
|
|
||
|
|
|
||
|
|
def _expr_texts(query: MagicMock) -> list[str]:
|
||
|
|
return [str(arg) for arg in query.filter.call_args.args]
|
||
|
|
|
||
|
|
|
||
|
|
def test_generate_timeline_batch_keeps_compact_and_cli_isolated() -> None:
|
||
|
|
now = datetime(2026, 3, 18, 12, 0, tzinfo=timezone.utc)
|
||
|
|
db = _FakeDb(
|
||
|
|
[
|
||
|
|
SimpleNamespace(
|
||
|
|
endpoint_id="endpoint-compact",
|
||
|
|
segment_idx=0,
|
||
|
|
total_count=2,
|
||
|
|
success_count=2,
|
||
|
|
failed_count=0,
|
||
|
|
min_time=now - timedelta(minutes=55),
|
||
|
|
max_time=now - timedelta(minutes=40),
|
||
|
|
),
|
||
|
|
SimpleNamespace(
|
||
|
|
endpoint_id="endpoint-cli",
|
||
|
|
segment_idx=0,
|
||
|
|
total_count=3,
|
||
|
|
success_count=0,
|
||
|
|
failed_count=3,
|
||
|
|
min_time=now - timedelta(minutes=54),
|
||
|
|
max_time=now - timedelta(minutes=39),
|
||
|
|
),
|
||
|
|
]
|
||
|
|
)
|
||
|
|
|
||
|
|
result = EndpointHealthService._generate_timeline_batch(
|
||
|
|
db=cast(Any, db),
|
||
|
|
format_endpoint_mapping={
|
||
|
|
"openai:compact": ["endpoint-compact"],
|
||
|
|
"openai:cli": ["endpoint-cli"],
|
||
|
|
},
|
||
|
|
now=now,
|
||
|
|
lookback_hours=1,
|
||
|
|
segments=4,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result["openai:compact"]["timeline"][0] == "healthy"
|
||
|
|
assert result["openai:cli"]["timeline"][0] == "unhealthy"
|
||
|
|
|
||
|
|
|
||
|
|
def test_generate_timeline_from_usage_uses_endpoint_ids_directly(
|
||
|
|
monkeypatch: pytest.MonkeyPatch,
|
||
|
|
) -> None:
|
||
|
|
expected = {
|
||
|
|
"timeline": ["healthy", "warning"],
|
||
|
|
"time_range_start": "start",
|
||
|
|
"time_range_end": "end",
|
||
|
|
}
|
||
|
|
|
||
|
|
captured: dict[str, object] = {}
|
||
|
|
|
||
|
|
def _fake_generate_timeline_batch(
|
||
|
|
db: Any,
|
||
|
|
format_endpoint_mapping: dict[str, list[str]],
|
||
|
|
now: datetime,
|
||
|
|
lookback_hours: int,
|
||
|
|
segments: int,
|
||
|
|
) -> dict[str, dict[str, Any]]:
|
||
|
|
captured["db"] = db
|
||
|
|
captured["mapping"] = format_endpoint_mapping
|
||
|
|
captured["lookback_hours"] = lookback_hours
|
||
|
|
captured["segments"] = segments
|
||
|
|
return {"_single": expected}
|
||
|
|
|
||
|
|
monkeypatch.setattr(
|
||
|
|
EndpointHealthService,
|
||
|
|
"_generate_timeline_batch",
|
||
|
|
staticmethod(_fake_generate_timeline_batch),
|
||
|
|
)
|
||
|
|
|
||
|
|
db = cast(Any, object())
|
||
|
|
now = datetime(2026, 3, 18, 12, 0, tzinfo=timezone.utc)
|
||
|
|
|
||
|
|
result = EndpointHealthService._generate_timeline_from_usage(
|
||
|
|
db=db,
|
||
|
|
endpoint_ids=["endpoint-compact"],
|
||
|
|
now=now,
|
||
|
|
lookback_hours=6,
|
||
|
|
segments=2,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert result == expected
|
||
|
|
assert captured["db"] is db
|
||
|
|
assert captured["mapping"] == {"_single": ["endpoint-compact"]}
|
||
|
|
assert captured["lookback_hours"] == 6
|
||
|
|
assert captured["segments"] == 2
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_endpoint_health_by_format_filters_inactive_endpoints(
|
||
|
|
monkeypatch: pytest.MonkeyPatch,
|
||
|
|
) -> None:
|
||
|
|
endpoint_query = MagicMock()
|
||
|
|
endpoint_query.join.return_value = endpoint_query
|
||
|
|
endpoint_query.filter.return_value = endpoint_query
|
||
|
|
endpoint_query.all.return_value = [
|
||
|
|
SimpleNamespace(
|
||
|
|
id="endpoint-compact",
|
||
|
|
provider_id="provider-1",
|
||
|
|
api_format="openai:compact",
|
||
|
|
is_active=True,
|
||
|
|
)
|
||
|
|
]
|
||
|
|
|
||
|
|
key_query = MagicMock()
|
||
|
|
key_query.filter.return_value = key_query
|
||
|
|
key_query.options.return_value = key_query
|
||
|
|
key_query.all.return_value = []
|
||
|
|
|
||
|
|
db = MagicMock()
|
||
|
|
db.query.side_effect = [endpoint_query, key_query]
|
||
|
|
|
||
|
|
monkeypatch.setattr(
|
||
|
|
EndpointHealthService,
|
||
|
|
"_generate_timeline_batch",
|
||
|
|
staticmethod(
|
||
|
|
lambda db, format_endpoint_mapping, now, lookback_hours: {
|
||
|
|
"openai:compact": {
|
||
|
|
"timeline": ["unknown"] * 100,
|
||
|
|
"time_range_start": None,
|
||
|
|
"time_range_end": None,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
EndpointHealthService.get_endpoint_health_by_format(
|
||
|
|
db=cast(Any, db),
|
||
|
|
lookback_hours=6,
|
||
|
|
include_admin_fields=False,
|
||
|
|
use_cache=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
filters = _expr_texts(endpoint_query)
|
||
|
|
assert any("provider_endpoints.is_active" in expr for expr in filters)
|
||
|
|
assert any("providers.is_active" in expr for expr in filters)
|