65 lines
1.6 KiB
Python
65 lines
1.6 KiB
Python
import sys, os, time
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from retry_jitter import retry
|
|
|
|
def test_success_no_sleep():
|
|
calls = {"n":0}
|
|
sleeps = []
|
|
def fn():
|
|
calls["n"]+=1
|
|
return 42
|
|
assert retry(fn, sleep=sleeps.append) == 42
|
|
assert calls["n"]==1 and sleeps==[]
|
|
|
|
def test_retries_then_succeeds():
|
|
calls={"n":0}
|
|
def fn():
|
|
calls["n"]+=1
|
|
if calls["n"]<3: raise ValueError("boom")
|
|
return "ok"
|
|
assert retry(fn, max_attempts=3, base_delay=0, sleep=lambda x:None)=="ok"
|
|
assert calls["n"]==3
|
|
|
|
def test_exhausted_raises_original():
|
|
class E(Exception): pass
|
|
def fn():
|
|
raise E("x")
|
|
try:
|
|
retry(fn, max_attempts=2, base_delay=0, sleep=lambda x:None)
|
|
except E as e:
|
|
assert str(e)=="x"
|
|
else:
|
|
raise AssertionError("no raise")
|
|
|
|
def test_nonretryable_propagates():
|
|
class A(Exception): pass
|
|
class B(Exception): pass
|
|
def fn():
|
|
raise B("no")
|
|
try:
|
|
retry(fn, retryable=(A,), max_attempts=3, base_delay=0, sleep=lambda x:None)
|
|
except B:
|
|
pass
|
|
else:
|
|
raise AssertionError("not propagated")
|
|
|
|
def test_max_attempts_validation():
|
|
try:
|
|
retry(lambda: 1, max_attempts=0)
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
raise AssertionError("no validation")
|
|
|
|
def test_jitter_bounded():
|
|
rng=__import__("random").Random(1)
|
|
sleeps=[]
|
|
def fn():
|
|
raise ValueError("e")
|
|
try:
|
|
retry(fn, max_attempts=4, base_delay=1.0, max_delay=2.0, rng=rng, sleep=sleeps.append)
|
|
except ValueError:
|
|
pass
|
|
for d in sleeps:
|
|
assert 0.0 <= d <= 2.0
|