Files
site/scripts/smoke_both_projects.py
T

155 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""Runtime smoke check: site orchestrator + WESP hub (debug session 785e22)."""
from __future__ import annotations
import json
import time
import urllib.error
import urllib.request
from pathlib import Path
LOG_PATH = Path("/Users/vlad/Documents/wesp new (1)/.cursor/debug-785e22.log")
SESSION = "785e22"
RUN_ID = "smoke-v1"
def _log(hypothesis_id: str, location: str, message: str, data: dict) -> None:
payload = {
"sessionId": SESSION,
"runId": RUN_ID,
"hypothesisId": hypothesis_id,
"location": location,
"message": message,
"data": data,
"timestamp": int(time.time() * 1000),
}
LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
with LOG_PATH.open("a", encoding="utf-8") as fh:
fh.write(json.dumps(payload, ensure_ascii=False) + "\n")
def _get(url: str, timeout: float = 3.0) -> tuple[int, str]:
req = urllib.request.Request(url, method="GET")
try:
with urllib.request.urlopen(req, timeout=timeout) as resp:
return resp.status, resp.read(500).decode("utf-8", errors="replace")
except urllib.error.HTTPError as exc:
return exc.code, exc.read(500).decode("utf-8", errors="replace")
except Exception as exc:
return 0, str(exc)
def _post_json(url: str, body: dict, headers: dict | None = None, timeout: float = 5.0) -> tuple[int, str]:
data = json.dumps(body).encode("utf-8")
hdrs = {"Content-Type": "application/json", **(headers or {})}
req = urllib.request.Request(url, data=data, headers=hdrs, method="POST")
try:
with urllib.request.urlopen(req, timeout=timeout) as resp:
return resp.status, resp.read(800).decode("utf-8", errors="replace")
except urllib.error.HTTPError as exc:
return exc.code, exc.read(800).decode("utf-8", errors="replace")
except Exception as exc:
return 0, str(exc)
def _get_with_cookies(url: str, cookie_header: str, timeout: float = 5.0) -> tuple[int, str]:
req = urllib.request.Request(url, method="GET", headers={"Cookie": cookie_header})
try:
with urllib.request.urlopen(req, timeout=timeout) as resp:
return resp.status, resp.read(800).decode("utf-8", errors="replace")
except urllib.error.HTTPError as exc:
return exc.code, exc.read(800).decode("utf-8", errors="replace")
except Exception as exc:
return 0, str(exc)
def _wesp_session_cookie() -> str:
data = json.dumps({"login": "admin", "password": "admin"}).encode("utf-8")
req = urllib.request.Request(
"http://127.0.0.1/api/auth/login",
data=data,
headers={"Content-Type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=5) as resp:
return resp.headers.get("Set-Cookie", "").split(";")[0]
except Exception:
return ""
def main() -> None:
install_env = Path(__file__).resolve().parents[1] / "apps/api/data/secrets/install.env"
wesp_state = Path(__file__).resolve().parents[2] / "wesp/data/orchestrator_sync_state.json"
db_scheme = "missing"
if install_env.is_file():
for line in install_env.read_text(encoding="utf-8").splitlines():
if line.startswith("DATABASE_URL="):
db_scheme = "postgresql" if "postgresql" in line else ("sqlite" if "sqlite" in line else "other")
break
_log("H1", "smoke:install.env", "install.env database scheme", {"scheme": db_scheme, "path": str(install_env)})
orch_cfg = {"exists": wesp_state.is_file(), "enabled": False, "has_upstream": False}
if wesp_state.is_file():
try:
state = json.loads(wesp_state.read_text(encoding="utf-8"))
orch_cfg["enabled"] = bool(state.get("enabled"))
orch_cfg["has_upstream"] = bool(state.get("upstream_url"))
except json.JSONDecodeError:
orch_cfg["parse_error"] = True
_log("H3", "smoke:wesp-state", "WESP orchestrator sync state", orch_cfg)
health_code, health_body = _get("http://127.0.0.1:8000/api/v1/health")
_log("H1", "smoke:site-health", "site API health", {"status": health_code, "body": health_body[:120]})
login_code, login_body = _post_json(
"http://127.0.0.1:8000/api/v1/auth/login",
{"email": "admin@compton.example", "password": "Admin1234"},
headers={"Origin": "http://localhost:5173"},
)
_log(
"H4",
"smoke:site-login",
"site API login",
{"status": login_code, "ok": login_code == 200, "has_token": "access_token" in login_body},
)
wesp_code, wesp_body = _get("http://127.0.0.1/")
_log("H2", "smoke:wesp-root", "WESP hub root", {"status": wesp_code, "body_prefix": wesp_body[:80]})
web_code, _ = _get("http://127.0.0.1:5173/")
_log("H1", "smoke:site-web", "site web dev server", {"status": web_code})
caps_code, caps_body = _get("http://127.0.0.1:8000/api/v1/sync/capabilities")
_log("H5", "smoke:sync-capabilities", "orchestrator sync API", {"status": caps_code, "body": caps_body[:120]})
cookie = _wesp_session_cookie()
if cookie:
ctx_code, ctx_body = _get_with_cookies("http://127.0.0.1/api/v1/orchestrator/context", cookie)
ctx = {}
try:
ctx = json.loads(ctx_body)
except json.JSONDecodeError:
pass
_log(
"H3",
"smoke:wesp-orchestrator-context",
"WESP orchestrator context",
{
"status": ctx_code,
"configured": ctx.get("configured"),
"reachable": ctx.get("reachable"),
"enterpriseId": ctx.get("enterpriseId"),
},
)
print("Smoke complete — see debug log:", LOG_PATH)
print(f" site health: {health_code}, login: {login_code}, web: {web_code}")
print(f" wesp hub: {wesp_code}, install.env db: {db_scheme}, orch configured: {orch_cfg.get('has_upstream')}")
if __name__ == "__main__":
main()