hermes-agent/tests/hermes_cli/test_runtime_tree.py

105 lines
4.1 KiB
Python

"""Tests for hermes_cli/runtime_tree.py — tree classification and channel."""
import json
from pathlib import Path
from hermes_cli.runtime_tree import (
CHANNEL_MAIN,
CHANNEL_STABLE,
STEWARD_UPDATE_MESSAGES,
GitCheckout,
Sealed,
is_managed_install_root,
resolve_update_channel,
runtime_tree,
steward_update_message,
)
class TestRuntimeTree:
def test_a_tree_with_git_is_a_checkout(self, tmp_path):
(tmp_path / ".git").mkdir()
tree = runtime_tree(tmp_path)
assert isinstance(tree, GitCheckout)
assert tree.root == tmp_path
def test_a_worktree_gitfile_also_counts(self, tmp_path):
# Linked worktrees and submodules have a .git FILE, not a directory.
(tmp_path / ".git").write_text("gitdir: /somewhere/else\n")
assert isinstance(runtime_tree(tmp_path), GitCheckout)
def test_a_gitless_tree_is_sealed_with_the_stamped_steward(self, tmp_path):
(tmp_path / "install-stamp.json").write_text(
json.dumps({"commit": "a" * 40, "distribution": "desktop-app"})
)
tree = runtime_tree(tmp_path)
assert isinstance(tree, Sealed)
assert tree.steward == "desktop-app"
def test_a_gitless_tree_without_a_stamp_is_sealed_unknown(self, tmp_path):
tree = runtime_tree(tmp_path)
assert isinstance(tree, Sealed)
assert tree.steward == "unknown"
def test_a_corrupt_stamp_degrades_to_unknown(self, tmp_path):
(tmp_path / "install-stamp.json").write_text("{not json")
tree = runtime_tree(tmp_path)
assert isinstance(tree, Sealed)
assert tree.steward == "unknown"
class TestStewardMessages:
def test_every_known_steward_names_its_mechanism(self):
assert "--eject" in steward_update_message("desktop-app")
assert "docker pull" in steward_update_message("docker")
assert "flake" in steward_update_message("nix")
def test_an_unknown_steward_gets_the_fallback_with_its_name(self):
message = steward_update_message("pacman")
assert "pacman" in message
assert "cannot update" in message
def test_every_table_entry_is_a_refusal(self):
for steward, message in STEWARD_UPDATE_MESSAGES.items():
assert message.startswith("\u2717"), steward
class TestManagedInstallRoot:
def test_hermes_home_checkout_is_managed(self, tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
root = tmp_path / ".hermes" / "hermes-agent"
root.mkdir(parents=True)
assert is_managed_install_root(root) is True
def test_a_dev_tree_is_not_managed(self, tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
dev = tmp_path / "src" / "hermes-agent"
dev.mkdir(parents=True)
assert is_managed_install_root(dev) is False
def test_the_fhs_root_layout_is_managed(self):
# /usr/local/lib/hermes-agent need not exist for the answer; the
# comparison is by path. If it does not resolve, False is safe.
result = is_managed_install_root(Path("/usr/local/lib/hermes-agent"))
assert result in (True, False) # never raises
# On machines without the dir, resolve() still succeeds (no symlinks
# involved), so the comparison holds.
assert result is True
class TestResolveUpdateChannel:
def test_stable_from_config(self):
assert resolve_update_channel({"update": {"channel": "stable"}}) == CHANNEL_STABLE
def test_main_is_the_default(self):
assert resolve_update_channel(None) == CHANNEL_MAIN
assert resolve_update_channel({}) == CHANNEL_MAIN
assert resolve_update_channel({"update": {}}) == CHANNEL_MAIN
def test_auto_and_unknown_mean_main(self):
assert resolve_update_channel({"update": {"channel": "auto"}}) == CHANNEL_MAIN
assert resolve_update_channel({"update": {"channel": "nightly"}}) == CHANNEL_MAIN
def test_case_and_whitespace_are_forgiven(self):
assert resolve_update_channel({"update": {"channel": " Stable "}}) == CHANNEL_STABLE