89 lines
3.2 KiB
Python
89 lines
3.2 KiB
Python
"""临时 E2E:对比 → 采用 → 存档 → 回滚。跑完可删。"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import sys
|
||
import urllib.request
|
||
|
||
# Windows 控制台避免 ✅ 等字符触发 GBK 编码错误
|
||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||
|
||
|
||
def chat(text: str, sid: str | None = None) -> list[dict]:
|
||
body = json.dumps({"text": text, "sessionId": sid}).encode()
|
||
req = urllib.request.Request(
|
||
"http://localhost:8000/api/chat",
|
||
data=body,
|
||
headers={"Content-Type": "application/json"},
|
||
)
|
||
events: list[dict] = []
|
||
with urllib.request.urlopen(req, timeout=60) as resp:
|
||
buf = ""
|
||
for chunk in resp:
|
||
buf += chunk.decode()
|
||
while "\n\n" in buf:
|
||
frame, buf = buf.split("\n\n", 1)
|
||
if frame.startswith("data: "):
|
||
events.append(json.loads(frame[6:]))
|
||
return events
|
||
|
||
|
||
def get(url: str) -> dict:
|
||
with urllib.request.urlopen(url, timeout=30) as r:
|
||
return json.loads(r.read())
|
||
|
||
|
||
def post(url: str, data: dict) -> dict:
|
||
body = json.dumps(data).encode()
|
||
req = urllib.request.Request(url, data=body, headers={"Content-Type": "application/json"})
|
||
with urllib.request.urlopen(req, timeout=60) as r:
|
||
return json.loads(r.read())
|
||
|
||
|
||
def main() -> None:
|
||
# 1) compare
|
||
ev = chat("对比几种策略", "e2e-m2")
|
||
blocks = [e for e in ev if e.get("type") == "block"]
|
||
assert any(b["block"]["type"] == "scenario-cards" for b in blocks), blocks
|
||
cards = next(b["block"]["props"]["cards"] for b in blocks if b["block"]["type"] == "scenario-cards")
|
||
print("compare OK", len(cards), "cards:", [c["label"] for c in cards])
|
||
tl0 = get("http://localhost:8000/api/timeline")
|
||
v0 = len(tl0["versions"])
|
||
|
||
# 2) apply best
|
||
best = min(cards, key=lambda c: (c["kpi"]["totalTardiness"], c["kpi"]["conflictCount"]))
|
||
r = post(
|
||
"http://localhost:8000/api/actions/scenario/apply",
|
||
{"sessionId": "e2e-m2", "strategy": best["strategy"], "engine": best["engine"]},
|
||
)
|
||
print("apply OK", (r.get("message") or "")[:80])
|
||
tl1 = get("http://localhost:8000/api/timeline")
|
||
assert len(tl1["versions"]) >= v0, (v0, len(tl1["versions"]))
|
||
print("versions", v0, "->", len(tl1["versions"]))
|
||
|
||
# 3) checkpoint create
|
||
ev2 = chat("存个档 叫 e2e基线", "e2e-m2")
|
||
text = "".join(e.get("text", "") for e in ev2 if e.get("type") == "token")
|
||
print("checkpoint create:", text[:100])
|
||
tl2 = get("http://localhost:8000/api/timeline")
|
||
assert tl2["checkpoints"], tl2
|
||
pair = tl2["checkpoints"][-1]
|
||
print("pair", pair["pairId"], pair["label"])
|
||
|
||
# 4) rollback stage + approve
|
||
ev3 = chat(f"回滚到检查点 {pair['pairId']}", "e2e-m2")
|
||
blocks3 = [e for e in ev3 if e.get("type") == "block"]
|
||
assert any(b["block"]["type"] == "confirm-card" for b in blocks3), blocks3
|
||
cid = next(b["block"]["props"]["confirmId"] for b in blocks3 if b["block"]["type"] == "confirm-card")
|
||
print("rollback staged", cid)
|
||
r2 = post(
|
||
"http://localhost:8000/api/actions/confirm",
|
||
{"sessionId": "e2e-m2", "confirmId": cid, "approve": True},
|
||
)
|
||
print("rollback OK", (r2.get("message") or "")[:100])
|
||
print("E2E M2 PASS")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|