Files
mission-control-v2/backend/tests/test_radar_suche_auftrag.py
T
HitonabiandClaude Opus 5.5 93f6613146 box-wart: Hirn gezielt pruefen, Laden meldet das echte Ergebnis, Radar-Suche als Auftrag
- Waechter (pruefe_kern): prueft jetzt gezielt das Modell mit der Rolle hermes und seinen
  Zustand in llama-swap (/running, v257 listet auch ladende Modelle), statt das Hirn fuer
  bereit zu halten, sobald irgendein Modell laeuft. Ein Ladevorgang ist kein Ausfall, aber
  nur bis 10 Minuten (MC_WAECHTER_HIRN_LADEN_S), sonst bliebe ein immer neu startendes Hirn
  unbemerkt. Sonst die ueblichen Takte (FAIL_AFTER); Knopf "Protokoll des Motors".
- llamaswap: modell_zustaende() und hirn_zustand(); lade_modell() meldet ok false mit
  deutschem Grund und der Meldung der Engine, "laedt noch" nach der Wartezeit ist kein Fehler,
  ein geladenes Modell ohne Chat (embed) zaehlt als geladen. POST /api/models/{id}/load
  reicht das Ergebnis durch (Router duenn).
- Radar "Jetzt suchen": startet die Suche als Auftrag (Job-Engine, Gruppe radar, hoechstens
  einer, radar_lauf.py --nur-suche) und antwortet sofort mit der Auftrags-ID. Die Ansicht
  zeigt "Sucht ..." bis der Auftrag fertig ist, liest danach das Radar neu und nennt eine
  gescheiterte Suche; die Auftragskarte zeigt den Stand.
- Tests: Hirn-Zustaende und Frist, Laden gegen eine llama-swap-Attrappe, Radar-Auftrag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 20:39:01 +02:00

78 lines
3.3 KiB
Python

"""„Jetzt suchen“ im Radar als Auftrag (24.09.2026): Die Route antwortet sofort mit einer Auftrags-ID, gesucht wird
in radar_lauf.py --nur-suche. Vorher lief die Suche synchron in der Anfrage und konnte Minuten dauern."""
import sys
import pytest
import radar_lauf
from fastapi import FastAPI
from fastapi.testclient import TestClient
from routers import radar as radar_router
from services import radar
@pytest.fixture
def auftraege(monkeypatch):
"""Job-Engine-Attrappe: merkt sich den Start; läuft schon einer, kommt der zurück."""
stand: dict = {"gestartet": [], "laeuft": None}
def start_job_exklusiv(gruppe, args, label, **kw):
if stand["laeuft"]:
return None, stand["laeuft"]
stand["gestartet"].append({"gruppe": gruppe, "args": args, "label": label, **kw})
return "job123", None
monkeypatch.setattr(radar.jobengine, "start_job_exklusiv", start_job_exklusiv)
return stand
def test_suche_startet_einen_auftrag(auftraege):
ergebnis = radar.suche_starten()
assert ergebnis["ok"] is True and ergebnis["job_id"] == "job123" and "Aufträge" in ergebnis["text"]
(start,) = auftraege["gestartet"]
assert start["gruppe"] == "radar" and start["zeitlimit_s"] == radar.SUCHE_ZEITLIMIT_S
assert start["args"][0] == sys.executable
assert start["args"][1].endswith("radar_lauf.py") and start["args"][2:] == ["--nur-suche"]
def test_laufende_suche_wird_nicht_doppelt_gestartet(auftraege):
auftraege["laeuft"] = {"id": "job-alt", "state": "running"}
ergebnis = radar.suche_starten()
assert (ergebnis["job_id"], ergebnis["laeuft_schon"]) == ("job-alt", True)
assert auftraege["gestartet"] == []
def test_route_antwortet_sofort_ohne_selbst_zu_suchen(auftraege, monkeypatch):
def nicht_hier():
raise AssertionError("Die Route darf nicht selbst suchen.")
monkeypatch.setattr(radar, "suche", nicht_hier)
app = FastAPI()
app.include_router(radar_router.router)
antwort = TestClient(app).post("/api/radar/suche")
assert antwort.status_code == 200 and antwort.json()["job_id"] == "job123"
@pytest.mark.parametrize("ergebnis, code, zeile", [
({"neu": ["Ornith 1.5"], "wartend": 2, "quellen": {"watchlist": True, "discover": True}}, 0,
"Suche fertig: 1 neu (Ornith 1.5), 2 warten auf den Nachttest."),
({"neu": [], "wartend": 1, "quellen": {"watchlist": True, "discover": False}}, 0,
"Suche fertig: nichts Neues, 1 warten auf den Nachttest, Hugging Face war nicht erreichbar."),
({"neu": [], "wartend": 0, "quellen": {"watchlist": False, "discover": False}}, 1,
("Suche fertig: nichts Neues, 0 warten auf den Nachttest, Hugging Face war nicht erreichbar, "
"die Merkliste war nicht lesbar.")),
])
def test_nur_suche_sagt_das_ergebnis_in_der_letzten_zeile(monkeypatch, capsys, ergebnis, code, zeile):
monkeypatch.setattr(radar_lauf.radar, "suche", lambda: ergebnis)
assert radar_lauf.nur_suche() == code
assert capsys.readouterr().out.strip().splitlines()[-1] == zeile
def test_nur_suche_bei_absturz(monkeypatch, capsys):
def kaputt():
raise OSError("Platte voll")
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")