Files
hermes-agent/tests/scripts/test_write_install_stamp.py
ethernet 6a6771e5e7 termux: stamp the deb as a self-contained runtime, not a bundled payload
build_deb.sh wrote HERMES_DESKTOP_VARIANT=bundled, so the Termux stamp
carried payload=bundled and every 'bundled' reader treated the tree as
the repo/ of an Electron payload. hermes uninstall --data then called
resolve_bundle_layout on it and rejected the plan: the deb has no
enclosing app to protect, so data-only removal was impossible on Termux.

Add a 'runtime' variant to write_install_stamp.py for a sealed CLI
runtime with no desktop app around it. It stays sealed for the update
gate and channel identity (source_check, update_channel accept it next
to bundled/light) while is_bundled_payload keeps answering False, so
cleanup planning protects the APT-owned package tree the ordinary way
and never asks where the app is.
2026-09-21 18:37:21 -04:00

78 lines
3.8 KiB
Python

"""The emitted stamp must preserve build identity and reach the runtime reader."""
import json
import os
from pathlib import Path
import subprocess
import sys
import pytest
@pytest.mark.parametrize("variant,distribution,mechanism,payload,tag", [
("", None, "self", "bootstrap", None),
("bootstrap", "docker", "external", "bootstrap", None),
("bundled", "desktop-app", "electron-updater", "bundled", "v0.18.0"),
("bundled", "desktop-app", "app-installer", "bundled", "v0.18.0"),
("bundled", "desktop-app", "microsoft-store", "bundled", "v0.18.0"),
("bundled", "desktop-app", "external", "bundled", "v0.18.0"),
("light", "desktop-app", "electron-updater", "light", "v0.18.0"),
("runtime", "apt-termux", "external", "runtime", "v0.18.0"),
])
def test_cli_stamp_roundtrip(tmp_path, monkeypatch, variant, distribution, mechanism, payload, tag):
out = tmp_path / "install-stamp.json"
script = Path(__file__).resolve().parents[2] / "scripts/write_install_stamp.py"
env = {**os.environ, "HERMES_DESKTOP_VARIANT": variant, "HERMES_PAYLOAD_TAG": "v0.18.0", "HERMES_BUILD_COMMIT": ""}
args = [sys.executable, str(script), "--output", str(out), "--commit", "d" * 40,
"--source", "ci", "--update-mechanism", mechanism]
if distribution:
args += ["--distribution", distribution]
result = subprocess.run(args, env=env, capture_output=True, text=True, timeout=30)
assert result.returncode == 0, result.stderr
data = json.loads(out.read_text(encoding="utf-8-sig"))
assert {key: data[key] for key in ("source", "distribution", "updateMechanism", "payload", "tag", "commit")} == {
"source": "ci", "distribution": distribution, "updateMechanism": mechanism,
"payload": payload, "tag": tag, "commit": "d" * 40}
from hermes_cli.version_info import _stamp_version_info
from hermes_cli.venv_sync import _is_sealed
monkeypatch.setenv("HERMES_INSTALL_ROOT", str(tmp_path))
if payload == "light":
with pytest.raises(RuntimeError, match="light"):
_stamp_version_info()
else:
info = _stamp_version_info()
assert info is not None and info.commit == "d" * 40
assert _is_sealed(tmp_path)
(tmp_path / ".git").mkdir()
assert not _is_sealed(tmp_path), "a stamped source checkout is not sealed"
@pytest.mark.parametrize("arguments", [[], ["--update-mechanism", "carrier-pigeon"]])
def test_missing_or_invalid_mechanism_cannot_emit_stamp(tmp_path, arguments):
from scripts.write_install_stamp import build_stamp
out = tmp_path / "install-stamp.json"
result = subprocess.run(
[sys.executable, str(Path(__file__).resolve().parents[2] / "scripts/write_install_stamp.py"),
"--output", str(out), "--commit", "a" * 40, *arguments],
capture_output=True, text=True, timeout=30,
)
assert result.returncode != 0 and "--update-mechanism" in result.stderr
assert not out.exists()
with pytest.raises(SystemExit, match="invalid --update-mechanism"):
build_stamp(commit="a" * 40, update_mechanism=arguments[-1] if arguments else "")
@pytest.mark.parametrize("variant,tag,error", [
("bundled", "", "HERMES_PAYLOAD_TAG"), ("light", "", "HERMES_PAYLOAD_TAG"),
("chonky", "v0.18.0", "unknown HERMES_DESKTOP_VARIANT"),
])
def test_invalid_variant_cannot_emit_stamp(tmp_path, variant, tag, error):
out = tmp_path / "install-stamp.json"
result = subprocess.run(
[sys.executable, str(Path(__file__).resolve().parents[2] / "scripts/write_install_stamp.py"),
"--output", str(out), "--commit", "d" * 40, "--update-mechanism", "self"],
env={**os.environ, "HERMES_DESKTOP_VARIANT": variant, "HERMES_PAYLOAD_TAG": tag, "HERMES_BUILD_COMMIT": ""},
capture_output=True, text=True, timeout=30)
assert result.returncode != 0 and error in result.stderr
assert not out.exists()