""" Unit test: ExponentialBackoff """ import asyncio import time import pytest from app.imap.reconnect import ExponentialBackoff @pytest.mark.asyncio async def test_backoff_increases(): """Il tempo di attesa aumenta ad ogni tentativo.""" backoff = ExponentialBackoff(label="test", jitter=False) # Registra i tempi senza aspettare davvero (patch asyncio.sleep) waits = [] original_sleep = asyncio.sleep async def fake_sleep(t): waits.append(t) asyncio.sleep = fake_sleep try: await backoff.wait() await backoff.wait() await backoff.wait() finally: asyncio.sleep = original_sleep assert waits[1] > waits[0], "Il secondo wait deve essere maggiore del primo" assert waits[2] > waits[1], "Il terzo wait deve essere maggiore del secondo" @pytest.mark.asyncio async def test_backoff_reset(): """reset() riporta il contatore a zero e il wait riparte dal valore iniziale.""" backoff = ExponentialBackoff(label="test", jitter=False) waits = [] async def fake_sleep(t): waits.append(t) original_sleep = asyncio.sleep asyncio.sleep = fake_sleep try: await backoff.wait() # waits[0]: valore iniziale (es. 1.0) await backoff.wait() # waits[1]: valore incrementato (es. 2.0) backoff.reset() await backoff.wait() # waits[2]: deve tornare al valore iniziale finally: asyncio.sleep = original_sleep # Dopo reset il wait riparte dal valore iniziale assert backoff.attempt == 1 assert waits[2] == waits[0], ( f"Dopo reset il wait deve tornare a {waits[0]}, ma era {waits[2]}" ) @pytest.mark.asyncio async def test_backoff_max(): """Il tempo di attesa non supera backoff_max_seconds.""" from app.config import get_settings settings = get_settings() backoff = ExponentialBackoff(label="test", jitter=False) max_recorded = 0.0 async def fake_sleep(t): nonlocal max_recorded max_recorded = max(max_recorded, t) original_sleep = asyncio.sleep asyncio.sleep = fake_sleep try: for _ in range(20): await backoff.wait() finally: asyncio.sleep = original_sleep assert max_recorded <= settings.backoff_max_seconds + 0.1 def test_backoff_attempt_count(): """Il contatore tentativi si incrementa correttamente.""" import asyncio backoff = ExponentialBackoff(label="test", jitter=False) async def run(): async def fake_sleep(_): pass asyncio.sleep = fake_sleep await backoff.wait() await backoff.wait() await backoff.wait() asyncio.get_event_loop().run_until_complete(run()) assert backoff.attempt == 3