SPB Git forge

spb/api-ka

Public

API-KA — plateforme centrale : collecte quotidienne des 8 services KA, historisation append-only et API publique sur www.api-ka.com

48commits 1branches 0releases
5.9 MBsize
maindefault branch
19 days agolast push
Python 60.9% HTML 21% TypeScript 7.3% JavaScript 5.2% CSS 4.8% Shell 0.8%
2.1 KB · 78 lines python
Raw Blame History
1# ============================================2# Projet   : API-KA3# Fichier  : tests/test_retry.py4# Node     : m3u96b5# Author   : Simon-Pierre Boucher6# Contact  : contact@spboucher.ai7# Date     : 2026-08-168# ============================================9"""Tests de la logique de retry avec backoff (src/utils/retry.py)."""1011from __future__ import annotations1213import pytest1415from src.utils.retry import retry, retry_call161718def test_retry_call_succeeds_first_try() -> None:19    """Aucune relance si le premier essai réussit."""20    calls = {"count": 0}2122    def ok() -> str:23        calls["count"] += 124        return "ok"2526    assert retry_call(ok, attempts=3, delays=(0, 0, 0)) == "ok"27    assert calls["count"] == 1282930def test_retry_call_recovers_after_failures() -> None:31    """Les échecs transitoires sont relancés jusqu'au succès."""32    calls = {"count": 0}33    retries: list[int] = []3435    def flaky() -> str:36        calls["count"] += 137        if calls["count"] < 3:38            raise RuntimeError("transitoire")39        return "ok"4041    result = retry_call(42        flaky,43        attempts=3,44        delays=(0, 0, 0),45        on_retry=lambda attempt, exc, delay: retries.append(attempt),46    )47    assert result == "ok"48    assert calls["count"] == 349    assert retries == [1, 2]505152def test_retry_call_raises_after_exhaustion() -> None:53    """Après épuisement des tentatives, la dernière exception est propagée."""54    calls = {"count": 0}5556    def always_fails() -> None:57        calls["count"] += 158        raise ValueError("permanent")5960    with pytest.raises(ValueError, match="permanent"):61        retry_call(always_fails, attempts=3, delays=(0, 0, 0))62    assert calls["count"] == 4  # essai initial + 3 relances636465def test_retry_decorator() -> None:66    """Le décorateur applique la même logique que retry_call."""67    calls = {"count": 0}6869    @retry(attempts=2, delays=(0, 0))70    def flaky(value: int) -> int:71        calls["count"] += 172        if calls["count"] == 1:73            raise RuntimeError("transitoire")74        return value * 27576    assert flaky(21) == 4277    assert calls["count"] == 278