From fce9459e42442ea700eb4902a7cb7bf7b0d6a6cd Mon Sep 17 00:00:00 2001 From: Godopu Date: Tue, 27 Oct 2026 04:07:42 +0000 Subject: [PATCH] test(update): the first transition reaches the skill and the conversion (Issue #72, criterion 5) A v4.11.0 workspace's .mam_deploy/update.sh installs the new version - the skill present, no updater left - and the skill run after it converts the registry. An update-backup in an unknown state now restarts the monitor it stopped: nothing was changed. Co-Authored-By: Claude Opus 5.5 --- tests/test_issue72_update.py | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_issue72_update.py b/tests/test_issue72_update.py index f554bae..52bd0cf 100644 --- a/tests/test_issue72_update.py +++ b/tests/test_issue72_update.py @@ -708,3 +708,40 @@ def test_an_entry_holding_the_admission_lock_is_waited_for_or_refuses(box, wait, assert needle in res.stderr, res.stderr assert not (box.ws / "INSTALLER-RAN").exists() assert not (box.mam / "update-in-progress").exists() + + +# --- the first transition (decision 4, criterion 5) ------------------------------------ + +def test_the_old_updater_installs_the_skill_which_then_converts_the_registry(tmp_path): + """A workspace installed by v4.11.0 still has .mam_deploy/update.sh. Run once, + it installs the new version - the skill, and no updater left behind - and + copies the registry unconverted; the skill run right after converts it.""" + old_src = tmp_path / "v4.11.0" + old_src.mkdir() + arch = subprocess.run(["git", "-C", str(REPO_ROOT), "archive", "0e1e2e8"], capture_output=True) + if arch.returncode != 0: + pytest.skip("no git history to rebuild v4.11.0 from") + subprocess.run(["tar", "-x", "-C", str(old_src)], input=arch.stdout, check=True) + root = Path(os.path.realpath(tmp_path)) + ws = root / "ws" + ws.mkdir() + (root / "bin").mkdir() + (root / "bin" / "herdr").write_text(FAKE_HERDR) + (root / "bin" / "herdr").chmod(0o755) + b = Box(root, ws) + res = subprocess.run(["bash", str(old_src / "deploy" / "install.sh"), str(ws)], + env=dict(b.env, MAM_REPO_URL=str(old_src)), capture_output=True, text=True, timeout=600) + assert res.returncode == 0, res.stdout + res.stderr + assert (ws / ".mam_deploy" / "update.sh").exists() + write_rows(ws, [row("old-one", status="stopped", kill_command="x", start_command="y")]) + + res = subprocess.run(["bash", str(ws / ".mam_deploy" / "update.sh"), "--force"], cwd=str(ws), env=b.env, + capture_output=True, text=True, timeout=600, stdin=subprocess.DEVNULL) + assert res.returncode == 0, res.stdout + res.stderr + assert (ws / UPDATE_REL).exists() and not (ws / ".mam_deploy" / "update.sh").exists() + assert "registry_format" not in yaml.safe_load((ws / ".mam" / "agent-sessions.yaml").read_text()) + + res = b.update() + assert res.returncode == 0, res.stdout + res.stderr + assert "registry-format: 1 -> 2, rows changed: 1" in res.stdout + assert yaml.safe_load((ws / ".mam" / "agent-sessions.yaml").read_text())["registry_format"] == 2