Files

79 lines
2.2 KiB
Python

import time
from circuit_breaker import CircuitBreaker, CircuitOpenError, CircuitState
def test_closed_normal():
cb = CircuitBreaker(failure_threshold=2, recovery_timeout=0.1, success_threshold=1)
assert cb.state is CircuitState.CLOSED
assert cb.call(lambda: 42) == 42
def test_opens_after_threshold():
cb = CircuitBreaker(failure_threshold=2, recovery_timeout=10, success_threshold=1)
def boom():
raise ValueError("x")
for _ in range(2):
try:
cb.call(boom)
except ValueError:
pass
assert cb.state is CircuitState.OPEN
try:
cb.call(lambda: 1)
raised = False
except CircuitOpenError:
raised = True
assert raised
def test_half_open_and_close():
cb = CircuitBreaker(failure_threshold=1, recovery_timeout=0.05, success_threshold=2)
try:
cb.call(lambda: (_ for _ in ()).throw(ValueError("x")))
except ValueError:
pass
assert cb.state is CircuitState.OPEN
time.sleep(0.06)
assert cb.state is CircuitState.HALF_OPEN
assert cb.call(lambda: "ok1") == "ok1"
assert cb.call(lambda: "ok2") == "ok2"
assert cb.state is CircuitState.CLOSED
def test_half_open_failure_reopens():
cb = CircuitBreaker(failure_threshold=1, recovery_timeout=0.05, success_threshold=2)
try:
cb.call(lambda: (_ for _ in ()).throw(ValueError("x")))
except ValueError:
pass
time.sleep(0.06)
assert cb.state is CircuitState.HALF_OPEN
try:
cb.call(lambda: (_ for _ in ()).throw(ValueError("y")))
except ValueError:
pass
assert cb.state is CircuitState.OPEN
def test_invalid_params():
for kw in ({"failure_threshold": 0}, {"recovery_timeout": -1}, {"success_threshold": 0}):
try:
CircuitBreaker(**kw)
assert False
except ValueError:
pass
def test_reset():
cb = CircuitBreaker(failure_threshold=1, recovery_timeout=10, success_threshold=1)
try:
cb.call(lambda: (_ for _ in ()).throw(ValueError("x")))
except ValueError:
pass
assert cb.state is CircuitState.OPEN
cb.reset()
assert cb.state is CircuitState.CLOSED
assert cb.call(lambda: 7) == 7