mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-24 11:38:29 +00:00
test(lazy-deps): make durable-target tests network-free
CI test shard has no PyPI egress: the real 'pip install packaging==20.9' in test_core_package_is_not_shadowed failed (the pypi.org reachability probe passed but the actual install didn't), failing slice 2/6. - Prove the anti-shadow invariant deterministically: synthesize a fake 'packaging' in the durable target with a sentinel and assert the import still resolves to the core copy (TestCoreNeverShadowed). No network. - Cover the install wire offline: stub subprocess and assert --target + --constraint are built in durable mode and absent in venv-scoped mode (TestInstallArgConstruction). - Gate the genuine PyPI install behind HERMES_RUN_NETWORK_TESTS=1 (opt-in, skipped in CI) instead of a flaky reachability probe that doesn't predict install success.
This commit is contained in:
@@ -175,28 +175,75 @@ class TestSysPathAppend:
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# E2E: a REAL install into a durable target cannot shadow core.
|
||||
# Install path: arg construction (network-free) + a real install (opt-in).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _network_available() -> bool:
|
||||
try:
|
||||
import urllib.request
|
||||
urllib.request.urlopen("https://pypi.org/simple/", timeout=5)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
class TestInstallArgConstruction:
|
||||
"""Verify the durable-target install builds the right pip/uv command
|
||||
WITHOUT hitting the network, by stubbing the subprocess layer. This is
|
||||
the CI-safe coverage of the install path; the genuine PyPI install below
|
||||
is opt-in only."""
|
||||
|
||||
def test_target_and_constraint_args_passed(self, tmp_path, monkeypatch):
|
||||
target = tmp_path / "lazy-packages"
|
||||
monkeypatch.setenv(ld._LAZY_TARGET_ENV, str(target))
|
||||
# No uv on PATH → force the pip tier so we assert one known command.
|
||||
monkeypatch.setattr(ld.shutil, "which", lambda _: None)
|
||||
|
||||
captured = {}
|
||||
|
||||
def fake_run(cmd, *a, **k):
|
||||
# The pip --version probe must look healthy so we reach install.
|
||||
if "--version" in cmd:
|
||||
return subprocess.CompletedProcess(cmd, 0, "pip 24.0", "")
|
||||
captured["cmd"] = cmd
|
||||
return subprocess.CompletedProcess(cmd, 0, "ok", "")
|
||||
|
||||
monkeypatch.setattr(ld.subprocess, "run", fake_run)
|
||||
# Avoid mutating the real interpreter's sys.path on success.
|
||||
monkeypatch.setattr(ld, "_activate_target_on_syspath", lambda _t: None)
|
||||
|
||||
result = ld._venv_pip_install(("somepkg==1.2.3",))
|
||||
assert result.success
|
||||
cmd = captured["cmd"]
|
||||
# --target points at the durable dir...
|
||||
assert "--target" in cmd
|
||||
assert str(target) in cmd
|
||||
# ...a --constraint file pins shared deps to core...
|
||||
assert "--constraint" in cmd
|
||||
# ...and the spec is last.
|
||||
assert cmd[-1] == "somepkg==1.2.3"
|
||||
|
||||
def test_no_target_args_in_venv_scoped_mode(self, monkeypatch):
|
||||
# Env unset → plain venv-scoped install, no --target / --constraint.
|
||||
monkeypatch.delenv(ld._LAZY_TARGET_ENV, raising=False)
|
||||
monkeypatch.setattr(ld.shutil, "which", lambda _: None)
|
||||
captured = {}
|
||||
|
||||
def fake_run(cmd, *a, **k):
|
||||
if "--version" in cmd:
|
||||
return subprocess.CompletedProcess(cmd, 0, "pip 24.0", "")
|
||||
captured["cmd"] = cmd
|
||||
return subprocess.CompletedProcess(cmd, 0, "ok", "")
|
||||
|
||||
monkeypatch.setattr(ld.subprocess, "run", fake_run)
|
||||
result = ld._venv_pip_install(("somepkg==1.2.3",))
|
||||
assert result.success
|
||||
assert "--target" not in captured["cmd"]
|
||||
assert "--constraint" not in captured["cmd"]
|
||||
|
||||
|
||||
@pytest.mark.skipif(not _network_available(), reason="needs PyPI network access")
|
||||
@pytest.mark.skipif(
|
||||
os.environ.get("HERMES_RUN_NETWORK_TESTS") != "1",
|
||||
reason="opt-in real-install test (set HERMES_RUN_NETWORK_TESTS=1); CI runs "
|
||||
"the network-free arg-construction + synthetic-shadow tests instead",
|
||||
)
|
||||
class TestRealInstallCoreWins:
|
||||
"""Install a real package into a durable target and prove:
|
||||
|
||||
1. It lands in the target dir, NOT the core venv.
|
||||
2. It is importable via the appended sys.path entry.
|
||||
3. A package name that ALSO exists in core resolves to the CORE copy,
|
||||
never the durable-store copy (the structural anti-shadow guarantee).
|
||||
"""
|
||||
"""Genuine PyPI install into a durable target (opt-in). Proves the wire
|
||||
end to end: the package lands in the target, not the core venv, and is
|
||||
importable via the appended sys.path entry. Skipped by default so the
|
||||
unit-test shard never depends on PyPI reachability/egress."""
|
||||
|
||||
def test_install_lands_in_target_and_imports(self, tmp_path, monkeypatch):
|
||||
target = tmp_path / "lazy-packages"
|
||||
@@ -215,46 +262,51 @@ class TestRealInstallCoreWins:
|
||||
assert mod.__file__ is not None
|
||||
assert Path(mod.__file__).is_relative_to(target)
|
||||
|
||||
def test_core_package_is_not_shadowed(self, tmp_path, monkeypatch):
|
||||
"""Force-install an OLD version of a package the core already ships
|
||||
into the durable target, then assert the running interpreter still
|
||||
imports the CORE version — proving append-ordering protects core.
|
||||
|
||||
We use 'packaging', which is always present in the venv (transitive
|
||||
of pip/build tooling). We install a deliberately old pin into the
|
||||
target and check the resolved module path + version is core's.
|
||||
"""
|
||||
import packaging # core copy
|
||||
core_path = Path(packaging.__file__).parent
|
||||
core_version = __import__("importlib.metadata", fromlist=["version"]).version(
|
||||
"packaging"
|
||||
)
|
||||
class TestCoreNeverShadowed:
|
||||
"""The headline invariant — a package in the durable store can never
|
||||
shadow a core module — proved WITHOUT a network install by synthesizing
|
||||
a shadow copy of a core package directly on disk in the target. This is
|
||||
deterministic (no PyPI) and a stronger check: we control exactly what
|
||||
the shadow contains, so a sentinel attribute proves which copy won.
|
||||
"""
|
||||
|
||||
def test_synthetic_shadow_does_not_win(self, tmp_path, monkeypatch):
|
||||
# 'packaging' is always present in the venv (transitive of the build
|
||||
# toolchain). Resolve the core copy's location first.
|
||||
import importlib.util
|
||||
core_spec = importlib.util.find_spec("packaging")
|
||||
assert core_spec is not None and core_spec.origin
|
||||
core_path = Path(core_spec.origin).parent
|
||||
|
||||
# Plant a fake 'packaging' in the durable target with a sentinel that
|
||||
# the real core copy does NOT have.
|
||||
target = tmp_path / "lazy-packages"
|
||||
monkeypatch.setenv(ld._LAZY_TARGET_ENV, str(target))
|
||||
# Install an old packaging into the target WITHOUT the core
|
||||
# constraints file (bypass the tidy resolver) so a shadow copy
|
||||
# genuinely exists on disk in the target — the worst case.
|
||||
ld._ensure_target_ready(target)
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "pip", "install", "--target", str(target),
|
||||
"--no-deps", "packaging==20.9"],
|
||||
check=True, capture_output=True, text=True,
|
||||
shadow_pkg = target / "packaging"
|
||||
shadow_pkg.mkdir()
|
||||
(shadow_pkg / "__init__.py").write_text(
|
||||
"SHADOW_SENTINEL = True\n__version__ = '0.0.0-shadow'\n"
|
||||
)
|
||||
assert list(target.glob("packaging*")), "shadow copy should exist on disk"
|
||||
assert (shadow_pkg / "__init__.py").exists(), "shadow copy must exist on disk"
|
||||
|
||||
# Activate the target (append) and re-resolve.
|
||||
ld._activate_target_on_syspath(target)
|
||||
import importlib
|
||||
importlib.invalidate_caches()
|
||||
importlib.reload(packaging)
|
||||
# Core path + version must still win.
|
||||
assert Path(packaging.__file__).parent == core_path, (
|
||||
"durable-store copy shadowed the core module — append ordering broke"
|
||||
)
|
||||
new_version = __import__("importlib.metadata", fromlist=["version"]).version(
|
||||
"packaging"
|
||||
)
|
||||
assert new_version == core_version, (
|
||||
f"metadata resolved to shadow version {new_version}, expected core {core_version}"
|
||||
)
|
||||
# Activate the target (append-only) and re-resolve the import.
|
||||
saved = list(sys.path)
|
||||
try:
|
||||
ld._activate_target_on_syspath(target)
|
||||
import importlib
|
||||
importlib.invalidate_caches()
|
||||
spec_after = importlib.util.find_spec("packaging")
|
||||
assert spec_after is not None and spec_after.origin
|
||||
resolved = Path(spec_after.origin).parent
|
||||
# Core path must still win; the shadow in the target is ignored.
|
||||
assert resolved == core_path, (
|
||||
f"durable-store copy shadowed core: resolved to {resolved}, "
|
||||
f"expected core at {core_path}"
|
||||
)
|
||||
assert resolved != shadow_pkg, "import resolved to the shadow copy"
|
||||
finally:
|
||||
sys.path[:] = saved
|
||||
sys.modules.pop("packaging", None)
|
||||
importlib.invalidate_caches()
|
||||
|
||||
Reference in New Issue
Block a user