Files
AI_engine/tests/test_stall_dedup.py

67 lines
2.3 KiB
Python

"""
Tests for the Redis-backed stall dedup claim (replaces the old in-memory set).
- The first claim for a booking wins; a second within the window is refused.
- The consumer-side handled-claim behaves the same (redelivery guard).
- A Redis error fails OPEN (returns True) so a genuine stall is never muted.
Run:
python -m unittest discover -s tests
"""
import unittest
from agents.exception_agent import ExceptionAgent
class FakeRedisNX:
"""Minimal Redis with SET NX + TTL semantics."""
def __init__(self, raise_on_set=False):
self.store = {}
self.raise_on_set = raise_on_set
self.set_calls = []
async def set(self, key, val, ex=None, nx=False):
if self.raise_on_set:
raise RuntimeError("redis down")
self.set_calls.append((key, ex, nx))
if nx and key in self.store:
return None # already claimed
self.store[key] = val
return True
def make_agent(redis):
agent = ExceptionAgent.__new__(ExceptionAgent) # skip heavy __init__
agent._redis = redis
return agent
class TestStallDedup(unittest.IsolatedAsyncioTestCase):
async def test_first_alert_claim_wins_second_refused(self):
agent = make_agent(FakeRedisNX())
self.assertTrue(await agent._claim_stall("b1")) # first wins
self.assertFalse(await agent._claim_stall("b1")) # duplicate refused
self.assertTrue(await agent._claim_stall("b2")) # different booking ok
async def test_claim_sets_ttl_and_nx(self):
redis = FakeRedisNX()
await make_agent(redis)._claim_stall("b9")
key, ex, nx = redis.set_calls[0]
self.assertEqual(key, "stall_notified:b9")
self.assertTrue(nx)
self.assertEqual(ex, 21600)
async def test_handled_claim_guards_redelivery(self):
agent = make_agent(FakeRedisNX())
self.assertTrue(await agent._claim_stall_handled("b1"))
self.assertFalse(await agent._claim_stall_handled("b1"))
async def test_redis_error_fails_open(self):
agent = make_agent(FakeRedisNX(raise_on_set=True))
self.assertTrue(await agent._claim_stall("b1")) # must not mute a real stall
self.assertTrue(await agent._claim_stall_handled("b1"))
if __name__ == "__main__":
unittest.main()