Exemple #1
0
def test_constant_backoff_validation():
    with pytest.raises(AssertionError):
        ConstantBackoff(retries='foo')
    with pytest.raises(AssertionError):
        ConstantBackoff(retries=-1)
    with pytest.raises(AssertionError):
        ConstantBackoff(interval='foo')
    with pytest.raises(AssertionError):
        ConstantBackoff(interval=-1)
Exemple #2
0
def test_constant_backoff_max_retries():
    backoff = ConstantBackoff(retries=5)
    assert backoff.retries == 5
    assert backoff.interval == .1
    assert backoff.pending_retries == backoff.retries

    for i in range(5):
        backoff.next()
        assert backoff.pending_retries == backoff.retries - (i + 1)

    assert backoff.next() == backoff.STOP
Exemple #3
0
def test_retry_async(MagicMock):
    import asyncio
    loop = asyncio.get_event_loop()

    # Track coro calls
    count = {'calls': 0}

    @asyncio.coroutine
    def coro(times, x):
        count['calls'] += 1

        if count['calls'] < times:
            raise RuntimeError('foo')

        return x * x

    on_retry = MagicMock()
    retrier = retry(on_retry=on_retry, backoff=ConstantBackoff(interval=.2,
                                                               retries=10))

    decorator = retrier(asyncio.coroutine(functools.partial(coro, 4)))
    result = loop.run_until_complete(decorator(2))
    assert result == 4

    assert on_retry.called
    assert on_retry.call_count == 3
Exemple #4
0
def test_async_retrier_custom():
    @asyncio.coroutine
    def sleep():
        pass

    @asyncio.coroutine
    def on_retry():
        pass

    @asyncio.coroutine
    def evaluator():
        pass

    backoff = ConstantBackoff()
    retrier = AsyncRetrier(timeout=1,
                           on_retry=on_retry,
                           sleep_coro=sleep,
                           evaluator=evaluator,
                           backoff=backoff)
    assert retrier.error is None
    assert retrier.attempts == 0
    assert retrier.timeout == 1
    assert retrier.on_retry is on_retry
    assert retrier.evaluator is evaluator
    assert retrier.sleep == sleep
    assert retrier.backoff == backoff
def test_async_retrier_context_manager(MagicMock, coro, run_coro):
    on_retry = MagicMock()
    retrier = AsyncRetrier(timeout=.25,
                           on_retry=on_retry,
                           backoff=ConstantBackoff(interval=.1, retries=5))

    @asyncio.coroutine
    def run_context():
        assert (yield from retrier.__aenter__()) is retrier  # noqa

        try:
            yield from retrier.run(coro(10), 2, 4, foo='bar')  # noqa
        except:
            yield from retrier.__aexit__(None, None, None)  # noqa
        else:
            raise AssertionError('must raise exception')

    run_coro(run_context())

    assert on_retry.called
    assert on_retry.call_count == 3

    assert retrier.attempts >= 1
    assert retrier.attempts < 4
    assert isinstance(retrier.error, RuntimeError)
Exemple #6
0
def test_retry(MagicMock):
    on_retry = MagicMock()
    retrier = retry(on_retry=on_retry)(task(4))
    assert retrier(2) == 4
    assert on_retry.called
    assert on_retry.call_count == 3

    on_retry = MagicMock()
    retrier = retry(on_retry=on_retry, backoff=ConstantBackoff())(task(4))
    assert retrier(3) == 9
    assert on_retry.called
    assert on_retry.call_count == 3

    on_retry = MagicMock()
    retrier = retry(on_retry=on_retry, backoff=ConstantBackoff())(task(4))
    assert retrier(4) == 16
    assert on_retry.called
    assert on_retry.call_count == 3
Exemple #7
0
def test_async_retrier_run_max_retries_error(MagicMock, coro):
    on_retry = MagicMock()
    task = coro(10)

    retrier = AsyncRetrier(on_retry=on_retry,
                           backoff=ConstantBackoff(interval=0, retries=2))

    with pytest.raises(MaxRetriesExceeded):
        run_coro(retrier.run(task, 2, 4, foo=6))

    assert on_retry.called
    assert on_retry.call_count == 2

    assert retrier.attempts == 2
    assert isinstance(retrier.error, RuntimeError)
Exemple #8
0
def test_async_retrier_run_max_timeout(MagicMock, coro):
    on_retry = MagicMock()
    task = coro(10)

    retrier = AsyncRetrier(timeout=.25, on_retry=on_retry,
                           backoff=ConstantBackoff(interval=.1))

    with pytest.raises(asyncio.TimeoutError):
        run_coro(retrier.run(task, 2, 4, foo=6))

    assert on_retry.called
    assert on_retry.call_count == 3

    assert retrier.attempts >= 1
    assert retrier.attempts < 4
    assert isinstance(retrier.error, RuntimeError)
Exemple #9
0
def test_async_retrier_cancelled_error(MagicMock, coro):
    on_retry = MagicMock()

    @asyncio.coroutine
    def coro(x):
        if on_retry.call_count < x:
            raise ValueError('small number')
        raise asyncio.CancelledError('oops')

    retrier = AsyncRetrier(on_retry=on_retry,
                           backoff=ConstantBackoff(interval=0, retries=10))

    with pytest.raises(asyncio.CancelledError):
        run_coro(retrier.run(coro, 4))

    assert on_retry.called
    assert on_retry.call_count == 4

    assert retrier.attempts == 5
    assert retrier.error is not None
Exemple #10
0
def test_async_retrier_evaluator_error_default(MagicMock, coro):
    on_retry = MagicMock()
    task = coro(4)

    def evaluator(x):
        if x < 4:
            raise ValueError('small number')
        raise ImportError('pass error')

    retrier = AsyncRetrier(evaluator=evaluator, on_retry=on_retry,
                           backoff=ConstantBackoff(interval=0, retries=10))

    with pytest.raises(ImportError):
        run_coro(retrier.run(task, 2, 4, foo=6))

    assert on_retry.called
    assert on_retry.call_count == 3

    assert retrier.attempts == 3
    assert isinstance(retrier.error, ImportError)
Exemple #11
0
def test_async_retrier_evaluator(MagicMock, coro):
    on_retry = MagicMock()
    task = coro(4)

    def evaluator(x):
        if x < 4:
            raise ValueError('small number')
        return False

    retrier = AsyncRetrier(evaluator=evaluator, on_retry=on_retry,
                           backoff=ConstantBackoff(interval=0, retries=10))

    res = run_coro(retrier.run(task, 2, 4, foo=6))
    assert res == 12

    assert on_retry.called
    assert on_retry.call_count == 3

    assert retrier.attempts == 3
    assert retrier.error is None
Exemple #12
0
def test_constant_backoff():
    backoff = ConstantBackoff()
    assert backoff.retries == 10
    assert backoff.interval == .1

    delay = backoff.next()
    assert delay == backoff.interval
    assert backoff.pending_retries == backoff.retries - 1

    delay = backoff.next()
    assert delay == backoff.interval
    assert backoff.pending_retries == backoff.retries - 2

    backoff.reset()
    assert backoff.retries == 10
    assert backoff.interval == .1
    assert backoff.pending_retries == backoff.retries
Exemple #13
0
def test_constant_backoff_defaults():
    backoff = ConstantBackoff()
    assert backoff.retries == 10
    assert backoff.interval == .1
    assert backoff.pending_retries == backoff.retries
Exemple #14
0
def test_constant_backoff_params():
    backoff = ConstantBackoff(interval=.5, retries=5)
    assert backoff.retries == 5
    assert backoff.interval == .5
    assert backoff.pending_retries == backoff.retries