feat: overhaul behavioral profiler — multi-tool detection, improved classification, TTL OS fallback
This commit is contained in:
@@ -10,6 +10,24 @@ from unittest.mock import AsyncMock, patch
|
||||
|
||||
# ── Stream endpoint tests ─────────────────────────────────────────────────────
|
||||
|
||||
_EMPTY_STATS = {"total_logs": 0, "unique_attackers": 0, "active_deckies": 0, "deployed_deckies": 0}
|
||||
|
||||
|
||||
def _mock_repo_prefetch(mock_repo, *, crash_on_logs: bool = True) -> None:
|
||||
"""
|
||||
Set up the three prefetch calls that now run in the endpoint function
|
||||
(outside the generator) to return valid dummy data.
|
||||
|
||||
If crash_on_logs is True, get_logs_after_id raises RuntimeError so the
|
||||
generator exits via its except-Exception handler without hanging.
|
||||
"""
|
||||
mock_repo.get_max_log_id = AsyncMock(return_value=0)
|
||||
mock_repo.get_stats_summary = AsyncMock(return_value=_EMPTY_STATS)
|
||||
mock_repo.get_log_histogram = AsyncMock(return_value=[])
|
||||
if crash_on_logs:
|
||||
mock_repo.get_logs_after_id = AsyncMock(side_effect=RuntimeError("test crash"))
|
||||
|
||||
|
||||
class TestStreamEvents:
|
||||
@pytest.mark.asyncio
|
||||
async def test_unauthenticated_returns_401(self, client: httpx.AsyncClient):
|
||||
@@ -18,25 +36,22 @@ class TestStreamEvents:
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stream_sends_initial_stats(self, client: httpx.AsyncClient, auth_token: str):
|
||||
# We force the generator to exit immediately by making the first awaitable raise
|
||||
# Prefetch calls (get_max_log_id, get_stats_summary, get_log_histogram) now
|
||||
# run in the endpoint function before the generator is created. Mock them
|
||||
# all. Crash get_logs_after_id so the generator exits without hanging.
|
||||
with patch("decnet.web.router.stream.api_stream_events.repo") as mock_repo:
|
||||
mock_repo.get_max_log_id = AsyncMock(side_effect=StopAsyncIteration)
|
||||
|
||||
# This will hit the 'except Exception' or just exit the generator
|
||||
_mock_repo_prefetch(mock_repo)
|
||||
resp = await client.get(
|
||||
"/api/v1/stream",
|
||||
headers={"Authorization": f"Bearer {auth_token}"},
|
||||
params={"lastEventId": "0"},
|
||||
)
|
||||
# It might return a 200 with an empty/error stream or a 500 depending on how SSE-starlette handles generator failure
|
||||
# But the important thing is that it FINISHES.
|
||||
assert resp.status_code in (200, 500)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stream_with_query_token(self, client: httpx.AsyncClient, auth_token: str):
|
||||
# Apply the same crash-fix to avoid hanging
|
||||
with patch("decnet.web.router.stream.api_stream_events.repo") as mock_repo:
|
||||
mock_repo.get_max_log_id = AsyncMock(side_effect=StopAsyncIteration)
|
||||
_mock_repo_prefetch(mock_repo)
|
||||
resp = await client.get(
|
||||
"/api/v1/stream",
|
||||
params={"token": auth_token, "lastEventId": "0"},
|
||||
|
||||
Reference in New Issue
Block a user