Exemplo n.º 1
0
def test_exception_whitelist(error_func):
    breaker = CircuitBreaker(error_threshold=1,
                             exception_whitelist=[IOError],
                             recovery_timeout=1)
    breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED
Exemplo n.º 2
0
def test_exception_whitelist_supports_inheritance(error_func):
    breaker = CircuitBreaker(error_threshold=1,
                             exception_whitelist=[Exception],
                             recovery_timeout=1)
    breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED
Exemplo n.º 3
0
def test_exception_blacklist_filters_errors(error_func):
    # When the blacklist is specified, only those errors are caught
    breaker = CircuitBreaker(error_threshold=1,
                             exception_blacklist=[ValueError],
                             recovery_timeout=1)
    breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED
Exemplo n.º 4
0
def test_breaker_recloses_after_recovery_time(error_func):
    breaker = CircuitBreaker(error_threshold=1, recovery_timeout=1)

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.OPEN

    sleep(1)
    assert breaker.state == CircuitBreakerState.HALF_OPEN
Exemplo n.º 5
0
def test_exception_blacklist_supports_inheritance(error_func):
    # When the blacklist is specified, only those errors are caught
    breaker = CircuitBreaker(error_threshold=1,
                             exception_blacklist=[Exception],
                             recovery_timeout=1)

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.OPEN
Exemplo n.º 6
0
def test_notifies_on_breaker_open(error_func, io_error):
    mock_open = mock.Mock()
    breaker = CircuitBreaker(error_threshold=1, on_open=mock_open)

    assert mock_open.call_count == 0

    with pytest.raises(IOError):
        breaker.call(error_func)

    mock_open.assert_called_once()
    mock_open.assert_called_with(breaker, io_error)
Exemplo n.º 7
0
def half_open_breaker(error_func):
    breaker = CircuitBreaker(error_threshold=1,
                             recovery_timeout=1,
                             recovery_threshold=2)

    with pytest.raises(IOError):
        breaker.call(error_func)

    sleep(1)

    return breaker
Exemplo n.º 8
0
def test_get_circuits_not_empty():
    registry = CircuitBreakerRegistry()
    db_circuit = CircuitBreaker(breaker_id="db")
    service_circuit = CircuitBreaker(breaker_id="service")

    registry.register(db_circuit)
    registry.register(service_circuit)

    registered = registry.get_circuits()
    assert len(registered) == 2
    assert db_circuit in registered
    assert service_circuit in registered
Exemplo n.º 9
0
def test_can_detect_errors_that_are_not_exceptions(error_val, expected_state):
    breaker = CircuitBreaker(
        detect_error=lambda ret_val: ret_val is False,
        error_threshold=1,
    )

    def return_code_error():
        return error_val

    result = breaker.call(return_code_error)
    assert result is error_val
    assert breaker.state is expected_state
Exemplo n.º 10
0
def test_get_open_circuits_when_one_circuit_is_open(error_func):
    registry = CircuitBreakerRegistry()
    open_circuit = CircuitBreaker(breaker_id="open_breaker", error_threshold=1)
    closed_circuit = CircuitBreaker(breaker_id="closed_breaker")
    registry.register(open_circuit)
    registry.register(closed_circuit)

    with pytest.raises(IOError):
        open_circuit.call(error_func)

    opened = registry.get_open_circuits()

    assert len(opened) == 1
    assert open_circuit in opened
    assert closed_circuit not in opened
Exemplo n.º 11
0
def test_get_open_circuits_when_all_circuits_are_closed():
    registry = CircuitBreakerRegistry()
    circuit = CircuitBreaker(breaker_id="closed_breaker", error_threshold=1)
    registry.register(circuit)

    opened = registry.get_open_circuits()

    assert len(opened) == 0
Exemplo n.º 12
0
def test_register_new_circuit_breaker():
    registry = CircuitBreakerRegistry()
    circuit_breaker = CircuitBreaker()

    registry.register(circuit_breaker)

    registered = registry.get_circuits()
    assert len(registered) == 1
    assert registered[0] == circuit_breaker
Exemplo n.º 13
0
def test_register_existing_circuit_breaker():
    registry = CircuitBreakerRegistry()
    circuit_breaker = CircuitBreaker()

    registry.register(circuit_breaker)

    with pytest.raises(CircuitBreakerRegistryException):
        registry.register(circuit_breaker)

    registered = registry.get_circuits()
    assert len(registered) == 1
    assert registered[0] == circuit_breaker
Exemplo n.º 14
0
def test_calling_an_open_breaker_raises_an_error(error_func):
    breaker = CircuitBreaker(error_threshold=1,
                             recovery_timeout=1,
                             recovery_threshold=2)

    with pytest.raises(IOError):
        breaker.call(error_func)

    with pytest.raises(CircuitBreakerException):
        breaker.call(error_func)
Exemplo n.º 15
0
def test_breaker_opens_after_specified_number_of_errors(error_func):
    breaker = CircuitBreaker(error_threshold=2)

    with pytest.raises(IOError):
        breaker.call(error_func)
    assert breaker.state == CircuitBreakerState.CLOSED

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.OPEN
Exemplo n.º 16
0
def test_net_error_strategy_half_open_to_closed(error_func, success_func):
    breaker = CircuitBreaker(
        strategy=CircuitBreakerStrategy.NET_ERROR,
        error_threshold=1,
        recovery_timeout=1,
    )

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.OPEN

    sleep(1)
    assert breaker.state == CircuitBreakerState.HALF_OPEN

    breaker.call(success_func)
    assert breaker.state == CircuitBreakerState.CLOSED
Exemplo n.º 17
0
def test_notifies_on_breaker_close(error_func, success_func):
    mock_close = mock.Mock()
    breaker = CircuitBreaker(
        error_threshold=1,
        on_close=mock_close,
        recovery_timeout=1,
    )

    assert mock_close.call_count == 0

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert mock_close.call_count == 0

    sleep(1)
    breaker.call(success_func)

    assert mock_close.call_count == 1
Exemplo n.º 18
0
def test_breaker_starts_closed():
    breaker = CircuitBreaker()
    assert breaker.state == CircuitBreakerState.CLOSED
Exemplo n.º 19
0
def test_unknown_strategy_causes_error():
    with pytest.raises(ValueError):
        CircuitBreaker(strategy="foo")
Exemplo n.º 20
0
def test_net_error_strategy_count_never_negative(success_func):
    breaker = CircuitBreaker(strategy=CircuitBreakerStrategy.NET_ERROR, )
    breaker.call(success_func)

    assert breaker._strategy._net_error_count == 0
Exemplo n.º 21
0
def test_net_error_strategy(error_func, success_func):
    breaker = CircuitBreaker(
        strategy=CircuitBreakerStrategy.NET_ERROR,
        error_threshold=3,
    )

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED

    breaker.call(success_func)

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.CLOSED

    with pytest.raises(IOError):
        breaker.call(error_func)

    assert breaker.state == CircuitBreakerState.OPEN
Exemplo n.º 22
0
def test_circuit_breaker_exception_serialization():
    breaker = CircuitBreaker(breaker_id="FOO")
    exception = CircuitBreakerException(breaker)
    exception_str = str(exception)
    assert "Circuit FOO OPEN until" in exception_str