"""Deploy registry + hot-swap atomicity.""" from __future__ import annotations import pytest from mindxtrain.deploy.hot_swap import promote_canary_to_live, rollback_live from mindxtrain.deploy.registry import DeployRegistry, Slot def test_registry_round_trip(tmp_path): reg = DeployRegistry(tmp_path / "reg.json") assert reg.get("live") is None reg.set(Slot(name="live", run_id="r1", blake3="a" * 64)) got = reg.get("live") assert got is not None assert got.run_id == "r1" def test_promote_canary_to_live_retains_previous(tmp_path): reg = DeployRegistry(tmp_path / "reg.json") reg.set(Slot(name="live", run_id="v1", blake3="0" * 64)) reg.set(Slot(name="canary", run_id="v2", blake3="1" * 64)) new_live = promote_canary_to_live(tmp_path / "reg.json") assert new_live.run_id == "v2" assert reg.get("previous_live") is not None assert reg.get("previous_live").run_id == "v1" assert reg.get("canary") is None def test_rollback_live(tmp_path): reg = DeployRegistry(tmp_path / "reg.json") reg.set(Slot(name="live", run_id="v1", blake3="0" * 64)) reg.set(Slot(name="canary", run_id="v2", blake3="1" * 64)) promote_canary_to_live(tmp_path / "reg.json") rolled = rollback_live(tmp_path / "reg.json") assert rolled.run_id == "v1" def test_rollback_with_no_previous_raises(tmp_path): DeployRegistry(tmp_path / "reg.json") with pytest.raises(RuntimeError): rollback_live(tmp_path / "reg.json")