mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 23:11:37 +08:00
108 lines
4.4 KiB
Python
108 lines
4.4 KiB
Python
|
|
"""Tests that load_cli_config() guards against lazy-import TERMINAL_CWD clobbering.
|
||
|
|
|
||
|
|
When the gateway resolves TERMINAL_CWD at startup and cli.py is later
|
||
|
|
imported lazily (via delegate_tool → CLI_CONFIG), load_cli_config() must
|
||
|
|
not overwrite the already-resolved value with os.getcwd().
|
||
|
|
|
||
|
|
config.yaml terminal.cwd is the canonical source of truth.
|
||
|
|
.env TERMINAL_CWD and MESSAGING_CWD are deprecated.
|
||
|
|
See issue #10817.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
|
||
|
|
# The sentinel values that mean "resolve at runtime"
|
||
|
|
_CWD_PLACEHOLDERS = (".", "auto", "cwd")
|
||
|
|
|
||
|
|
|
||
|
|
def _resolve_terminal_cwd(terminal_config: dict, defaults: dict, env: dict):
|
||
|
|
"""Simulate the CWD resolution logic from load_cli_config().
|
||
|
|
|
||
|
|
This mirrors the code in cli.py that checks for a pre-resolved
|
||
|
|
TERMINAL_CWD before falling back to os.getcwd().
|
||
|
|
"""
|
||
|
|
if terminal_config.get("cwd") in _CWD_PLACEHOLDERS:
|
||
|
|
_existing_cwd = env.get("TERMINAL_CWD", "")
|
||
|
|
if _existing_cwd and _existing_cwd not in _CWD_PLACEHOLDERS and os.path.isabs(_existing_cwd):
|
||
|
|
terminal_config["cwd"] = _existing_cwd
|
||
|
|
defaults["terminal"]["cwd"] = _existing_cwd
|
||
|
|
else:
|
||
|
|
effective_backend = terminal_config.get("env_type", "local")
|
||
|
|
if effective_backend == "local":
|
||
|
|
terminal_config["cwd"] = "/fake/getcwd" # stand-in for os.getcwd()
|
||
|
|
defaults["terminal"]["cwd"] = terminal_config["cwd"]
|
||
|
|
else:
|
||
|
|
terminal_config.pop("cwd", None)
|
||
|
|
|
||
|
|
# Simulate the bridging loop: write terminal_config["cwd"] to env
|
||
|
|
_file_has_terminal = defaults.get("_file_has_terminal", False)
|
||
|
|
if "cwd" in terminal_config:
|
||
|
|
if _file_has_terminal or "TERMINAL_CWD" not in env:
|
||
|
|
env["TERMINAL_CWD"] = str(terminal_config["cwd"])
|
||
|
|
|
||
|
|
return env.get("TERMINAL_CWD", "")
|
||
|
|
|
||
|
|
|
||
|
|
class TestLazyImportGuard:
|
||
|
|
"""TERMINAL_CWD resolved by gateway must survive a lazy cli.py import."""
|
||
|
|
|
||
|
|
def test_gateway_resolved_cwd_survives(self):
|
||
|
|
"""Gateway set TERMINAL_CWD → lazy cli import must not clobber."""
|
||
|
|
env = {"TERMINAL_CWD": "/home/user/workspace"}
|
||
|
|
terminal_config = {"cwd": ".", "env_type": "local"}
|
||
|
|
defaults = {"terminal": {"cwd": "."}, "_file_has_terminal": False}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "/home/user/workspace"
|
||
|
|
|
||
|
|
def test_gateway_resolved_cwd_survives_with_file_terminal(self):
|
||
|
|
"""Even when config.yaml has a terminal: section, resolved CWD survives."""
|
||
|
|
env = {"TERMINAL_CWD": "/home/user/workspace"}
|
||
|
|
terminal_config = {"cwd": ".", "env_type": "local"}
|
||
|
|
defaults = {"terminal": {"cwd": "."}, "_file_has_terminal": True}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "/home/user/workspace"
|
||
|
|
|
||
|
|
|
||
|
|
class TestConfigCwdResolution:
|
||
|
|
"""config.yaml terminal.cwd is the canonical source of truth."""
|
||
|
|
|
||
|
|
def test_explicit_config_cwd_wins(self):
|
||
|
|
"""terminal.cwd: /explicit/path always wins."""
|
||
|
|
env = {"TERMINAL_CWD": "/old/gateway/value"}
|
||
|
|
terminal_config = {"cwd": "/explicit/path"}
|
||
|
|
defaults = {"terminal": {"cwd": "/explicit/path"}, "_file_has_terminal": True}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "/explicit/path"
|
||
|
|
|
||
|
|
def test_dot_cwd_resolves_to_getcwd_when_no_prior(self):
|
||
|
|
"""With no pre-set TERMINAL_CWD, "." resolves to os.getcwd()."""
|
||
|
|
env = {}
|
||
|
|
terminal_config = {"cwd": "."}
|
||
|
|
defaults = {"terminal": {"cwd": "."}, "_file_has_terminal": False}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "/fake/getcwd"
|
||
|
|
|
||
|
|
def test_remote_backend_pops_cwd(self):
|
||
|
|
"""Remote backend + placeholder cwd → popped for backend default."""
|
||
|
|
env = {}
|
||
|
|
terminal_config = {"cwd": ".", "env_type": "docker"}
|
||
|
|
defaults = {"terminal": {"cwd": "."}, "_file_has_terminal": False}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "" # cwd popped, no env var set
|
||
|
|
|
||
|
|
def test_remote_backend_with_prior_cwd_preserves(self):
|
||
|
|
"""Remote backend + pre-resolved TERMINAL_CWD → adopted."""
|
||
|
|
env = {"TERMINAL_CWD": "/project"}
|
||
|
|
terminal_config = {"cwd": ".", "env_type": "docker"}
|
||
|
|
defaults = {"terminal": {"cwd": "."}, "_file_has_terminal": False}
|
||
|
|
|
||
|
|
result = _resolve_terminal_cwd(terminal_config, defaults, env)
|
||
|
|
assert result == "/project"
|