Files
hermes-webui/tests/test_issue513_wsl_autostart.py
T
nesquena-hermesandtomas-forgac a308fdd5e8 release: v0.51.494 — TLS-aware launcher health probes (#4412)
Absorbs #4412 (tomas-forgac) rebased onto fresh master, plus two
Codex-regression-gate fixes: (1) use the scheme that actually answered the
probe for the ready/already-up URL + browser-open, (2) honor an explicit
HERMES_WEBUI_HEALTH_URL override in the WSL autostart probe.

Co-authored-by: tomas-forgac <tomas-forgac@users.noreply.github.com>

Closes #4412
2026-06-18 18:13:46 +00:00

110 lines
4.0 KiB
Python

from __future__ import annotations
import re
import shutil
import subprocess
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DOC = REPO_ROOT / "docs" / "wsl-autostart.md"
WSL_SCRIPT = REPO_ROOT / "scripts" / "wsl" / "hermes_webui_autostart.sh"
POWERSHELL_SCRIPT = REPO_ROOT / "scripts" / "windows" / "setup_webui_autostart.ps1"
README = REPO_ROOT / "README.md"
def _read(path: Path) -> str:
return path.read_text(encoding="utf-8")
def test_wsl_autostart_docs_cover_session_and_task_scheduler_options():
doc = _read(DOC)
readme = _read(README)
assert "docs/wsl-autostart.md" in readme
assert "WSL session startup" in doc
assert "Windows Task Scheduler" in doc
assert "scripts/wsl/hermes_webui_autostart.sh" in doc
assert "scripts/windows/setup_webui_autostart.ps1" in doc
assert "HERMES_WEBUI_REPO" in doc
assert "HERMES_WEBUI_LOG_DIR" in doc
assert "HERMES_WEBUI_REQUIRE_AGENT_PROCESS" in doc
assert "/root" not in doc
assert "C:\\Users\\Michael" not in doc
def test_wsl_autostart_launcher_has_safe_duplicate_prevention_and_exports_runtime_env():
script = _read(WSL_SCRIPT)
assert script.startswith("#!/usr/bin/env bash\n")
assert "set -euo pipefail" in script
assert "flock -n" in script
assert "HERMES_WEBUI_LOCK_FILE" in script
assert "HERMES_WEBUI_PID_FILE" in script
assert "hermes_webui_probe_health" in script
assert "bash \"${HERMES_WEBUI_REPO}/start.sh\" --foreground" in script
assert "nohup" in script
# The launcher documents HERMES_WEBUI_HOST/PORT as runtime knobs; they must
# be exported so bootstrap.py/server.py receive the selected WSL values.
assert re.search(r"^export HERMES_WEBUI_HOST HERMES_WEBUI_PORT$", script, re.MULTILINE)
assert "/root" not in script
assert "/home/michael" not in script
def test_wsl_autostart_launcher_passes_bash_syntax_check():
subprocess.run(["bash", "-n", str(WSL_SCRIPT)], check=True, cwd=REPO_ROOT)
def test_wsl_autostart_honors_explicit_health_url_override():
"""#4412 regression: an explicitly-set HERMES_WEBUI_HEALTH_URL must remain the
actual probe target (documented escape hatch), not be silently ignored in
favor of the TLS-aware HOST/PORT helper after the probe refactor.
"""
script = _read(WSL_SCRIPT)
# The override must be detected and used for the probe, not just for logging.
assert "_HERMES_WEBUI_HEALTH_URL_EXPLICIT" in script
# webui_healthy must branch on the explicit flag and probe the exact URL.
assert re.search(
r'_HERMES_WEBUI_HEALTH_URL_EXPLICIT.*==.*"1"',
script,
)
assert '"${HERMES_WEBUI_HEALTH_URL}"' in script
def test_windows_task_scheduler_helper_is_idempotent_and_validates_wsl_script_path():
script = _read(POWERSHELL_SCRIPT)
assert "[CmdletBinding(SupportsShouldProcess = $true)]" in script
assert "Register-ScheduledTask" in script
assert "-Force" in script
assert "New-ScheduledTaskSettingsSet" in script
assert "-MultipleInstances IgnoreNew" in script
assert "Get-ScheduledTask -TaskName $TaskName" in script
assert "wsl.exe" in script
assert '"--exec", "bash", $WslScriptPath' in script
assert '"--exec", "test", "-f", $WslScriptPath' in script
assert "Start-ScheduledTask -TaskName $TaskName" in script
assert "/root" not in script
assert "C:\\Users\\Michael" not in script
def test_powershell_helper_passes_parser_when_pwsh_is_available():
pwsh = None
for candidate in ("pwsh", "powershell"):
resolved = shutil.which(candidate)
if resolved:
pwsh = resolved
break
if not pwsh:
# Linux CI often does not include PowerShell. The source-string tests
# above still pin the safety/idempotency invariants in that case.
return
subprocess.run(
[pwsh, "-NoProfile", "-Command", f"$null = [scriptblock]::Create((Get-Content -Raw '{POWERSHELL_SCRIPT.as_posix()}'))"],
check=True,
cwd=REPO_ROOT,
)