- pm.environment owns _RESOLVER_MARKERS: the streaming uv runner imported
pm.workspace, whose tomllib import fails on the 3.10 system python that
bootstraps the Docker arm64 image (No module named 'tomllib'). Invariant test
proves runtime staging needs neither tomllib nor pm.workspace.
- run_tests.sh forwards the MSVC/SDK/Rust/OpenSSL toolchain variables through
its env -i scrub so PM tests that compile ruamel-yaml-clib on Windows arm64
find cl.exe (previously 'Visual C++ 14.0 or greater is required').
- nix desktop-backend check: the spawned backend outlives cage's process group
and kept writing under the temp HERMES_HOME during rmtree; stop every
process bound to the throwaway HOME before cleanup.
- windows: test_launcher_runtime_selection imports runtime_state from
hermes_cli (moved in bbec973514); the ' spaced ' suffix row loses its
trailing space on win32 (the filesystem strips it).
- macOS: test_sealed_worker_command copies the interpreter into the payload
(the escape guard resolves symlinks) and links the host lib tree.
102 lines
4.2 KiB
Python
102 lines
4.2 KiB
Python
"""Default-root isolation through the real Python resolution chain."""
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
|
|
# Win32 strips a trailing space from every path component, so the literal-suffix contract is
|
|
# only checkable with the leading space there.
|
|
_SPACED = " spaced" if sys.platform == "win32" else " spaced "
|
|
|
|
|
|
@pytest.mark.platforms("linux", "macos", "windows")
|
|
@pytest.mark.parametrize("suffix", ["", "-asdfasdf", "magic-test", _SPACED])
|
|
def test_suffix_scopes_default_home_and_profiles(tmp_path, suffix):
|
|
env = dict(os.environ)
|
|
env.pop("HERMES_HOME", None)
|
|
env.update(
|
|
HOME=str(tmp_path), USERPROFILE=str(tmp_path),
|
|
LOCALAPPDATA=str(tmp_path / "AppData" / "Local"),
|
|
HERMES_DATA_DIR_SUFFIX=suffix,
|
|
)
|
|
script = """
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
from hermes_constants import get_hermes_home, get_process_hermes_home, get_default_hermes_root
|
|
from hermes_cli.profiles import _get_profiles_root, _get_active_profile_path, resolve_profile_env
|
|
root = get_default_hermes_root()
|
|
profile = root / 'profiles' / 'coder'
|
|
profile.mkdir(parents=True)
|
|
(profile / 'config.yaml').write_text('', encoding='utf-8')
|
|
result = [str(get_hermes_home()), str(get_process_hermes_home()), str(root),
|
|
str(_get_profiles_root()), str(_get_active_profile_path()), resolve_profile_env('coder')]
|
|
os.environ['HERMES_HOME'] = str(profile)
|
|
result.extend([str(get_hermes_home()), str(get_default_hermes_root())])
|
|
os.environ.pop('HERMES_HOME')
|
|
os.environ['HERMES_DATA_DIR_SUFFIX'] += '-changed'
|
|
result.append(str(get_default_hermes_root()))
|
|
print(json.dumps(result))
|
|
"""
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", script], env=env,
|
|
cwd=Path(__file__).resolve().parents[2],
|
|
text=True, capture_output=True,
|
|
)
|
|
assert result.returncode == 0, result.stderr
|
|
base = tmp_path / "AppData" / "Local" / "hermes" if sys.platform == "win32" else tmp_path / ".hermes"
|
|
root = Path(str(base) + suffix)
|
|
profile = root / "profiles" / "coder"
|
|
assert json.loads(result.stdout) == list(map(str, [
|
|
root, root, root, root / "profiles", root / "active_profile", profile,
|
|
profile, root, Path(str(root) + "-changed"),
|
|
]))
|
|
|
|
|
|
@pytest.mark.platforms("linux", "macos", "windows")
|
|
def test_startup_readers_use_the_suffixed_home(tmp_path, monkeypatch):
|
|
from hermes_constants import get_process_hermes_home
|
|
from hermes_cli.dashboard_procs import _hermes_home_dir
|
|
from hermes_cli.env_loader import load_hermes_dotenv
|
|
from hermes_startup_watchdog import get_startup_watchdog_dump_path
|
|
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "AppData" / "Local"))
|
|
monkeypatch.delenv("HERMES_HOME", raising=False)
|
|
monkeypatch.setenv("HERMES_DATA_DIR_SUFFIX", "magic-test")
|
|
monkeypatch.delenv("SUFFIX_TEST_CREDENTIAL", raising=False)
|
|
home = get_process_hermes_home()
|
|
home.mkdir(parents=True)
|
|
(home / ".env").write_text("SUFFIX_TEST_CREDENTIAL=suffixed\n", encoding="utf-8")
|
|
|
|
load_hermes_dotenv(project_env=tmp_path / "absent.env", load_external_secrets=False)
|
|
assert os.environ.get("SUFFIX_TEST_CREDENTIAL") == "suffixed"
|
|
assert _hermes_home_dir() == home
|
|
assert get_startup_watchdog_dump_path() == home / "logs" / "gateway-startup-watchdog.log"
|
|
|
|
|
|
def test_suffix_does_not_change_explicit_or_context_home(tmp_path, monkeypatch):
|
|
from hermes_constants import (
|
|
get_default_hermes_root, get_hermes_home, get_process_hermes_home,
|
|
reset_hermes_home_override, set_hermes_home_override,
|
|
)
|
|
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "AppData" / "Local"))
|
|
explicit = tmp_path / "explicit"
|
|
scoped = tmp_path / "scoped"
|
|
monkeypatch.setenv("HERMES_HOME", str(explicit))
|
|
monkeypatch.setenv("HERMES_DATA_DIR_SUFFIX", "magic-test")
|
|
assert get_hermes_home() == get_process_hermes_home() == get_default_hermes_root() == explicit
|
|
token = set_hermes_home_override(scoped)
|
|
try:
|
|
assert get_hermes_home() == scoped
|
|
assert get_process_hermes_home() == get_default_hermes_root() == explicit
|
|
finally:
|
|
reset_hermes_home_override(token)
|