"""Collected rounds held in memory until the database takes them (#5995): stored oldest first, one writer at a time, bounded, and kept through a store that fails or never answers.""" import asyncio from types import SimpleNamespace as NS from steward.core.holding import Holding, holding def test_rounds_held_while_the_store_hangs_are_stored_in_order_once_it_answers(): async def main(): gate, stored = asyncio.Event(), [] async def store(rounds): await gate.wait() stored.append(list(rounds)) held = Holding("t", store, limit=10) held.hold("a") assert await held.flush(0.05) is False # the store hangs: the caller goes on held.hold("b") assert await held.flush(0.05) is False and len(held) == 2 gate.set() assert await held.flush(1.0) is True and len(held) == 0 return stored assert asyncio.run(main()) == [["a"], ["b"]] # "b" waited for the store in flight def test_past_its_limit_the_oldest_round_goes_and_is_counted(): held = Holding("t", store=None, limit=2) for r in ("a", "b", "c"): held.hold(r) assert len(held) == 2 and held.dropped == 1 and [i for _, i in held._held] == ["b", "c"] def test_a_store_that_cant_reach_the_database_or_overruns_its_deadline_keeps_the_rounds_held(): async def main(): async def unreachable(rounds): raise ConnectionRefusedError("database down") held = Holding("t", unreachable, limit=10) held.hold("a") assert await held.flush(1.0) is False and len(held) == 1 async def never(rounds): await asyncio.sleep(3600) stuck = Holding("t", never, limit=10, deadline_s=0.05) stuck.hold("a") assert await stuck.flush(1.0) is False and len(stuck) == 1 # given up, not lost asyncio.run(main()) def test_a_round_the_database_refuses_is_dropped_and_holds_up_nobody_after_it(): async def main(): stored = [] async def store(rounds): if "bad" in rounds: raise ValueError("value out of range") stored.extend(rounds) held = Holding("t", store, limit=10) for r in ("a", "bad", "c"): held.hold(r) assert await held.flush(1.0) is True return stored assert asyncio.run(main()) == ["a", "c"] def test_an_app_has_one_holding_per_collector(): app = NS() first = holding(app, "SNMP poll", store=None, limit=5) assert holding(app, "SNMP poll", store=None, limit=5) is first assert holding(app, "UniFi poll", store=None, limit=5) is not first