update
This commit is contained in:
@@ -196,56 +196,73 @@ async def test_api_truncation_flagged(monkeypatch):
|
||||
def ram_gate(monkeypatch):
|
||||
monkeypatch.setattr(agents, "RAM_MIN_FREE_PCT", 20)
|
||||
monkeypatch.setattr(agents, "_RAM_POLL_S", 0.01)
|
||||
monkeypatch.setattr(agents, "_opencode_recent_starts", [])
|
||||
monkeypatch.setattr(agents, "_cli_recent_starts", [])
|
||||
return monkeypatch
|
||||
|
||||
|
||||
_EST = agents._RAM_PER_PROC_KB # default batch-agent estimate
|
||||
|
||||
|
||||
async def test_ram_gate_admits_with_free_ram(ram_gate):
|
||||
ram_gate.setattr(agents, "_opencode_running", 5)
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (4_000_000, 8_000_000)) # 50 % frei
|
||||
assert await agents._ram_gate("k") is True
|
||||
assert len(agents._opencode_recent_starts) == 1 # Commit registriert
|
||||
assert await agents._ram_gate("k", _EST) is True
|
||||
assert len(agents._cli_recent_starts) == 1 # Commit registriert
|
||||
|
||||
|
||||
async def test_ram_gate_waits_when_low(ram_gate):
|
||||
ram_gate.setattr(agents, "_opencode_running", 5)
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (800_000, 8_000_000)) # 10 % frei
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(agents._ram_gate("k"), 0.1)
|
||||
await asyncio.wait_for(agents._ram_gate("k", _EST), 0.1)
|
||||
# RAM wird frei → Gate lässt nach ≥1 Poll durch
|
||||
vals = iter([(800_000, 8_000_000)])
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: next(vals, (4_000_000, 8_000_000)))
|
||||
assert await agents._ram_gate("k") is True
|
||||
assert await agents._ram_gate("k", _EST) is True
|
||||
|
||||
|
||||
async def test_ram_gate_floor_and_fail_open(ram_gate):
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (100_000, 8_000_000)) # fast nichts frei
|
||||
ram_gate.setattr(agents, "_opencode_running", 1) # unter Floor
|
||||
assert await agents._ram_gate("k") is True
|
||||
ram_gate.setattr(agents, "_opencode_running", 5)
|
||||
ram_gate.setattr(agents, "_cli_running", 1) # unter Floor
|
||||
assert await agents._ram_gate("k", _EST) is True
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: None) # kein /proc/meminfo
|
||||
assert await agents._ram_gate("k") is True
|
||||
assert await agents._ram_gate("k", _EST) is True
|
||||
ram_gate.setattr(agents, "RAM_MIN_FREE_PCT", 0) # Gate aus
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: pytest.fail("Gate aus liest kein meminfo"))
|
||||
assert await agents._ram_gate("k") is True
|
||||
assert await agents._ram_gate("k", _EST) is True
|
||||
|
||||
|
||||
async def test_ram_gate_commit_accounting(ram_gate):
|
||||
"""Knapp über der Schwelle, aber 2 frische Zulassungen → deren geschätzter RSS zählt."""
|
||||
"""Knapp über der Schwelle, aber 2 frische Zulassungen → deren geschätzter RSS zählt.
|
||||
Ein `full`-Spawn wiegt mehr (MCP-Server) und drückt die verfügbare RAM stärker."""
|
||||
import time as _time
|
||||
ram_gate.setattr(agents, "_opencode_running", 5)
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (1_700_000, 8_000_000)) # 21 % frei
|
||||
agents._opencode_recent_starts.extend([_time.monotonic(), _time.monotonic()])
|
||||
agents._cli_recent_starts.extend([(_time.monotonic(), _EST), (_time.monotonic(), _EST)])
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(agents._ram_gate("k"), 0.1)
|
||||
await asyncio.wait_for(agents._ram_gate("k", _EST), 0.1)
|
||||
|
||||
|
||||
async def test_ram_gate_full_weighs_more(ram_gate):
|
||||
"""Ein frischer Vorgänger belegt Commit für das Fenster. Ein leichter (350 MB) lässt den
|
||||
nächsten noch durch; ein `full` (1250 MB, MCP-Server) reißt die Schwelle → nächster wartet."""
|
||||
import time as _time
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (2_000_000, 8_000_000)) # 25 % frei
|
||||
agents._cli_recent_starts[:] = [(_time.monotonic(), _EST)] # leichter Vorgänger
|
||||
assert await agents._ram_gate("nach-leicht", _EST) is True
|
||||
agents._cli_recent_starts[:] = [(_time.monotonic(), agents._RAM_PER_PROC_FULL_KB)] # full-Vorgänger
|
||||
with pytest.raises(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(agents._ram_gate("nach-full", _EST), 0.1)
|
||||
|
||||
|
||||
async def test_ram_gate_cancelled_scope(ram_gate):
|
||||
ram_gate.setattr(agents, "_opencode_running", 5)
|
||||
ram_gate.setattr(agents, "_cli_running", 5)
|
||||
ram_gate.setattr(agents, "_meminfo", lambda: (800_000, 8_000_000))
|
||||
agents.cancel_scope("blocks-cxl-")
|
||||
try:
|
||||
assert await agents._ram_gate("blocks-cxl-x") is False
|
||||
assert await agents._ram_gate("blocks-cxl-x", _EST) is False
|
||||
finally:
|
||||
agents.clear_scope("blocks-cxl-")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user