예제 #1
0
def test_async_retrier_run_success(MagicMock, coro):
    on_retry = MagicMock()
    retrier = AsyncRetrier(on_retry=on_retry)

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

    assert retrier.attempts == 0
    assert retrier.error is None
예제 #2
0
def test_async_retrier_run_valid_retries(MagicMock, coro):
    task = coro(4)
    on_retry = MagicMock()

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

    assert retrier.attempts == 3
    assert retrier.error is None
예제 #3
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)
예제 #4
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)
예제 #5
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
예제 #6
0
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)
예제 #7
0
def test_async_retrier_defaults():
    retrier = AsyncRetrier()
    assert retrier.error is None
    assert retrier.attempts == 0
    assert retrier.timeout is None
    assert retrier.on_retry is None
    assert retrier.evaluator is None
    assert retrier.sleep == asyncio.sleep
    assert isinstance(retrier.backoff, ConstantBackoff)
예제 #8
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
예제 #9
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)
예제 #10
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
예제 #11
0
def test_async_retrier_assestion_error():
    with pytest.raises(AssertionError):
        AsyncRetrier(timeout='foo')
    with pytest.raises(AssertionError):
        AsyncRetrier(timeout=-1)
예제 #12
0
def test_async_retrier_istimeout():
    assert AsyncRetrier().istimeout(1234) is False

    now = time.time() - 100
    assert AsyncRetrier(timeout=1).istimeout(now) is True