def test_backoff_basic(failure, strategy, max_tries, max_delay, retry_execute):
    """Test the :ref:`backoff_utils._backoff.backoff` function."""
    global _attempts  # pylint: disable=W0603,C0103
    if not failure:
        with pytest.raises(ZeroDivisionError) as excinfo:
            start_time = datetime.utcnow()
            backoff(to_execute=divide_by_zero_function,
                    args=[False],
                    kwargs=None,
                    strategy=strategy,
                    retry_execute=retry_execute,
                    retry_args=[True],
                    retry_kwargs=None,
                    max_tries=max_tries,
                    max_delay=max_delay,
                    catch_exceptions=[type(ZeroDivisionError())],
                    on_failure=None,
                    on_success=None)
        end_time = datetime.utcnow()
        elapsed_time = start_time - end_time
        elapsed_time = elapsed_time.total_seconds()
        if max_delay is not None:
            assert elapsed_time <= max_delay
            assert _attempts <= max_tries
        else:
            assert _attempts == max_tries
        assert 'Subsequent Attempt' in str(excinfo.value)
    else:
        with pytest.raises(failure):
            start_time = datetime.utcnow()
            backoff(to_execute=divide_by_zero_function,
                    args=[False],
                    kwargs=None,
                    strategy=strategy,
                    retry_execute=retry_execute,
                    retry_args=[True],
                    retry_kwargs=None,
                    max_tries=max_tries,
                    max_delay=max_delay,
                    catch_exceptions=[type(ZeroDivisionError())],
                    on_failure=None,
                    on_success=None)
        end_time = datetime.utcnow()
        elapsed_time = start_time - end_time
        elapsed_time = elapsed_time.total_seconds()

    _attempts = 0
 def wrapper(*args, **kwargs):
     return backoff(to_execute=func,
                    args=args,
                    kwargs=kwargs,
                    strategy=strategy,
                    max_tries=max_tries,
                    max_delay=max_delay,
                    catch_exceptions=catch_exceptions,
                    on_failure=on_failure,
                    on_success=on_success)
def test_backoff_on_failure_function(strategy, max_tries, on_failure):
    """Test the :ref:`backoff_utils._backoff.backoff` function."""
    global _attempts  # pylint: disable=W0603,C0103
    global _was_successful  # pylint: disable=W0603,C0103

    with pytest.raises(AttributeError) as excinfo:
        backoff(to_execute=divide_by_zero_function,
                args=[False],
                kwargs=None,
                strategy=strategy,
                retry_execute=None,
                retry_args=[True],
                retry_kwargs=None,
                max_tries=max_tries,
                catch_exceptions=[type(ZeroDivisionError())],
                on_failure=on_failure,
                on_success=None)
    assert _attempts == max_tries
    assert _was_successful is False
    _attempts = 0
    _was_successful = False
def test_backoff_on_success(strategy, max_tries, on_success):
    """Test the :ref:`backoff_utils._backoff.backoff` function."""
    global _attempts  # pylint: disable=W0603,C0103
    global _was_successful  # pylint: disable=W0603,C0103

    return_value = backoff(to_execute=successful_function,
                           args=[False, max_tries],
                           kwargs=None,
                           strategy=strategy,
                           retry_execute=None,
                           retry_args=[True, max_tries],
                           retry_kwargs=None,
                           max_tries=max_tries,
                           catch_exceptions=[type(ZeroDivisionError())],
                           on_failure=None,
                           on_success=on_success)
    assert _attempts == max_tries
    assert _was_successful is True
    assert return_value == successful_function(True, max_tries)
    _attempts = 0
    _was_successful = False