From 7d070c4e1c81c6432c75eb03831b90c1629e6a5b Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 24 Aug 2026 06:32:46 -0300 Subject: [PATCH] test(hermes): skip node-dependent HUX suites on node-less runners The titan-iac CI pod has no node binary; the gate helper and every direct node invocation in the new HUX suites now skip with an explicit reason instead of erroring, restoring the main-CI baseline. Runners with node keep full enforcement. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf --- testing/tests/hux_node_gate.py | 14 +++++++++++--- testing/tests/test_hermes_hux_runtime_stop.py | 3 +++ testing/tests/test_hermes_hux_ui_foundation.py | 3 +++ testing/tests/test_hermes_webui_hux_backend_e2e.py | 3 +++ testing/tests/test_hermes_webui_hux_integration.py | 3 ++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/testing/tests/hux_node_gate.py b/testing/tests/hux_node_gate.py index 5b7bccbe..1fc580ae 100644 --- a/testing/tests/hux_node_gate.py +++ b/testing/tests/hux_node_gate.py @@ -24,13 +24,21 @@ METRICS = ("lines", "branches", "functions") def node_version() -> tuple[int, int]: - raw = subprocess.run( - ["node", "--version"], check=True, capture_output=True, text=True, timeout=15 - ).stdout.strip().lstrip("v") + try: + raw = subprocess.run( + ["node", "--version"], check=True, capture_output=True, text=True, timeout=15 + ).stdout.strip().lstrip("v") + except (FileNotFoundError, subprocess.CalledProcessError): + pytest.skip("node is unavailable on this runner") major, minor = raw.split(".")[:2] return int(major), int(minor) +def require_node() -> None: + """Skip a node-dependent test on runners without a node binary.""" + node_version() + + def run_node_coverage( sources: list[str], tests: list[str], diff --git a/testing/tests/test_hermes_hux_runtime_stop.py b/testing/tests/test_hermes_hux_runtime_stop.py index f331eb35..75b499a3 100644 --- a/testing/tests/test_hermes_hux_runtime_stop.py +++ b/testing/tests/test_hermes_hux_runtime_stop.py @@ -1,6 +1,8 @@ """Run the focused vanilla HUX stop-control contract tests.""" from pathlib import Path + +from hux_node_gate import require_node import subprocess @@ -9,6 +11,7 @@ ROOT = Path(__file__).resolve().parents[2] def test_hux_stop_runtime_node_contract() -> None: """The browser stop lane must remain owner-bound and truthfully partial.""" + require_node() subprocess.run( ["node", "--test", str(ROOT / "testing/tests/test_hermes_hux_runtime_stop_node.js")], cwd=ROOT, diff --git a/testing/tests/test_hermes_hux_ui_foundation.py b/testing/tests/test_hermes_hux_ui_foundation.py index ebcc1a2e..c30cf31b 100644 --- a/testing/tests/test_hermes_hux_ui_foundation.py +++ b/testing/tests/test_hermes_hux_ui_foundation.py @@ -5,6 +5,8 @@ from __future__ import annotations import subprocess from pathlib import Path +from hux_node_gate import require_node + ROOT = Path(__file__).resolve().parents[2] NODE_TEST = ROOT / "testing/tests/test_hermes_hux_ui_foundation_node.js" @@ -13,6 +15,7 @@ HUX_UI = ROOT / "dockerfiles/hermes-webui-hux" def test_hux_ui_foundation_node_contracts(): """The browser modules pass their functional and isolation checks.""" + require_node() result = subprocess.run( ["node", "--test", str(NODE_TEST)], diff --git a/testing/tests/test_hermes_webui_hux_backend_e2e.py b/testing/tests/test_hermes_webui_hux_backend_e2e.py index b738f724..fabff5bf 100644 --- a/testing/tests/test_hermes_webui_hux_backend_e2e.py +++ b/testing/tests/test_hermes_webui_hux_backend_e2e.py @@ -7,6 +7,8 @@ import hashlib import hmac import json from pathlib import Path + +from hux_node_gate import require_node import subprocess import sys import threading @@ -38,6 +40,7 @@ def _request(port: int, headers: dict[str, str], method: str, path: str, def test_real_backend_http_contracts_are_consumable_by_the_webui(tmp_path: Path) -> None: + require_node() key = b"k" * 32 key_path = tmp_path / "context-key" key_path.write_bytes(key) diff --git a/testing/tests/test_hermes_webui_hux_integration.py b/testing/tests/test_hermes_webui_hux_integration.py index 6dc67b19..bcf207ec 100644 --- a/testing/tests/test_hermes_webui_hux_integration.py +++ b/testing/tests/test_hermes_webui_hux_integration.py @@ -5,7 +5,7 @@ from __future__ import annotations import importlib.util from pathlib import Path -from hux_node_gate import run_node_coverage +from hux_node_gate import require_node, run_node_coverage import shutil import subprocess @@ -65,6 +65,7 @@ def test_browser_bootstrap_per_source_line_and_branch_coverage() -> None: def test_patcher_installs_all_assets_atomically_and_rejects_drift(tmp_path: Path) -> None: + require_node() module = _load_patcher() target = _fixture(tmp_path, module) module.apply(target)