test: refactor suite to use AsyncClient, in-memory DBs, and parallel coverage

This commit is contained in:
2026-04-09 16:43:49 -04:00
parent de84cc664f
commit 6fc1a2a3ea
11 changed files with 230 additions and 215 deletions

View File

@@ -1,53 +1,43 @@
from typing import Any, Optional
from fastapi.testclient import TestClient
from decnet.web.api import app
from hypothesis import given, strategies as st, settings
import pytest
import httpx
from typing import Any, Optional
from decnet.env import DECNET_ADMIN_USER, DECNET_ADMIN_PASSWORD
from ..conftest import _FUZZ_SETTINGS
from hypothesis import given, strategies as st, settings
def test_get_logs_unauthorized() -> None:
with TestClient(app) as client:
response = client.get("/api/v1/logs")
assert response.status_code == 401
@pytest.mark.anyio
async def test_get_logs_unauthorized(client: httpx.AsyncClient) -> None:
response = await client.get("/api/v1/logs")
assert response.status_code == 401
def test_get_logs_success() -> None:
with TestClient(app) as client:
login_response = client.post(
"/api/v1/auth/login",
json={"username": DECNET_ADMIN_USER, "password": DECNET_ADMIN_PASSWORD}
)
token = login_response.json()["access_token"]
response = client.get(
"/api/v1/logs",
headers={"Authorization": f"Bearer {token}"}
)
assert response.status_code == 200
data = response.json()
assert "data" in data
assert data["total"] >= 0
assert isinstance(data["data"], list)
@pytest.mark.anyio
async def test_get_logs_success(client: httpx.AsyncClient, auth_token: str) -> None:
response = await client.get(
"/api/v1/logs",
headers={"Authorization": f"Bearer {auth_token}"}
)
assert response.status_code == 200
data = response.json()
assert "data" in data
assert data["total"] >= 0
assert isinstance(data["data"], list)
@pytest.mark.anyio
@settings(**_FUZZ_SETTINGS)
@given(
limit=st.integers(min_value=-2000, max_value=5000),
offset=st.integers(min_value=-2000, max_value=5000),
search=st.one_of(st.none(), st.text(max_size=2048))
)
def test_fuzz_get_logs(limit: int, offset: int, search: Optional[str]) -> None:
with TestClient(app) as _client:
_login_resp: httpx.Response = _client.post("/api/v1/auth/login", json={"username": DECNET_ADMIN_USER, "password": DECNET_ADMIN_PASSWORD})
_token: str = _login_resp.json()["access_token"]
async def test_fuzz_get_logs(client: httpx.AsyncClient, auth_token: str, limit: int, offset: int, search: Optional[str]) -> None:
_params: dict[str, Any] = {"limit": limit, "offset": offset}
if search is not None:
_params["search"] = search
_params: dict[str, Any] = {"limit": limit, "offset": offset}
if search is not None:
_params["search"] = search
_response: httpx.Response = _client.get(
"/api/v1/logs",
params=_params,
headers={"Authorization": f"Bearer {_token}"}
)
assert _response.status_code in (200, 422)
_response: httpx.Response = await client.get(
"/api/v1/logs",
params=_params,
headers={"Authorization": f"Bearer {auth_token}"}
)
assert _response.status_code in (200, 422)

View File

@@ -9,7 +9,7 @@ import json
import pytest
from datetime import datetime, timedelta
from freezegun import freeze_time
from decnet.web.sqlite_repository import SQLiteRepository
from decnet.web.db.sqlite.repository import SQLiteRepository
@pytest.fixture
@@ -30,11 +30,13 @@ def _log(decky="d", service="ssh", ip="1.2.3.4", timestamp=None):
}
@pytest.mark.anyio
async def test_histogram_empty_db(repo):
result = await repo.get_log_histogram()
assert result == []
@pytest.mark.anyio
@freeze_time("2026-04-09 12:00:00")
async def test_histogram_single_bucket(repo):
now = datetime.now()
@@ -48,6 +50,7 @@ async def test_histogram_single_bucket(repo):
assert result[0]["count"] == 5
@pytest.mark.anyio
@freeze_time("2026-04-09 12:00:00")
async def test_histogram_two_buckets(repo):
now = datetime.now()
@@ -65,6 +68,7 @@ async def test_histogram_two_buckets(repo):
assert counts == {3, 7}
@pytest.mark.anyio
@freeze_time("2026-04-09 12:00:00")
async def test_histogram_respects_start_end_filter(repo):
now = datetime.now()
@@ -82,6 +86,7 @@ async def test_histogram_respects_start_end_filter(repo):
assert total == 1
@pytest.mark.anyio
@freeze_time("2026-04-09 12:00:00")
async def test_histogram_search_filter(repo):
now = datetime.now()