Repository navigation
Expand file tree
/
Copy pathtest_resilience.py
More file actions
65 lines (46 loc) · 1.72 KB
/
Copy pathtest_resilience.py
File metadata and controls
65 lines (46 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""Tests for resilience patterns."""
import pytest
from utils.resilience.circuit_breaker import CircuitBreaker, CircuitState
from utils.resilience.retry import retry_with_backoff
def test_circuit_breaker_closed():
"""Test circuit breaker in closed state."""
breaker = CircuitBreaker(failure_threshold=3)
def success_func():
return "success"
result = breaker.call(success_func)
assert result == "success"
assert breaker.state == CircuitState.CLOSED
assert breaker.failure_count == 0
def test_circuit_breaker_opens_after_failures():
"""Test circuit breaker opens after threshold failures."""
breaker = CircuitBreaker(failure_threshold=3)
def failing_func():
raise Exception("Test failure")
# Fail 3 times to open circuit
for _ in range(3):
with pytest.raises(Exception):
breaker.call(failing_func)
assert breaker.state == CircuitState.OPEN
assert breaker.failure_count >= 3
def test_retry_with_backoff_success():
"""Test retry succeeds eventually."""
attempts = []
@retry_with_backoff(max_attempts=3, base_delay=0.1)
def flaky_func():
attempts.append(1)
if len(attempts) < 2:
raise Exception("Temporary failure")
return "success"
result = flaky_func()
assert result == "success"
assert len(attempts) == 2
def test_retry_with_backoff_exhaustion():
"""Test retry exhausts all attempts."""
attempts = []
@retry_with_backoff(max_attempts=3, base_delay=0.1)
def always_fails():
attempts.append(1)
raise ValueError("Always fails")
with pytest.raises(ValueError):
always_fails()
assert len(attempts) == 3