85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
|
|
import database # noqa: E402
|
|
|
|
|
|
@pytest.fixture
|
|
async def testdb(tmp_path, monkeypatch):
|
|
"""Fresh sqlite file per test; resets the module-global connection."""
|
|
monkeypatch.setattr(database, "DB_PATH", tmp_path / "test.db")
|
|
database._db = None
|
|
await database.init_db()
|
|
yield database
|
|
await database.close_db()
|
|
|
|
|
|
@pytest.fixture
|
|
async def fake_welt(testdb, tmp_path, monkeypatch):
|
|
"""E2E ohne LLM: run_agent überall durch die Fake-Welt ersetzt, Tempo-Bremsen raus.
|
|
Alle echten Schichten (_race, Quorum, Panels, Producer, QA-Gate) laufen mit."""
|
|
import agents
|
|
import blocks
|
|
import board_inventory as bi
|
|
import guide
|
|
import kanban
|
|
import pipeline
|
|
import qa
|
|
import repair
|
|
from fake_agents import Welt
|
|
|
|
welt = Welt()
|
|
|
|
async def fake_run_agent(agent_key, prompt, timeout, provider="claude", role="fast",
|
|
capabilities="none", lane="batch", scope=None, on_line=None, label=""):
|
|
return welt.respond(agent_key, prompt, capabilities)
|
|
|
|
for mod in (agents, pipeline, blocks, guide, repair):
|
|
monkeypatch.setattr(mod, "run_agent", fake_run_agent)
|
|
|
|
# Tempo: grace/poll/backoff bremsen echte Läufe, nicht den Fake
|
|
monkeypatch.setattr(blocks, "CONSENSUS_GRACE", 0)
|
|
monkeypatch.setattr(bi, "_QA_GATE_POLL", 0.05)
|
|
monkeypatch.setattr(kanban, "RETRY_BACKOFF", 0.05)
|
|
monkeypatch.setattr(qa, "QA_DIR", tmp_path / "qa")
|
|
import guide_board
|
|
monkeypatch.setattr(guide_board, "READABILITY_ACTIVE", False) # kein Modell-Load im Test
|
|
import asyncio as _aio
|
|
monkeypatch.setattr(bi, "_ingest_lock", _aio.Lock()) # Modul-Lock klebt sonst am Vortest-Loop
|
|
|
|
class _FakeEmb: # identischer Text → cos 1.0, sonst 0.0 (deterministisch, ohne Modell)
|
|
@staticmethod
|
|
def available():
|
|
return True
|
|
|
|
@staticmethod
|
|
def embed_sims(texts):
|
|
import numpy as np
|
|
uniq = {t: k for k, t in enumerate(dict.fromkeys(texts))}
|
|
arr = np.zeros((len(texts), max(len(uniq), 1)))
|
|
for r, t in enumerate(texts):
|
|
arr[r, uniq[t]] = 1.0
|
|
return arr @ arr.T
|
|
|
|
@staticmethod
|
|
def embed(texts):
|
|
import numpy as np
|
|
uniq = {t: k for k, t in enumerate(dict.fromkeys(texts))}
|
|
arr = np.zeros((len(texts), max(len(uniq), 1)))
|
|
for r, t in enumerate(texts):
|
|
arr[r, uniq[t]] = 1.0
|
|
return arr
|
|
|
|
import board_artefacts as ba
|
|
for mod in (blocks, ba, qa):
|
|
monkeypatch.setattr(mod, "embedding", _FakeEmb)
|
|
|
|
async def emb_ok(flow): # Board-1-Vektorpfade aus (wie board_env) — Judge-Wellen reichen
|
|
return False
|
|
monkeypatch.setattr(bi, "_emb_ok", emb_ok)
|
|
return welt
|