From 85cd576b0665f31771236bd6d64a94dcdfb5f8a9 Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Mon, 24 Aug 2026 14:35:08 +0800 Subject: [PATCH] test(bot-relay): match delivery CLI by basename in argv filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI runners have a real hermes sibling next to the venv python, so local_delivery_command now resolves an absolute path there — the exact argv filters in the retry-policy fakes and the relay-methods pins must match by basename instead of the literal "hermes", mirroring the _delivery_lock matcher. --- tests/tools/test_bot_retry_policy.py | 17 ++++++++++++----- tests/tui_gateway/test_bot_relay_methods.py | 6 ++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/tools/test_bot_retry_policy.py b/tests/tools/test_bot_retry_policy.py index 06b302d67f..c623bfbb16 100644 --- a/tests/tools/test_bot_retry_policy.py +++ b/tests/tools/test_bot_retry_policy.py @@ -76,11 +76,18 @@ def _deliver(params): return srv._methods["bot_relay.deliver"](1, params) +def _is_hermes_cli(argv) -> bool: + """Match the delivery CLI by basename — local_delivery_command may + resolve the venv-relative hermes next to the interpreter (#93590).""" + name = str(argv[0]).rsplit("\\", 1)[-1].rsplit("/", 1)[-1] + return name in ("hermes", "hermes.exe") + + def _transport_calls(calls): """Only the Bot Chat transport spawns — a global subprocess.run patch also catches unrelated maintenance calls (git version probes on first server import), which must not count as delivery attempts.""" - return [argv for argv in calls if argv and argv[0] == "hermes"] + return [argv for argv in calls if argv and _is_hermes_cli(argv)] class _Proc: @@ -97,7 +104,7 @@ def test_deliver_retries_same_argv_on_transient_failure(home, monkeypatch): def _fake_run(argv, **kwargs): calls.append(list(argv)) - if list(argv)[:1] != ["hermes"]: + if not _is_hermes_cli(list(argv)): return _Proc(0) if len(_transport_calls(calls)) == 1: return _Proc(1, stderr="Error code: 429 - rate limit exceeded") @@ -119,7 +126,7 @@ def test_deliver_retries_once_on_context_overflow(home, monkeypatch): def _fake_run(argv, **kwargs): calls.append(list(argv)) - if list(argv)[:1] != ["hermes"]: + if not _is_hermes_cli(list(argv)): return _Proc(0) if len(_transport_calls(calls)) == 1: return _Proc(1, stderr="This model's maximum context length is 200000 tokens") @@ -139,7 +146,7 @@ def test_deliver_never_retries_auth_failure(home, monkeypatch): def _fake_run(argv, **kwargs): calls.append(list(argv)) - if list(argv)[:1] != ["hermes"]: + if not _is_hermes_cli(list(argv)): return _Proc(0) return _Proc(1, stderr="Error code: 401 - Your API key is invalid") @@ -156,7 +163,7 @@ def test_deliver_failure_carries_typed_reason(home, monkeypatch): monkeypatch.setattr( "subprocess.run", lambda argv, **k: _Proc(1, stderr="502 server error - overloaded") - if list(argv)[:1] == ["hermes"] + if _is_hermes_cli(list(argv)) else _Proc(0), ) out = _deliver({"profile": "ops", "message": "ping"}) diff --git a/tests/tui_gateway/test_bot_relay_methods.py b/tests/tui_gateway/test_bot_relay_methods.py index 5aac95bb23..7b70ec7b86 100644 --- a/tests/tui_gateway/test_bot_relay_methods.py +++ b/tests/tui_gateway/test_bot_relay_methods.py @@ -78,12 +78,14 @@ def test_deliver_validates_profile_and_runs_transport(home, monkeypatch): ) assert out["reply"] == "pong from ops" argv = calls["argv"] - assert argv[:3] == ["hermes", "-p", "ops"] + # argv[0] may be a resolved venv path (#93590) — match by basename. + assert argv[1:3] == ["-p", "ops"] + assert argv[0].rsplit("\\", 1)[-1].rsplit("/", 1)[-1] in ("hermes", "hermes.exe") assert "Bot Chat" in argv and "--query-file" in argv # 'hermes' alias resolves to default _result(srv._methods["bot_relay.deliver"](2, {"profile": "hermes", "message": "x"})) - assert calls["argv"][:3] == ["hermes", "-p", "default"] + assert calls["argv"][1:3] == ["-p", "default"] # unknown profile refuses without spawning calls.clear()