Files
Pier_v1/Code/교각모델링앱/tools/test_web_ulsan_full.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

59 lines
2.6 KiB
Python

"""Web flow test for Ulsan P1 with the full scope G1~G5 (rebar stage, 2026-10-13). Uses a copy of
the protected template data/_템플릿/산외교울산P1형 in 검증/web_ulsan_full_test_data (recreated); real Rhino runs (one batch session)."""
import os
import shutil
import sys
import time
from pathlib import Path
APP = Path(__file__).resolve().parents[1]
TD = APP / "검증" / "web_ulsan_full_test_data"
if TD.exists():
shutil.rmtree(TD)
# source: the protected template (the pier data/산외교울산P1 itself was deleted in the app on 2026-10-13)
shutil.copytree(APP / "data" / "_템플릿" / "산외교울산P1형", TD / "울산전체", ignore=shutil.ignore_patterns("template.json"))
os.environ["PIERAPP_DATA"] = str(TD)
sys.path.insert(0, str(APP / "web"))
import app as webapp # noqa: E402
sys.path.insert(0, str(Path(__file__).resolve().parent))
from testlib import confirm_required # noqa: E402
import store # noqa: E402
P, BY = "울산전체", "시험자"
EXP = {"G1": 104, "G2": 35, "G3": 63, "G4": 129, "G5": 75}
ok = True
def check(name, cond, detail=""):
global ok
ok &= bool(cond)
print("PASS" if cond else "FAIL", name, str(detail)[:300], flush=True)
c = webapp.app.test_client()
p = store.Pier(P)
check("scope = G1~G5", p.scope() == ["G1", "G2", "G3", "G4", "G5"], p.scope())
h = c.get(f"/pier/{P}").get_data(as_text=True)
check("pier page has no out-of-scope note", "범위 밖" not in h)
confirm_required(c, webapp, store, P, BY)
check("bulk confirm", not webapp.unconfirmed(store.Pier(P)))
c.post(f"/pier/{P}/gates/run_all", data={"by": BY})
t0 = time.time()
while time.time() - t0 < 3000:
b = webapp.batch_state(store.Pier(P))
if b and b["state"] != "실행 중":
break
time.sleep(10)
p = store.Pier(P)
check("batch completes", b["state"] == "완료", b["log"])
for g, n in EXP.items():
st = p.gate_status(g)
check(f"{g} approved, PASS {n}/{n}", st["approved"] and st["report"]["summary"]["passed"] == n, st["report"]["summary"])
c.post(f"/pier/{P}/report", data={"by": BY}, follow_redirects=True)
md = next(p.run_dir.glob("보고서_*.md")).read_text(encoding="utf-8")
check("report: 5/5 gates, all PASS", "게이트 진행: 5/5 실행" in md and "전 게이트 PASS·승인" in md and "범위 밖" not in md)
check("G5 model download", c.get(f"/pier/{P}/download/G5").status_code == 200)
for page in ("/", f"/pier/{P}", f"/pier/{P}/gates", f"/pier/{P}/candidates", f"/pier/{P}/search?q=EL"):
check(f"page renders {page}", c.get(page).status_code == 200)
sys.exit(0 if ok else 1)