Files
hermes-agent/tests/pm/test_bootstrap_import_closure.py
2026-10-10 15:20:13 +02:00

86 lines
3.5 KiB
Python

"""The tool-only build stage imports PM without third-party dependencies."""
import os
from pathlib import Path
import shutil
import subprocess
import sys
import pytest
def test_minimal_bootstrap_closure_reaches_pm_paths_and_locks(tmp_path):
repo = Path(__file__).resolve().parents[2]
stage = tmp_path / "stage"
shutil.copytree(repo / "pm", stage / "pm", ignore=shutil.ignore_patterns("__pycache__"))
shutil.copy2(repo / "hermes_constants.py", stage / "hermes_constants.py")
(stage / "hermes_cli").mkdir()
for name in ("__init__.py", "runtime_state.py"):
shutil.copy2(repo / "hermes_cli" / name, stage / "hermes_cli" / name)
store = stage / "tools"
env = dict(os.environ, HERMES_HOME=str(tmp_path / "home"),
HERMES_RUNTIME_DIR=str(store), PYTHONPATH=str(stage))
script = """
from pathlib import Path
import pm.paths
from pm.store import Store
from pm.lock import Facts
root = pm.paths.store_root()
with Store(root).install_lock():
facts = Facts(root / 'facts.json')
facts.record_state('probe', 'checked', [])
assert facts.path.is_file()
print(root)
"""
result = subprocess.run([sys.executable, "-S", "-c", script], cwd=stage, env=env,
capture_output=True, text=True, timeout=15, check=False)
assert result.returncode == 0, result.stdout + result.stderr
assert Path(result.stdout.strip()) == store
def test_managed_python_signing_import_needs_no_pm_or_application(tmp_path):
repo = Path(__file__).resolve().parents[2]
script = """
import sys
class NoApplication:
def find_spec(self, fullname, path=None, target=None):
if fullname == 'pm' or fullname == 'utils' or fullname.startswith(('pm.', 'agent.')):
raise AssertionError('signing imported ' + fullname)
sys.meta_path.insert(0, NoApplication())
from hermes_cli.macos_signing import sign_managed_python
assert callable(sign_managed_python)
"""
result = subprocess.run([sys.executable, "-S", "-c", script], cwd=repo,
env=dict(os.environ, HERMES_HOME=str(tmp_path / "home")),
capture_output=True, text=True, timeout=15, check=False)
assert result.returncode == 0, result.stderr
@pytest.mark.platforms("linux", "macos", "windows")
def test_runtime_staging_streams_uv_output_without_tomllib(tmp_path):
"""Bootstrap runs before PM selects its Python: Docker has 3.10 and
historical Windows updaters have 3.11, without os.set_blocking for pipes.
"""
repo = Path(__file__).resolve().parents[2]
script = """
import os
import sys
if sys.platform == 'win32' and hasattr(os, 'set_blocking'):
del os.set_blocking
class NoTomllib:
def find_spec(self, fullname, path=None, target=None):
if fullname in ('tomllib', 'pm.workspace', 'pm.plugin_declarations'):
raise AssertionError('runtime staging imported ' + fullname)
sys.meta_path.insert(0, NoTomllib())
import pm.runtime_stage
from pm.environment import _run_streaming
import subprocess
result = _run_streaming([sys.executable, '-c', 'print(\"no solution found\")'],
cwd='.', env={}, timeout=30, output=sys.stderr)
assert result.returncode == 0, result
"""
result = subprocess.run([sys.executable, "-S", "-c", script], cwd=repo,
env=dict(os.environ, HERMES_HOME=str(tmp_path / "home")),
capture_output=True, text=True, timeout=60, check=False)
assert result.returncode == 0, result.stdout + result.stderr