Rebuild beta and campaign file activations

This commit is contained in:
2026-10-12 22:52:58 -04:00
parent fa0baa8db5
commit 537b9841a7
22 changed files with 533 additions and 94 deletions
+60
View File
@@ -1821,6 +1821,66 @@ class AgentTests(unittest.TestCase):
self.assertTrue(path.is_symlink())
request.assert_not_called()
def staged_rebuild(self, deleting=False):
spec = self.create()
self.agent.rcon = lambda *_: {"ok": True, "players": 0}
file = {"id": 9, "path": "configs/server.cfg", "contentBase64": None if deleting else base64.b64encode(b"replacement").decode(), "checkBefore": True, "expectedBeforeSha": module.digest(b"original")}
staged = self.agent.execute(self.operation("files.stage", {"stageId": "campaign", "files": [file]}, "stage"))
self.assertEqual(staged["state"], "completed")
spec["files"] = [] if deleting else [file]
return self.operation("instance.rebuild", {"spec": spec, "stageId": "campaign", "nextGeneration": 2}, "rebuild")
def test_file_rebuild_replaces_generation_and_retains_before_images(self):
operation = self.staged_rebuild()
result = self.agent.execute(operation)
self.assertEqual(result["state"], "completed", result)
receipt = json.loads(result["result"])
self.assertEqual(receipt["before"], [{"id": 9, "path": "configs/server.cfg", "contentBase64": base64.b64encode(b"original").decode()}])
self.assertEqual(receipt["generation"], 2)
self.assertFalse(self.agent.instance_dir(INSTANCE, 1).exists())
self.assertEqual((self.agent.instance_dir(INSTANCE, 2) / "app/configs/server.cfg").read_bytes(), b"replacement")
self.assertIn("instance.rebuild-files", self.agent.inventory()["capabilities"])
calls = list(self.docker.calls)
self.assertEqual(self.agent.execute(operation)["state"], "completed")
self.assertEqual(self.docker.calls, calls)
def test_file_rebuild_removes_requested_files(self):
operation = self.staged_rebuild(deleting=True)
result = self.agent.execute(operation)
self.assertEqual(result["state"], "completed", result)
self.assertFalse((self.agent.instance_dir(INSTANCE, 2) / "app/configs/server.cfg").exists())
self.assertEqual(len(json.loads(result["result"])["before"]), 1)
def test_file_rebuild_rejects_changed_targets_and_mismatched_replacement(self):
operation = self.staged_rebuild()
target = self.agent.instance_dir(INSTANCE, 1) / "app/configs/server.cfg"
target.write_bytes(b"changed")
self.assertEqual(self.agent.execute(operation)["state"], "failed")
self.assertTrue(self.agent.inspect(INSTANCE, 1)["running"])
target.write_bytes(b"original")
operation["id"] = "mismatched"
operation["payload"]["spec"]["files"] = []
self.assertEqual(self.agent.execute(operation)["state"], "failed")
self.assertTrue(self.agent.inspect(INSTANCE, 1)["running"])
self.assertFalse(any(call[:2] == ("container", "rm") for call in self.docker.calls))
def test_file_rebuild_rechecks_players_after_snapshot_preparation(self):
operation = self.staged_rebuild()
with patch.object(self.agent, "rcon", side_effect=[{"ok": True, "players": 0}, {"ok": True, "players": 1}]):
self.assertEqual(self.agent.execute(operation)["state"], "accepted")
self.assertTrue(self.agent.inspect(INSTANCE, 1)["running"])
self.assertFalse(self.agent.inspect(INSTANCE, 2)["exists"])
def test_file_rebuild_reconciles_snapshots_after_old_storage_was_removed(self):
operation = self.staged_rebuild()
self.assertEqual(self.agent.execute(operation)["state"], "completed")
self.agent.journal.update(operation["id"], "unknown", error="Lost completion")
calls = list(self.docker.calls)
result = self.agent.execute(operation)
self.assertEqual(result["state"], "completed", result)
self.assertEqual(json.loads(result["result"])["before"][0]["contentBase64"], base64.b64encode(b"original").decode())
self.assertEqual(self.docker.calls, calls)
def test_rebuild_moves_generation_and_rejects_old_commands(self):
payload = self.create()
self.agent.rcon = lambda *_: {"ok": True, "players": 0}