79 lines
2.2 KiB
Python
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 |