Restored (OS fakes replaced by windows_only/macos_only markers): - test_update_shim_self_lock.py: venv/.venv scripts dir lookup (#79542, all OSes); Windows shim detection (argv0, zipapp, ancestor chain, foreign install ignored), re-exec hand-off under venv python without recursion or on spawn failure, dependency-sync guard (shim-only vs native lock). - test_update_concurrent_quarantine.py: concurrent-parent detection robust to one bad hop and excludes launcher/self (#29341, #34795); quarantine success/unbreakable lock; Windows gateway pause/resume, service rollback and retryable resume failures, abort on indeterminate discovery; venv launcher ancestor detection; concurrent gate gateway-only skip vs non-gateway abort; refusal to tree-kill the gateway ancestor (#98814). - test_update_apply_shallow_count.py (recreated): real _prepare_checkout_for_update on full vs depth-1 clones — shallow behind-count recovered via compare API, unknown offline, never bogus (#53479, #86257). - test_lazy_refresh_venv_repair.py: venv repair reinstalls lazy/tool snapshots through an isolated uv env (#83914). - test_verify_console_scripts.py (recreated, windows_only): missing hermes.exe triggers reinstall; still-missing shim reported, no reinstall when all present (#52931). - test_macos_fda_guidance.py (recreated): doctor/setup Full Disk Access guidance granted/denied/indeterminate, silent off macOS (#52010).
100 lines
3.4 KiB
Python
100 lines
3.4 KiB
Python
"""Post-install console-script verification on Windows (issue #52931).
|
|
|
|
``uv pip install -e .`` can record ``hermes.exe`` in the wheel RECORD while the
|
|
file never lands, so ``hermes`` drops off PATH after a "successful" install.
|
|
``_verify_console_scripts_installed`` must notice the missing shim and repair it
|
|
with ``--reinstall -e .`` under quarantine. The check is gated on the real host,
|
|
so these tests run on the Windows lane.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import textwrap
|
|
|
|
import pytest
|
|
|
|
from hermes_cli import main_install_repair
|
|
|
|
pytestmark = pytest.mark.windows_only
|
|
|
|
_SCRIPTS = ("hermes", "hermes-agent", "hermes-acp")
|
|
|
|
|
|
@pytest.fixture
|
|
def scripts_dir(tmp_path, monkeypatch):
|
|
"""A project with three declared console scripts and an empty venv Scripts dir."""
|
|
(tmp_path / "pyproject.toml").write_text(
|
|
textwrap.dedent(
|
|
"""\
|
|
[project]
|
|
name = "fake"
|
|
version = "0.0.0"
|
|
|
|
[project.scripts]
|
|
hermes = "hermes_cli.main:main"
|
|
hermes-agent = "run_agent:main"
|
|
hermes-acp = "acp_adapter.entry:main"
|
|
"""
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
import hermes_cli.main as main_mod
|
|
|
|
monkeypatch.setattr(main_mod, "PROJECT_ROOT", tmp_path)
|
|
scripts = tmp_path / "venv" / "Scripts"
|
|
scripts.mkdir(parents=True)
|
|
monkeypatch.setattr(main_install_repair, "_venv_scripts_dir", lambda: scripts)
|
|
return scripts
|
|
|
|
|
|
def _record_installs(monkeypatch, *, lands: tuple[str, ...] = ()):
|
|
"""Replace the quarantined uv install; it writes the *lands* shims like a real repair."""
|
|
calls = []
|
|
|
|
def fake_install(cmd, *, env=None, scripts_dir=None, **_kwargs):
|
|
calls.append((list(cmd), scripts_dir))
|
|
assert scripts_dir is not None
|
|
for name in lands:
|
|
(scripts_dir / f"{name}.exe").write_bytes(b"shim")
|
|
|
|
monkeypatch.setattr(main_install_repair, "_run_quarantined_install", fake_install)
|
|
return calls
|
|
|
|
|
|
def test_missing_hermes_exe_is_reinstalled(scripts_dir, monkeypatch, capsys):
|
|
"""The #52931 shape: hermes-agent/hermes-acp landed, hermes.exe did not."""
|
|
for name in ("hermes-agent", "hermes-acp"):
|
|
(scripts_dir / f"{name}.exe").write_bytes(b"shim")
|
|
calls = _record_installs(monkeypatch, lands=("hermes",))
|
|
|
|
main_install_repair._verify_console_scripts_installed(["uv", "pip"], env={})
|
|
|
|
assert calls == [(["uv", "pip", "install", "--reinstall", "-e", "."], scripts_dir)]
|
|
assert (scripts_dir / "hermes.exe").is_file()
|
|
out = capsys.readouterr().out
|
|
assert "hermes" in out and "missing" in out
|
|
assert "Still missing" not in out
|
|
|
|
|
|
def test_repair_that_still_leaves_a_shim_missing_is_reported(scripts_dir, monkeypatch, capsys):
|
|
"""A reinstall that again fails to land the shim must not claim success."""
|
|
for name in ("hermes-agent", "hermes-acp"):
|
|
(scripts_dir / f"{name}.exe").write_bytes(b"shim")
|
|
_record_installs(monkeypatch)
|
|
|
|
main_install_repair._verify_console_scripts_installed(["uv", "pip"], env={})
|
|
|
|
out = capsys.readouterr().out
|
|
assert "Still missing after repair: hermes" in out
|
|
assert "python -m hermes_cli.main" in out
|
|
|
|
|
|
def test_no_reinstall_when_every_shim_is_present(scripts_dir, monkeypatch):
|
|
for name in _SCRIPTS:
|
|
(scripts_dir / f"{name}.exe").write_bytes(b"shim")
|
|
calls = _record_installs(monkeypatch)
|
|
|
|
main_install_repair._verify_console_scripts_installed(["uv", "pip"], env={})
|
|
|
|
assert calls == []
|