from __future__ import annotations import tempfile import unittest from pathlib import Path from support import * # noqa: F403 from netbox_store_agent.errors import ConflictError from netbox_store_agent.journal import Journal, ManagedPlugin from netbox_store_agent.protocol import OperationRequest class JournalTests(unittest.TestCase): def setUp(self) -> None: self.temporary = tempfile.TemporaryDirectory() self.journal = Journal(Path(self.temporary.name) / "journal.sqlite3") self.key = "20f4274f-d4e5-42bf-9164-967b1a774481" self.request = OperationRequest( "eea17d87-8944-4ee2-a076-363338ab746d", "install", "demo-plugin", "1.2.3", "opaque", "alice", ) def tearDown(self) -> None: self.temporary.cleanup() def test_idempotency_same_payload_returns_existing(self) -> None: first, created = self.journal.submit(self.key, self.request) second, created_again = self.journal.submit(self.key, self.request) self.assertTrue(created) self.assertFalse(created_again) self.assertEqual(first["operation_id"], second["operation_id"]) def test_idempotency_conflict(self) -> None: self.journal.submit(self.key, self.request) changed = OperationRequest(**{**self.request.as_dict(), "requested_by": "mallory"}) with self.assertRaises(ConflictError): self.journal.submit(self.key, changed) def test_claim_is_exactly_once(self) -> None: self.journal.submit(self.key, self.request) self.assertTrue(self.journal.claim(self.key)) self.assertFalse(self.journal.claim(self.key)) def test_running_recovery_is_manual(self) -> None: self.journal.submit(self.key, self.request) self.journal.claim(self.key) self.assertEqual(self.journal.recover_interrupted(), 1) operation = self.journal.get_operation(self.key) self.assertEqual(operation["state"], "manual_recovery") def test_managed_plugin_round_trip(self) -> None: plugin = ManagedPlugin( "demo-plugin", "demo-plugin", "demo_plugin", "1.2.3", False, ({"sha256": "a" * 64},), ) self.journal.upsert_managed_plugin(plugin) self.assertEqual(self.journal.get_managed_plugin("demo-plugin"), plugin) self.journal.delete_managed_plugin("demo-plugin") self.assertIsNone(self.journal.get_managed_plugin("demo-plugin")) if __name__ == "__main__": unittest.main()