feat(admin): LLM-/GPU-Status-Karte (read-only) — Plan-Schritt 2
- app/admin_llm.py: read-only Statusabfragen ohne sudo (docker ps, ollama ps, nvidia-smi, systemctl --user) mit sicheren Defaults bei fehlenden Tools. - GET /api/admin/llm/status (require_admin): Backend, Modell, Backend-Status, geladene Ollama-Modelle, GPU-Auslastung, Gateway-Dienst-Status. - Admin Status-Tab: LLM-Backend-Karte mit GPU-Balken. - Tests: Auth-Gate + Antwortschema (160 grün). - Doku §7.5: Status-Tab um LLM/GPU-Karte ergänzt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bd20a308de
commit
97ae0a5d34
6 changed files with 216 additions and 3 deletions
41
tests/test_admin_llm_status.py
Normal file
41
tests/test_admin_llm_status.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"""Tests für den read-only LLM-/System-Status (Admin-Panel).
|
||||
|
||||
Getestet: GET /api/admin/llm/status — Auth-Gate + Antwortschema. Die Status-Helfer
|
||||
rufen externe Tools (docker/ollama/nvidia-smi/systemctl) auf; fehlen sie in der
|
||||
Testumgebung, liefern sie sichere Defaults -> der Endpunkt bleibt 200.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
from app.config import settings
|
||||
|
||||
client = TestClient(app)
|
||||
ADMIN = "test-admin-key"
|
||||
ADM_HDR = {"X-Admin-Key": ADMIN}
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _setup(monkeypatch):
|
||||
monkeypatch.setattr(settings, "admin_api_key", ADMIN)
|
||||
monkeypatch.setattr(settings, "auth_enabled", False)
|
||||
yield
|
||||
|
||||
|
||||
def test_status_requires_admin():
|
||||
# Ohne Admin-Key (Auth aus -> anonym, kein Admin) -> 401.
|
||||
assert client.get("/api/admin/llm/status").status_code == 401
|
||||
|
||||
|
||||
def test_status_schema():
|
||||
resp = client.get("/api/admin/llm/status", headers=ADM_HDR)
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
for key in ("backend", "model", "base_url", "llamacpp_running",
|
||||
"ollama_reachable", "ollama_loaded", "gpus", "gateway_service_active"):
|
||||
assert key in data, key
|
||||
assert isinstance(data["ollama_loaded"], list)
|
||||
assert isinstance(data["gpus"], list)
|
||||
# backend wird aus der base_url abgeleitet.
|
||||
assert data["backend"] in ("ollama", "llamacpp", "unknown")
|
||||
Loading…
Add table
Add a link
Reference in a new issue