80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Production smoke check for Jyotisha web deployment."""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
import time
|
|
from urllib.error import HTTPError, URLError
|
|
from urllib.request import Request, urlopen
|
|
|
|
|
|
def fetch(url: str, timeout: float) -> tuple[int, str, float]:
|
|
started = time.monotonic()
|
|
request = Request(url, headers={"User-Agent": "jyotisha-production-smoke/1.0"})
|
|
try:
|
|
with urlopen(request, timeout=timeout) as response:
|
|
return response.status, response.read().decode("utf-8", "replace"), time.monotonic() - started
|
|
except HTTPError as error:
|
|
return error.code, error.read().decode("utf-8", "replace"), time.monotonic() - started
|
|
except URLError as error:
|
|
raise RuntimeError(str(error.reason)) from error
|
|
|
|
|
|
def check(base_url: str, timeout: float, expected_git_sha: str | None = None) -> dict:
|
|
base = base_url.rstrip("/")
|
|
checks: list[dict] = []
|
|
|
|
status, body, elapsed = fetch(f"{base}/", timeout)
|
|
checks.append(
|
|
{
|
|
"name": "homepage",
|
|
"ok": status == 200 and ("Jyotisha" in body or "账户与出生资料" in body),
|
|
"status": status,
|
|
"latency_ms": round(elapsed * 1000),
|
|
}
|
|
)
|
|
|
|
status, body, elapsed = fetch(f"{base}/api/health", timeout)
|
|
health = json.loads(body) if body.strip().startswith("{") else {}
|
|
checks.append(
|
|
{
|
|
"name": "health",
|
|
"ok": (
|
|
status in {200, 503}
|
|
and health.get("status") in {"ok", "degraded", "blocked"}
|
|
and (not expected_git_sha or health.get("deployment", {}).get("gitCommit") == expected_git_sha)
|
|
),
|
|
"status": status,
|
|
"latency_ms": round(elapsed * 1000),
|
|
"health_status": health.get("status"),
|
|
"checks": sorted((health.get("checks") or {}).keys()),
|
|
"deployment_git_commit": health.get("deployment", {}).get("gitCommit"),
|
|
}
|
|
)
|
|
|
|
return {
|
|
"base_url": base,
|
|
"ok": all(item["ok"] for item in checks),
|
|
"checks": checks,
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--base-url", default="https://jyotisha.chat")
|
|
parser.add_argument("--timeout", type=float, default=8.0)
|
|
parser.add_argument("--expected-git-sha")
|
|
args = parser.parse_args()
|
|
try:
|
|
report = check(args.base_url, args.timeout, args.expected_git_sha)
|
|
except Exception as error: # noqa: BLE001 - CLI smoke should report compact failure.
|
|
report = {"base_url": args.base_url, "ok": False, "error": str(error)}
|
|
print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True))
|
|
return 0 if report.get("ok") else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|