update
This commit is contained in:
@@ -184,3 +184,101 @@ async def test_inhaltsfehler_kein_laufabbruch(monkeypatch):
|
||||
res = await llm.call(ctx, stage="soll", template="Korpus-Soll",
|
||||
werte={"topic": topic, "quelle": "q", "text": "x"}, erwartet=list)
|
||||
assert res is None # begrenzte Restarts, dann None — kein Absturz, keine Pause
|
||||
|
||||
|
||||
async def test_stop_cancelt_verwaisten_haupt_task(monkeypatch):
|
||||
"""Stop cancelt den Wartenden — der ensure_future-Haupt-Task muss MIT
|
||||
sterben, sonst hält er Slot + Tokens bis zum Timeout (aak: 10 Waisen)."""
|
||||
import asyncio
|
||||
import agents
|
||||
import llm
|
||||
from conftest import run_anlegen, topic_anlegen
|
||||
topic = topic_anlegen("orphan")
|
||||
ctx = llm.Kontext(run_anlegen(topic), topic, "minimax")
|
||||
ctx.ebene = "inventar"
|
||||
gestartet = asyncio.Event()
|
||||
gecancelt = asyncio.Event()
|
||||
|
||||
async def langsamer_agent(key, prompt, timeout, **kw):
|
||||
gestartet.set()
|
||||
try:
|
||||
await asyncio.sleep(60)
|
||||
except asyncio.CancelledError:
|
||||
gecancelt.set()
|
||||
raise
|
||||
return agents.AgentErgebnis(0, "nie", "")
|
||||
|
||||
monkeypatch.setattr(agents, "run_agent", langsamer_agent)
|
||||
monkeypatch.setattr(llm, "HEDGE_NACH_S", 0) # Pfad: return await haupt
|
||||
task = asyncio.ensure_future(llm._roher_call("k", "p", 10, ctx, "judge", "none"))
|
||||
await gestartet.wait()
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
await asyncio.wait_for(gecancelt.wait(), timeout=2) # Waise wurde mitgecancelt
|
||||
|
||||
|
||||
async def test_pause_drainiert_statt_zu_canceln(monkeypatch):
|
||||
"""ManuellePause in llm.alle: Laufende laufen zu Ende (Ergebnis zählt),
|
||||
nichts wird gecancelt."""
|
||||
import asyncio
|
||||
import llm
|
||||
fertig = {"langsam": False}
|
||||
|
||||
async def schnell_pausiert():
|
||||
raise llm.ManuellePause("manuell pausiert")
|
||||
|
||||
async def langsam():
|
||||
await asyncio.sleep(0.05)
|
||||
fertig["langsam"] = True
|
||||
|
||||
import pytest
|
||||
with pytest.raises(llm.ManuellePause):
|
||||
await llm.alle([schnell_pausiert(), langsam()])
|
||||
assert fertig["langsam"] is True # NICHT gecancelt — ausgelaufen
|
||||
|
||||
|
||||
async def test_pause_beendet_lauf_als_paused():
|
||||
"""Pause-Flag → nächster Agent liefert „pausiert" → Lauf endet 'paused';
|
||||
Start setzt normal fort (Flag wird aufgehoben)."""
|
||||
import db
|
||||
import pipeline
|
||||
from conftest import topic_anlegen
|
||||
topic = topic_anlegen("pausetest")
|
||||
run_id = pipeline.lauf_starten(topic)
|
||||
pipeline.lauf_pausieren(topic) # vor dem ersten Call — deterministisch
|
||||
await pipeline._laeufe[topic]
|
||||
run = db.one("SELECT * FROM runs WHERE id=?", (run_id,))
|
||||
assert run["status"] == "paused" and "pausiert" in run["grund"]
|
||||
# Resume: Start hebt die Pause auf, Lauf läuft durch
|
||||
pipeline.lauf_starten(topic)
|
||||
await pipeline._laeufe[topic]
|
||||
assert db.one("SELECT status FROM topics WHERE name=?", (topic,))["status"] == "fertig"
|
||||
|
||||
|
||||
async def test_output_cap_ohne_neuversuch(monkeypatch):
|
||||
"""stop=max_tokens ist deterministisch — sofort None statt 2 Neuversuche
|
||||
(der Aufrufer halbiert den Chunk)."""
|
||||
import agents
|
||||
import db
|
||||
import llm
|
||||
from conftest import run_anlegen, topic_anlegen
|
||||
topic = topic_anlegen("cap")
|
||||
ctx = llm.Kontext(run_anlegen(topic), topic, "minimax")
|
||||
ctx.ebene = "inventar"
|
||||
aufrufe = {"n": 0}
|
||||
|
||||
async def cap_agent(key, prompt, timeout, **kw):
|
||||
aufrufe["n"] += 1
|
||||
return agents.AgentErgebnis(1, "", "leere Antwort (stop=max_tokens)",
|
||||
{"input": 100, "output": 32000})
|
||||
monkeypatch.setattr(agents, "run_agent", cap_agent)
|
||||
monkeypatch.setattr(llm, "HEDGE_NACH_S", 0)
|
||||
res = await llm.call(ctx, stage="extraktion", template="Atom-Extraktion",
|
||||
werte={"topic": topic, "quelle": "q", "text": "x"}, erwartet=list)
|
||||
assert res is None and aufrufe["n"] == 1 # genau EIN Versuch
|
||||
ev = db.one("SELECT status, tok_out FROM events WHERE run_id=? AND stage='extraktion'",
|
||||
(ctx.run_id,))
|
||||
assert ev["status"] == "cap" and ev["tok_out"] == 32000
|
||||
|
||||
Reference in New Issue
Block a user