radar: „Jetzt testen“ – Kandidaten auf Knopfdruck prüfen, wenn der Speicher reicht

User 25.09.: „Warum kann ich Modell-Tests nicht selbst anstoßen, sondern muss
immer auf die Box warten?“ Nachts testet das Radar weiter selbst. Tagsüber jetzt
auch per Knopf – aber nur, wenn Kandidat, Warm-Set UND der heutige Coder
zusammen unter die 115-GB-Grenze passen (der Test-Wächter stoppt den Kandidaten
erst bis zu 10 s, nachdem der Coder zu laden beginnt), und nicht 00:00–03:30.
Sonst steht der Grund beim Kandidaten. Test als Auftrag (radar_lauf.py --test),
höchstens 2 h, dieselben Leitplanken wie nachts; jedes Ergebnis kommt als Meldung.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-25 13:16:39 +02:00
co-authored by Claude Opus 5.5
parent c31ef827fc
commit 44f33c31d3
31 changed files with 278 additions and 36 deletions
+2 -1
View File
@@ -336,7 +336,8 @@ def test_uebersicht_hat_die_felder_der_oberflaeche(zustand):
radar._speichere(stand)
u = radar.uebersicht(_zeit("2026-10-01T12:00:00"))
assert set(u) == {"naechster_test", "letzter_test", "kandidaten", "tests"}
assert set(u["kandidaten"][0]) == set(radar.KANDIDAT_FELDER)
# Dazu seit 25.09.2026, ob „Jetzt testen“ geht und warum nicht.
assert set(u["kandidaten"][0]) == set(radar.KANDIDAT_FELDER) | {"testbar_jetzt", "testbar_grund"}
assert [k["status"] for k in u["kandidaten"]] == ["wartet", "bestanden"]
assert u["naechster_test"] == "2026-10-06T00:30:00+02:00" # die Woche ab dem 29.09. ist belegt
assert u["letzter_test"].startswith("2026-09-29T01:40")
+52
View File
@@ -2,6 +2,7 @@
in radar_lauf.py --nur-suche. Vorher lief die Suche synchron in der Anfrage und konnte Minuten dauern."""
import sys
from datetime import datetime
import pytest
import radar_lauf
@@ -75,3 +76,54 @@ def test_nur_suche_bei_absturz(monkeypatch, capsys):
monkeypatch.setattr(radar_lauf.radar, "suche", kaputt)
assert radar_lauf.nur_suche() == 1
assert capsys.readouterr().out.strip().endswith("Die Suche ist gescheitert: OSError: Platte voll")
# --- „Jetzt testen“ (seit 25.09.2026) ------------------------------------------------------------------------
@pytest.fixture
def radarstand(monkeypatch, tmp_path):
monkeypatch.setattr(radar, "STORE_PATH", tmp_path / "mc2-radar.json")
monkeypatch.setattr(radar, "RADAR_DIR", tmp_path / "radar")
(tmp_path / "radar").mkdir()
stand = radar._leer()
# Zahlen vom 25.09.: Ornith (~27 GB mit KV-Cache) passt tagsüber, Flash-Next (84,6 GB) nur nachts.
stand["kandidaten"]["ornith"] = {"id": "ornith", "name": "Ornith-1.5-35B-A3B", "rolle": "hirn", "status": "neu",
"passt": True, "eng": False, "bedarf_gb": 27.4, "groesse_gb": 22.6}
stand["kandidaten"]["flash"] = {"id": "flash", "name": "Qwen3.8-Flash-Next", "rolle": "coder", "status": "wartet",
"passt": True, "eng": True, "bedarf_gb": 84.6, "groesse_gb": 82.9}
stand["kandidaten"]["alt"] = {"id": "alt", "name": "Alt", "rolle": "hirn", "status": "durchgefallen",
"passt": True, "bedarf_gb": 20.0}
radar._speichere(stand)
return stand
MITTAG = datetime(2026, 9, 25, 13, 0, tzinfo=radar.LOCAL_TZ)
NACHT = datetime(2026, 9, 26, 1, 15, tzinfo=radar.LOCAL_TZ)
def test_jetzt_testbar_nur_wenn_auch_der_coder_noch_passt(radarstand):
k = radarstand["kandidaten"]
assert radar.jetzt_testbar(k["ornith"], MITTAG) == (True, None)
testbar, grund = radar.jetzt_testbar(k["flash"], MITTAG)
assert not testbar and grund.startswith("Zu groß für einen Test tagsüber: braucht ~84,6 GB")
assert radar.jetzt_testbar(k["alt"], MITTAG) == (False, None) # schon beurteilt
testbar, grund = radar.jetzt_testbar(k["ornith"], NACHT)
assert not testbar and "testet das Radar selbst" in grund
oeffentlich = {x["id"]: x for x in radar.uebersicht(MITTAG)["kandidaten"]}
assert oeffentlich["ornith"]["testbar_jetzt"] is True and oeffentlich["flash"]["testbar_jetzt"] is False
def test_jetzt_testen_startet_einen_auftrag(radarstand, auftraege, monkeypatch):
monkeypatch.setattr(radar, "jetzt", lambda: MITTAG)
ergebnis = radar.test_starten("ornith")
assert ergebnis["ok"] and ergebnis["job_id"] == "job123"
start = auftraege["gestartet"][0]
assert start["gruppe"] == "radar" and start["args"][1:] == [str(radar._LAUF_SKRIPT), "--test", "ornith"]
assert start["label"] == "Modell-Radar: Test von Ornith-1.5-35B-A3B"
zu_gross = radar.test_starten("flash")
assert zu_gross["ok"] is False and zu_gross["status"] == 409 and "Zu groß" in zu_gross["detail"]
assert radar.test_starten("gibt-es-nicht")["status"] == 404
app = FastAPI()
app.include_router(radar_router.router)
antwort = TestClient(app).post("/api/radar/flash/testen")
assert antwort.status_code == 409 and "Zu groß" in antwort.json()["detail"]