mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Systematic prune per AGENTS.md test policy, one pass over every major test tree (gateway, hermes_cli, tools, agent, run_agent, plugins, cli, cron, tui_gateway, honcho/openviking, root-level): - DELETE: source-reading tests (read_text/getsource on prod files), change-detector tests (exact catalog counts, model-name snapshots, config version literals), mock-echo tests (assert a mock returns what it was told), assertion-free/trivial tests, near-duplicate parametrizations (boundaries + one representative kept), async/sync twin duplicates, cosmetic within-file variations. - KEEP (mandatory): security/redaction/approval guards, message-role alternation invariants, prompt-caching/deterministic-call-id invariants, issue-number regression tests (deduped), E2E tests. - 6 test files deleted outright (script-style/no-assert or fully redundant); conftest.py, fakes/, fixtures/ untouched. - tests/acp/conftest.py added: autouse fixture stubs the live models.dev/GitHub/Copilot/Anthropic inventory fetches that ACP server tests performed on every session create — test_server.py 147s → 3.4s, and the tests are now genuinely hermetic. - Sleep-based slowness shrunk where safe (codex_ttfb_watchdog, compression_concurrent_fork, etc.); no wall-clock assertion tightened. Verification: full hermetic suite via scripts/run_tests.sh — 2439 files, 31,130 tests passed, 0 failed, 0 flaky retries, 315s wall (baseline: 583s wall, 13,564s subprocess CPU).
144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
"""Tests for WSL detection and WSL-aware gateway behavior."""
|
|
|
|
import subprocess
|
|
from types import SimpleNamespace
|
|
from unittest.mock import patch, MagicMock, mock_open
|
|
|
|
import pytest
|
|
|
|
import hermes_cli.gateway as gateway
|
|
import hermes_constants
|
|
|
|
|
|
# =============================================================================
|
|
# is_wsl() in hermes_constants
|
|
# =============================================================================
|
|
|
|
class TestIsWsl:
|
|
"""Test the shared is_wsl() utility."""
|
|
|
|
def setup_method(self):
|
|
# Reset cached value between tests
|
|
hermes_constants._wsl_detected = None
|
|
|
|
def test_detects_wsl2(self):
|
|
fake_content = (
|
|
"Linux version 5.15.146.1-microsoft-standard-WSL2 "
|
|
"(gcc (GCC) 11.2.0) #1 SMP Thu Jan 11 04:09:03 UTC 2024\n"
|
|
)
|
|
with patch("builtins.open", mock_open(read_data=fake_content)):
|
|
assert hermes_constants.is_wsl() is True
|
|
|
|
|
|
def test_no_proc_version(self):
|
|
with patch("builtins.open", side_effect=FileNotFoundError):
|
|
assert hermes_constants.is_wsl() is False
|
|
|
|
|
|
# =============================================================================
|
|
# _wsl_systemd_operational() in gateway
|
|
# =============================================================================
|
|
|
|
class TestWslSystemdOperational:
|
|
"""Test the WSL systemd check."""
|
|
|
|
def test_running(self, monkeypatch):
|
|
monkeypatch.setattr(
|
|
gateway.subprocess, "run",
|
|
lambda *a, **kw: SimpleNamespace(
|
|
returncode=0, stdout="running\n", stderr=""
|
|
),
|
|
)
|
|
assert gateway._wsl_systemd_operational() is True
|
|
|
|
|
|
# =============================================================================
|
|
# supports_systemd_services() WSL integration
|
|
# =============================================================================
|
|
|
|
class TestSupportsSystemdServicesWSL:
|
|
"""Test that supports_systemd_services() handles WSL correctly."""
|
|
|
|
def test_wsl_with_systemd(self, monkeypatch):
|
|
"""WSL + working systemd → True."""
|
|
monkeypatch.setattr(gateway, "is_linux", lambda: True)
|
|
monkeypatch.setattr(gateway, "is_termux", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_wsl", lambda: True)
|
|
monkeypatch.setattr(gateway, "_wsl_systemd_operational", lambda: True)
|
|
assert gateway.supports_systemd_services() is True
|
|
|
|
|
|
def test_termux_still_excluded(self, monkeypatch):
|
|
"""Termux → False regardless of WSL status."""
|
|
monkeypatch.setattr(gateway, "is_linux", lambda: True)
|
|
monkeypatch.setattr(gateway, "is_termux", lambda: True)
|
|
assert gateway.supports_systemd_services() is False
|
|
|
|
|
|
# =============================================================================
|
|
# WSL messaging in gateway commands
|
|
# =============================================================================
|
|
|
|
class TestGatewayCommandWSLMessages:
|
|
"""Test that WSL users see appropriate guidance."""
|
|
|
|
def test_install_wsl_no_systemd(self, monkeypatch, capsys):
|
|
"""hermes gateway install on WSL without systemd shows guidance."""
|
|
monkeypatch.setattr(gateway, "is_linux", lambda: True)
|
|
monkeypatch.setattr(gateway, "is_termux", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_wsl", lambda: True)
|
|
monkeypatch.setattr(gateway, "supports_systemd_services", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
|
# CRITICAL: also stub is_windows. Without this, running this test on a
|
|
# real Windows host falls through to the is_windows() branch *before*
|
|
# the WSL guidance branch, invoking gateway_windows.install() which
|
|
# writes a Startup-folder .cmd into the real user's Startup folder
|
|
# (NOT tmp_path) pointing at a now-vanished pytest fixture path.
|
|
# The user then sees a broken Hermes_Gateway.cmd flash a cmd.exe
|
|
# window on every login. See fix/windows-gateway-reliability.
|
|
monkeypatch.setattr(gateway, "is_windows", lambda: False)
|
|
|
|
args = SimpleNamespace(
|
|
gateway_command="install", force=False, system=False,
|
|
run_as_user=None,
|
|
)
|
|
with pytest.raises(SystemExit) as exc_info:
|
|
gateway.gateway_command(args)
|
|
assert exc_info.value.code == 1
|
|
|
|
out = capsys.readouterr().out
|
|
assert "WSL detected" in out
|
|
assert "systemd is not running" in out
|
|
assert "hermes gateway run" in out
|
|
assert "tmux" in out
|
|
|
|
|
|
def test_status_wsl_running_manual(self, monkeypatch, capsys):
|
|
"""hermes gateway status on WSL with manual process shows WSL note."""
|
|
monkeypatch.setattr(gateway, "supports_systemd_services", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_termux", lambda: False)
|
|
monkeypatch.setattr(gateway, "is_wsl", lambda: True)
|
|
# Stub is_windows so a Windows host running this test does NOT take
|
|
# the Windows status branch (which reads gateway_windows.is_installed()).
|
|
monkeypatch.setattr(gateway, "is_windows", lambda: False)
|
|
monkeypatch.setattr(gateway, "find_gateway_pids", lambda: [12345])
|
|
monkeypatch.setattr(gateway, "_runtime_health_lines", lambda: [])
|
|
# Stub out the systemd unit path check
|
|
monkeypatch.setattr(
|
|
gateway, "get_systemd_unit_path",
|
|
lambda system=False: SimpleNamespace(exists=lambda: False),
|
|
)
|
|
monkeypatch.setattr(
|
|
gateway, "get_launchd_plist_path",
|
|
lambda: SimpleNamespace(exists=lambda: False),
|
|
)
|
|
|
|
args = SimpleNamespace(gateway_command="status", deep=False, system=False)
|
|
gateway.gateway_command(args)
|
|
|
|
out = capsys.readouterr().out
|
|
assert "WSL note" in out
|
|
assert "tmux or screen" in out
|
|
|