Files
hermes-agent/tests/hermes_cli/test_profile_delete_service_name.py
ethernet 16652eea18 Merge remote-tracking branch 'origin/main' into ethie/pm-clean
# Conflicts:
#	gateway/config.py
#	gateway/config_loader.py
#	gateway/readiness.py
#	hermes_cli/managed_scope.py
#	hermes_cli/plugin_python_deps.py
#	hermes_cli/plugins_cmd.py
#	hermes_cli/update_cmd_maint.py
#	plugin-catalog/hindsight.yaml
#	plugins/plugin_loader.py
#	providers/__init__.py
#	scripts/run_tests.sh
#	tests/gateway/test_control_socket_windows_live.py
#	tests/gateway/test_gateway_streaming_nested_config.py
#	tests/hermes_cli/test_doctor.py
#	tests/hermes_cli/test_plan_reconciliation_windows_live.py
#	tests/hermes_cli/test_update_apply_shallow_count.py
#	tests/hermes_cli/test_update_concurrent_quarantine.py
#	tests/hermes_cli/test_update_shim_self_lock.py
#	tests/hermes_cli/test_verify_console_scripts.py
#	tests/tools/test_lazy_deps.py
#	tests/tui_gateway/test_subprocess_encoding.py
#	tools/lazy_deps.py
2026-09-23 15:26:34 -04:00

52 lines
2.3 KiB
Python

"""Deleting a profile from a multiplexed process removes THAT profile's service, never the host's.
A multi-profile dashboard/tui-gateway process has ``set_multiplex_active(True)`` and the launch
home pinned for routed-profile decisions. ``DELETE /api/profiles/<name>`` then runs
``profiles._cleanup_gateway_service`` in that same process, which switches the home to the victim
to resolve ``get_service_name()``. If that switch were invisible to ``get_hermes_home()`` the name
would resolve to the launch home's bare ``hermes-gateway`` and the cleanup would disable, stop and
unlink the HOST multiplexer's own unit.
"""
from __future__ import annotations
from pathlib import Path
import pytest
from agent.secret_scope import set_multiplex_active
from hermes_cli import profiles
@pytest.fixture
def two_homes(tmp_path, monkeypatch):
monkeypatch.setattr(Path, "home", lambda: tmp_path)
launch = tmp_path / ".hermes"
victim = launch / "profiles" / "victim"
victim.mkdir(parents=True)
monkeypatch.setenv("HERMES_HOME", str(launch))
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "xdg"))
unit_dir = tmp_path / "xdg" / "systemd" / "user"
unit_dir.mkdir(parents=True)
host_unit = unit_dir / "hermes-gateway.service"
victim_unit = unit_dir / "hermes-gateway-victim.service"
host_unit.write_text("[Service]\n")
victim_unit.write_text("[Service]\n")
return launch, victim, host_unit, victim_unit
@pytest.mark.platforms("linux")
def test_delete_from_a_pinned_multiplexer_targets_the_victims_unit_only(two_homes, monkeypatch):
launch, victim, host_unit, victim_unit = two_homes
calls: list[list[str]] = []
monkeypatch.setattr(profiles.subprocess, "run", lambda cmd, **kw: calls.append(list(cmd)))
set_multiplex_active(True) # the dashboard has served a second profile: launch home pinned
profiles._cleanup_gateway_service("victim", victim)
assert not victim_unit.exists()
assert host_unit.exists(), "the host multiplexer's own unit must survive a profile delete"
assert ["systemctl", "--user", "disable", "hermes-gateway-victim"] in calls
assert not any(c[:3] == ["systemctl", "--user", "disable"] and c[3] == "hermes-gateway" for c in calls)
# The caller's process home is restored: the process still is the launch profile afterwards.
assert profiles.os.environ["HERMES_HOME"] == str(launch)