def test_breaker_will_raise(testbreakbox):
    """
    Using the circuit_breaker context should raise CircuitBroken if
    called on a CircuitBreaker that has already tripped.
    """
    breaker = testbreakbox["basic"]
    raisefault("basic", testbreakbox)
    assert breaker.tripped is True
    with pytest.raises(CircuitBroken):
        with circuit_breaker("basic", breakerbox=testbreakbox):
            1/0
def test_breaker_blocks(testbreakbox):
    """
    A circuit_breaker context with the blocks=True flag should not raise, but
    instead wait.
    """
    breaker = testbreakbox["short"]
    raisefault("short", testbreakbox)
    assert breaker.tripped is True
    with pytest.raises(gevent.Timeout), gevent.Timeout(0.001):
        with circuit_breaker("short", block=True, breakerbox=testbreakbox):
            raise Exception("Should not get here.")
def test_breaker_clears_on_success(testbreakbox):
    """
    Once a circuit_breaker context has passed, it should completely clear the
    breaker so that future uses will succeed as normal.
    """
    breaker = testbreakbox["multi"]
    raisefault("multi", testbreakbox)
    assert breaker.fails == 1
    with circuit_breaker("multi", breakerbox=testbreakbox):
        pass  # Should cause 'clear' to be run.
    assert breaker.fails == 0
def raisefault(brk_name, breakerbox):
    """
    Deliberately raise a fault in the named breaker.

    Helper function to avoid needing to type out a full try/except block
    in every test.
    """
    try:
        with circuit_breaker(brk_name, breakerbox=breakerbox):
            1/0
    except Exception:
        pass  # Swallow, we know.
def test_breaker_reset_fails_not_fully_reset(testbreakbox):
    """
    A circuit_breaker's reset timer task should set its failure state to
    one below the threshold, rather than  completely clear it.
    """
    breaker = testbreakbox["shortmulti"]
    for x in range(3):
        raisefault("shortmulti", testbreakbox)
    assert breaker.tripped is True
    gevent.sleep(0.02)
    # Reset should run and set us to threshold-1 for a try.
    assert breaker.tripped is False
    assert breaker.fails == 2
    # One more should be back at threshold.
    raisefault("shortmulti", testbreakbox)
    assert breaker.tripped is True
    # And clear it fully.
    with circuit_breaker("shortmulti", breakerbox=testbreakbox, block=True):
        pass
    assert breaker.tripped is False
    assert breaker.fails == 0
 def slow_worker():
     with circuit_breaker("basic", breakerbox=testbreakbox):
         gevent.sleep(0.01)
 def waiting_task():
     with circuit_breaker("short", block=True):
         gevent.sleep(0.001)
         result["done"] = True