Automatically remove unused game-file versions

This commit is contained in:
2026-10-04 23:05:32 -04:00
parent 9c6d7cc347
commit 725d41c112
15 changed files with 336 additions and 22 deletions
+50
View File
@@ -74,6 +74,56 @@ class AgentTests(unittest.TestCase):
self.agent.journal.close()
self.temp.cleanup()
def test_library_remove_preserves_other_versions_and_is_idempotent(self):
other = self.agent.library_dir("t5", "other-library")
other.mkdir()
staging = self.library.with_name("." + self.library_id + ".partial")
staging.mkdir()
(staging / "partial").write_bytes(b"partial")
payload = {"libraryVersionId": self.library_id, "game": "t5"}
self.assertTrue(self.agent.library_remove(payload)["removed"])
self.assertFalse(self.library.exists())
self.assertFalse(staging.exists())
self.assertTrue(other.exists())
self.assertTrue(self.agent.library_remove(payload)["removed"])
def test_library_remove_refuses_stopped_container_mounts_and_docker_errors(self):
payload = {"libraryVersionId": self.library_id, "game": "t5"}
with patch.object(self.docker, "call", return_value="stopped-container"), patch.object(self.docker, "inspect", return_value={
"State": {"Running": False}, "Mounts": [{"Source": str(self.library / "content")}]
}):
with self.assertRaisesRegex(AgentError, "still mounted"):
self.agent.library_remove(payload)
with patch.object(self.docker, "call", side_effect=AgentError("Docker unavailable")):
with self.assertRaises(AgentError):
self.agent.library_remove(payload)
self.assertTrue((self.library / "content" / "game.ff").exists())
def test_library_remove_recovers_after_interrupted_deletion(self):
payload = {"libraryVersionId": self.library_id, "game": "t5"}
operation = {"id": "library-cleanup", "kind": "library.remove", "payload": payload}
self.agent.journal.accept(operation)
self.agent.journal.update(operation["id"], "running")
self.agent.journal.checkpoint(operation["id"], {"phase": "removing-library"})
(self.library / "manifest.json").unlink()
row = self.agent.reconcile(operation, self.agent.journal.get(operation["id"]))
self.assertEqual(row["state"], "completed")
self.assertFalse(self.library.exists())
def test_library_remove_ignores_unrelated_and_tmpfs_mounts(self):
with patch.object(self.docker, "call", return_value="other-container"), patch.object(self.docker, "inspect", return_value={
"Mounts": [{"Type": "tmpfs", "Source": ""}, {"Source": str(self.agent.root / "instances")}]
}):
self.agent.library_remove({"libraryVersionId": self.library_id, "game": "t5"})
self.assertFalse(self.library.exists())
def test_library_remove_refuses_symlink_storage(self):
linked = self.agent.library_dir("t5", "linked-library")
linked.symlink_to(self.library, target_is_directory=True)
with self.assertRaisesRegex(AgentError, "symlink"):
self.agent.library_remove({"libraryVersionId": "linked-library", "game": "t5"})
self.assertTrue(self.library.exists())
def cpu_sample(self, line):
with patch.object(Path, "open", mock_open(read_data=line)):
return self.agent.cpu_usage_percent()