127 lines
4.9 KiB
Python
127 lines
4.9 KiB
Python
"""C-2 — Remove unused .cache/multi-agent-mux-monitor state directory creation.
|
|
|
|
Verifies:
|
|
Y-1: --dry-run does not create .cache/multi-agent-mux-monitor
|
|
Y-2: --once --emit-diff does not create .cache/multi-agent-mux-monitor
|
|
Y-3: AGENT_SESSIONS_STATE_DIR does not create custom path or default path
|
|
Y-4: Reconcile executes normally and outputs valid drift JSON
|
|
Y-5: Existing pre-created .cache directory/files are unmolested during runtime
|
|
Y-6: Setting AGENT_SESSIONS_STATE_DIR emits deprecation warning on stderr without polluting stdout JSON
|
|
Y-7: Unset AGENT_SESSIONS_STATE_DIR is completely silent on stderr
|
|
Y-8: Empty .cache parent directory is reclaimed during uninstall
|
|
Y-9: Non-empty .cache directory is preserved during uninstall
|
|
Y-10: deploy/remove.sh correctly employs relative rmdir .cache
|
|
"""
|
|
import os
|
|
import subprocess
|
|
import shutil
|
|
import json
|
|
import pytest
|
|
|
|
def _run_reconcile(sandbox, extra_args=None, extra_env=None):
|
|
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
sandbox_agents = sandbox / ".agents"
|
|
if not sandbox_agents.exists():
|
|
os.symlink(os.path.join(repo_root, ".agents"), sandbox_agents, target_is_directory=True)
|
|
|
|
mam_dir = sandbox / ".mam"
|
|
mam_dir.mkdir(exist_ok=True)
|
|
yaml_file = mam_dir / "agent-sessions.yaml"
|
|
if not yaml_file.exists():
|
|
yaml_file.write_text("herdr_sessions: []\n")
|
|
|
|
env = dict(os.environ)
|
|
env["WORKSPACE_ROOT"] = str(sandbox)
|
|
if extra_env:
|
|
env.update(extra_env)
|
|
|
|
reconcile_script = os.path.join(repo_root, ".agents", "skills", "multi-agent-mux-monitor", "scripts", "reconcile.sh")
|
|
cmd = ["bash", reconcile_script]
|
|
if extra_args:
|
|
cmd.extend(extra_args)
|
|
|
|
return subprocess.run(cmd, capture_output=True, text=True, cwd=str(sandbox), env=env)
|
|
|
|
|
|
def test_y1_y2_no_cache_dir_created(mam_sandbox):
|
|
cache_dir = mam_sandbox / ".cache"
|
|
if cache_dir.exists():
|
|
shutil.rmtree(cache_dir)
|
|
|
|
# Y-1: dry-run
|
|
res_dry = _run_reconcile(mam_sandbox, ["--once", "--emit-diff", "--dry-run"])
|
|
assert res_dry.returncode == 0
|
|
assert not (mam_sandbox / ".cache" / "multi-agent-mux-monitor").exists()
|
|
assert not (mam_sandbox / ".cache").exists()
|
|
|
|
# Y-2: change pass
|
|
res_once = _run_reconcile(mam_sandbox, ["--once", "--emit-diff"])
|
|
assert res_once.returncode == 0
|
|
assert not (mam_sandbox / ".cache" / "multi-agent-mux-monitor").exists()
|
|
|
|
|
|
def test_y3_y6_y7_agent_sessions_state_dir_deprecation(mam_sandbox):
|
|
custom_dir = mam_sandbox / "custom_state_dir"
|
|
|
|
# Y-6: Set env var -> notice on stderr, stdout is valid JSON, no dir created
|
|
res_env = _run_reconcile(mam_sandbox, ["--once", "--emit-diff", "--dry-run"],
|
|
extra_env={"AGENT_SESSIONS_STATE_DIR": str(custom_dir)})
|
|
assert res_env.returncode == 0
|
|
assert "Notice: AGENT_SESSIONS_STATE_DIR is set but has no effect" in res_env.stderr
|
|
assert not custom_dir.exists()
|
|
assert not (mam_sandbox / ".cache").exists()
|
|
|
|
# Valid JSON on stdout
|
|
data = json.loads(res_env.stdout)
|
|
assert "drifts" in data or "drift" in data
|
|
|
|
# Y-7: Unset env var -> no notice on stderr
|
|
res_silent = _run_reconcile(mam_sandbox, ["--once", "--emit-diff", "--dry-run"])
|
|
assert res_silent.returncode == 0
|
|
assert "AGENT_SESSIONS_STATE_DIR" not in res_silent.stderr
|
|
|
|
|
|
def test_y4_reconcile_runs_normally(mam_sandbox):
|
|
res = _run_reconcile(mam_sandbox, ["--once", "--emit-diff"])
|
|
assert res.returncode == 0
|
|
data = json.loads(res.stdout)
|
|
assert "timestamp" in data
|
|
assert "drifts" in data or "drift" in data
|
|
|
|
|
|
def test_y5_existing_cache_dir_unmolested(mam_sandbox):
|
|
target = mam_sandbox / ".cache" / "multi-agent-mux-monitor"
|
|
target.mkdir(parents=True, exist_ok=True)
|
|
leftover = target / "leftover.state"
|
|
leftover.write_text("FROM-AN-OLDER-INSTALL")
|
|
|
|
res = _run_reconcile(mam_sandbox, ["--once", "--emit-diff"])
|
|
assert res.returncode == 0
|
|
assert leftover.exists()
|
|
assert leftover.read_text() == "FROM-AN-OLDER-INSTALL"
|
|
|
|
|
|
def test_y8_y9_remove_script_parent_cache_reclaim(mam_sandbox):
|
|
from pathlib import Path
|
|
repo_root = Path(__file__).resolve().parent.parent
|
|
remove_script = repo_root / "deploy" / "remove.sh"
|
|
assert remove_script.exists()
|
|
|
|
# Y-8: Empty .cache is reclaimed
|
|
cache_dir = mam_sandbox / ".cache" / "multi-agent-mux-monitor"
|
|
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Y-10: Check deploy/remove.sh source for relative rmdir ".cache"
|
|
content = remove_script.read_text()
|
|
assert 'rmdir ".cache"' in content or 'rmdir .cache' in content
|
|
|
|
# Y-9: Non-empty .cache is preserved (simulated rmdir logic)
|
|
other_tool = mam_sandbox / ".cache" / "other_tool"
|
|
other_tool.mkdir(parents=True, exist_ok=True)
|
|
(other_tool / "data.bin").write_text("keep me")
|
|
|
|
shutil.rmtree(cache_dir)
|
|
with pytest.raises(OSError):
|
|
os.rmdir(mam_sandbox / ".cache")
|
|
assert (other_tool / "data.bin").exists()
|