#!/usr/bin/env python3 import os import sys import tempfile import time import unittest from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from registry import Registry # noqa: E402 class RegistryTests(unittest.TestCase): def setUp(self): self.reg = Registry(n=4) def test_unique_slots(self): a = self.reg.assign("AA:BB:CC:DD:EE:01") b = self.reg.assign("AA:BB:CC:DD:EE:02") self.assertIsNotNone(a) self.assertIsNotNone(b) self.assertNotEqual(a.slot, b.slot) def test_collector_assigns_slot(self): s = self.reg.assign("11:22:33:44:55:66") self.assertEqual(s.slot, 0) # sensor cannot pick slot — second assign same addr returns same s2 = self.reg.assign("11:22:33:44:55:66") self.assertIs(s, s2) def test_pool_full(self): for i in range(4): self.assertIsNotNone(self.reg.assign(f"AA:BB:CC:DD:EE:0{i}")) self.assertTrue(self.reg.pool_full()) self.assertIsNone(self.reg.assign("FF:FF:FF:FF:FF:FF")) def test_stale_keeps_slot(self): s = self.reg.assign("AA:BB:CC:DD:EE:10") s.last_seen = time.time() - 1000 self.reg.reevaluate(now=time.time(), period_s=30) # k=3 → stale at 90s; lost at 180s — 1000s → lost # use milder silence for stale only s2 = self.reg.assign("AA:BB:CC:DD:EE:11") s2.last_seen = time.time() - 100 self.reg.reevaluate(now=time.time(), period_s=30) self.assertEqual(s2.state, "stale") self.assertIs(self.reg.slots[s2.slot], s2) def test_lost_frees_slot(self): s = self.reg.assign("AA:BB:CC:DD:EE:20") slot = s.slot s.last_seen = time.time() - 10000 self.reg.reevaluate(now=time.time(), period_s=30) self.assertIsNone(self.reg.slots[slot]) self.assertNotIn("AA:BB:CC:DD:EE:20", self.reg.by_addr) def test_pool_full_iff_no_none(self): self.assertFalse(self.reg.pool_full()) for i in range(4): self.reg.assign(f"AA:00:00:00:00:0{i}") self.assertTrue(self.reg.pool_full()) self.assertTrue(None not in self.reg.slots) def test_persist(self): with tempfile.TemporaryDirectory() as td: path = Path(td) / "reg.json" r1 = Registry(n=4, path=path) r1.assign("AA:BB:CC:DD:EE:30") r1.save() r2 = Registry(n=4, path=path) r2.load() self.assertIn("AA:BB:CC:DD:EE:30", r2.by_addr) self.assertEqual(r2.by_addr["AA:BB:CC:DD:EE:30"].slot, 0) if __name__ == "__main__": unittest.main()