atlas-iac/dockerfiles/hermes-webui-smoke.py
2026-08-23 04:42:08 +00:00

128 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""Exercise branded PWA responses from a running upstream WebUI server."""
from __future__ import annotations
import json
import sys
from collections.abc import Callable
from typing import Any
from urllib.parse import urljoin
from urllib.request import Request, urlopen
PNG_MAGIC = b"\x89PNG\r\n\x1a\n"
PERSONA_LINKS = (
"static/hermes-agent.ico",
"static/hermes-agent-192.png",
"static/hermes-agent-512.png",
)
def _get(
url: str,
opener: Callable[..., Any],
) -> tuple[bytes, str]:
request = Request(url, headers={"Accept-Encoding": "identity"})
with opener(request, timeout=5) as response:
status = int(getattr(response, "status", 0))
if status != 200:
raise RuntimeError(f"GET {url} returned HTTP {status}")
body = response.read()
final_url = response.geturl()
return body, final_url
def _icon_sources(value: object) -> list[str]:
sources: list[str] = []
if isinstance(value, dict):
icons = value.get("icons")
if isinstance(icons, list):
for icon in icons:
if not isinstance(icon, dict) or not isinstance(icon.get("src"), str):
raise RuntimeError("manifest contains an invalid icon entry")
if icon.get("type") != "image/png":
raise RuntimeError("manifest contains a non-PNG icon")
sources.append(icon["src"])
for child in value.values():
if child is not icons:
sources.extend(_icon_sources(child))
elif isinstance(value, list):
for child in value:
sources.extend(_icon_sources(child))
return sources
def smoke(
base_url: str,
*,
opener: Callable[..., Any] = urlopen,
) -> dict[str, object]:
base_url = base_url.rstrip("/") + "/"
manifest_body, manifest_url = _get(urljoin(base_url, "manifest.json"), opener)
try:
manifest = json.loads(manifest_body)
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise RuntimeError("served /manifest.json is not valid branded JSON") from exc
if manifest.get("name") != "Hermes Chat" or manifest.get("short_name") != "Hermes":
raise RuntimeError("served /manifest.json is not branded for Hermes Chat")
expected = {
"static/hermes-agent-192.png",
"static/hermes-agent-512.png",
}
top_level = manifest.get("icons")
if not isinstance(top_level, list) or {
icon.get("src") for icon in top_level if isinstance(icon, dict)
} != expected:
raise RuntimeError("served /manifest.json has the wrong Hermes icons")
icon_sources = _icon_sources(manifest)
if not icon_sources:
raise RuntimeError("served /manifest.json has no icon URLs")
for source in icon_sources:
icon_body, _icon_url = _get(urljoin(manifest_url, source), opener)
if not icon_body.startswith(PNG_MAGIC):
raise RuntimeError(f"manifest icon is not PNG: {source}")
root_body, _root_url = _get(base_url, opener)
try:
root_html = root_body.decode("utf-8")
except UnicodeDecodeError as exc:
raise RuntimeError("served / is not UTF-8 HTML") from exc
for source in PERSONA_LINKS:
if source not in root_html:
raise RuntimeError(f"served / omitted Hermes persona link: {source}")
if "static/hermes-brand.css" not in root_html:
raise RuntimeError("served / omitted static/hermes-brand.css")
direct_icon, _direct_url = _get(
urljoin(base_url, "static/hermes-agent-192.png"), opener
)
if not direct_icon.startswith(PNG_MAGIC):
raise RuntimeError("served /static/hermes-agent-192.png is not PNG")
return {
"manifest": manifest_url,
"icon_requests": len(icon_sources),
"root": base_url,
"direct_icon": "static/hermes-agent-192.png",
}
def main() -> int:
if len(sys.argv) != 2:
raise SystemExit("usage: hermes-webui-smoke.py BASE_URL")
result = smoke(sys.argv[1])
print(
"Hermes WebUI smoke passed: "
f"manifest={result['manifest']} "
f"icon_requests={result['icon_requests']} "
"root=branded direct_icon=png"
)
return 0
if __name__ == "__main__":
raise SystemExit(main())