Files
hermes-agent/tests/pm/test_installed_package.py
teknium1 92ce6f4760 fix(pm): heal agent-browser entries staged without the exec bit
28edf7c75a made stage() chmod the native agent-browser binary, but
entries staged before it (lazy installs since the pm store landed) stay
0644 forever: every browser_* call fails with PermissionError and the
store never restages because the entry verifies. Restore the bit in
place when the entry is looked up on its own target (modes are not part
of the pinned digest); an entry that cannot be chmodded counts as not
installed so ensure() restages it.
2026-09-28 10:11:33 -07:00

64 lines
2.5 KiB
Python

"""Installed runtime lookup uses the same shipped/addition precedence as ensure."""
from __future__ import annotations
import os
import pytest
import pm
from pm import paths
from pm.install import ensure
from pm.lock import Lockfile
from tests.pm.test_pm_authority import core_env, pm_env, served # noqa: F401
def test_installed_lookup_prefers_current_pin_then_recorded_fallback(pm_env, tmp_path, monkeypatch):
ensure("faketool", explicit=True)
original = pm.installed_package("faketool")
assert original is not None and original.binary.is_file()
lock = Lockfile(pm_env["lockfile_path"])
lock.set_pin("faketool", "2.0", {"any": {
"url": pm_env["base_url"] + "/faketool-2.0.tar.gz", "sha256": "b" * 64,
}})
lock.save()
assert pm.installed_package("faketool") is None
assert pm.installed_package("faketool", allow_outdated=True) == original
shipped = tmp_path / "sealed" / "tools"
shipped.mkdir(parents=True)
monkeypatch.setattr(paths, "store_root", lambda: shipped)
monkeypatch.setattr(paths, "writable_store_root", lambda: pm_env["runtime"])
assert pm.installed_package("faketool", allow_outdated=True) == original
original.binary.unlink()
assert pm.installed_package("faketool", allow_outdated=True) is None
def test_state_fact_in_shared_facts_file_is_not_a_store_install(pm_env):
"""``venv`` is recorded via ``record_state`` (stamp + extras, no entry) into
the same facts.json as tool facts. Reading the composed env over every
registered package must skip it, not KeyError on ``fact["entry"]`` —
that crashed ``activate`` (``pm.environments``) after a sync."""
from pm.install import env_for
from pm.lock import Facts
from pm.registry import all_packages
ensure("faketool", explicit=True)
facts = Facts(paths.facts_path())
facts.record_state("venv", "stamp", ["all"])
assert not facts.installed("venv", None, paths.store_root())
composed = env_for("venv", "faketool", *all_packages())
assert composed == env_for("faketool")
@pytest.mark.skipif(os.name == "nt", reason="POSIX exec bit")
def test_entry_staged_without_exec_bit_is_usable_again(pm_env):
"""agent-browser entries staged before stage() set the exec bit raised PermissionError on every launch."""
ensure("faketool", explicit=True)
binary = pm.installed_package("faketool").binary
binary.chmod(0o644)
healed = pm.installed_package("faketool")
assert healed is not None and healed.binary == binary and os.access(binary, os.X_OK)