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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
This commit is contained in:
parent
852d37c087
commit
7d070c4e1c
@ -24,13 +24,21 @@ METRICS = ("lines", "branches", "functions")
|
|||||||
|
|
||||||
|
|
||||||
def node_version() -> tuple[int, int]:
|
def node_version() -> tuple[int, int]:
|
||||||
raw = subprocess.run(
|
try:
|
||||||
["node", "--version"], check=True, capture_output=True, text=True, timeout=15
|
raw = subprocess.run(
|
||||||
).stdout.strip().lstrip("v")
|
["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]
|
major, minor = raw.split(".")[:2]
|
||||||
return int(major), int(minor)
|
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(
|
def run_node_coverage(
|
||||||
sources: list[str],
|
sources: list[str],
|
||||||
tests: list[str],
|
tests: list[str],
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
"""Run the focused vanilla HUX stop-control contract tests."""
|
"""Run the focused vanilla HUX stop-control contract tests."""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from hux_node_gate import require_node
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
@ -9,6 +11,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
|||||||
|
|
||||||
def test_hux_stop_runtime_node_contract() -> None:
|
def test_hux_stop_runtime_node_contract() -> None:
|
||||||
"""The browser stop lane must remain owner-bound and truthfully partial."""
|
"""The browser stop lane must remain owner-bound and truthfully partial."""
|
||||||
|
require_node()
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["node", "--test", str(ROOT / "testing/tests/test_hermes_hux_runtime_stop_node.js")],
|
["node", "--test", str(ROOT / "testing/tests/test_hermes_hux_runtime_stop_node.js")],
|
||||||
cwd=ROOT,
|
cwd=ROOT,
|
||||||
|
|||||||
@ -5,6 +5,8 @@ from __future__ import annotations
|
|||||||
import subprocess
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from hux_node_gate import require_node
|
||||||
|
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[2]
|
ROOT = Path(__file__).resolve().parents[2]
|
||||||
NODE_TEST = ROOT / "testing/tests/test_hermes_hux_ui_foundation_node.js"
|
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():
|
def test_hux_ui_foundation_node_contracts():
|
||||||
"""The browser modules pass their functional and isolation checks."""
|
"""The browser modules pass their functional and isolation checks."""
|
||||||
|
require_node()
|
||||||
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["node", "--test", str(NODE_TEST)],
|
["node", "--test", str(NODE_TEST)],
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import hashlib
|
|||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from hux_node_gate import require_node
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
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:
|
def test_real_backend_http_contracts_are_consumable_by_the_webui(tmp_path: Path) -> None:
|
||||||
|
require_node()
|
||||||
key = b"k" * 32
|
key = b"k" * 32
|
||||||
key_path = tmp_path / "context-key"
|
key_path = tmp_path / "context-key"
|
||||||
key_path.write_bytes(key)
|
key_path.write_bytes(key)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
from pathlib import Path
|
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 shutil
|
||||||
import subprocess
|
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:
|
def test_patcher_installs_all_assets_atomically_and_rejects_drift(tmp_path: Path) -> None:
|
||||||
|
require_node()
|
||||||
module = _load_patcher()
|
module = _load_patcher()
|
||||||
target = _fixture(tmp_path, module)
|
target = _fixture(tmp_path, module)
|
||||||
module.apply(target)
|
module.apply(target)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user