def test_retry_target_non_retryable_error(utcnow, sleep): predicate = retry.if_exception_type(ValueError) exception = TypeError() target = mock.Mock(side_effect=exception) with pytest.raises(TypeError) as exc_info: retry.retry_target(target, predicate, range(10), None) assert exc_info.value == exception sleep.assert_not_called()
def _retry_and_handle(self, msg, conn, fn): """retry a function call within the context of exception_handler.""" with self.exception_handler(msg): return retry.retry_target(target=fn, predicate=_ErrorCounter( self.get_retries(conn)).count_error, sleep_generator=self._retry_generator(), deadline=None)
def test_retry_target_deadline_exceeded(utcnow, sleep): predicate = retry.if_exception_type(ValueError) exception = ValueError('meep') target = mock.Mock(side_effect=exception) # Setup the timeline so that the first call takes 5 seconds but the second # call takes 6, which puts the retry over the deadline. utcnow.side_effect = [ # The first call to utcnow establishes the start of the timeline. datetime.datetime.min, datetime.datetime.min + datetime.timedelta(seconds=5), datetime.datetime.min + datetime.timedelta(seconds=11)] with pytest.raises(exceptions.RetryError) as exc_info: retry.retry_target(target, predicate, range(10), deadline=10) assert exc_info.value.cause == exception assert exc_info.match('Deadline of 10.0s exceeded') assert exc_info.match('last exception: meep') assert target.call_count == 2
def test_retry_target_deadline_exceeded(utcnow, sleep): predicate = retry.if_exception_type(ValueError) exception = ValueError("meep") target = mock.Mock(side_effect=exception) # Setup the timeline so that the first call takes 5 seconds but the second # call takes 6, which puts the retry over the deadline. utcnow.side_effect = [ # The first call to utcnow establishes the start of the timeline. datetime.datetime.min, datetime.datetime.min + datetime.timedelta(seconds=5), datetime.datetime.min + datetime.timedelta(seconds=11), ] with pytest.raises(exceptions.RetryError) as exc_info: retry.retry_target(target, predicate, range(10), deadline=10) assert exc_info.value.cause == exception assert exc_info.match("Deadline of 10.0s exceeded") assert exc_info.match("last exception: meep") assert target.call_count == 2
def test_retry_target_success(utcnow, sleep): predicate = retry.if_exception_type(ValueError) call_count = [0] def target(): call_count[0] += 1 if call_count[0] < 3: raise ValueError() return 42 result = retry.retry_target(target, predicate, range(10), None) assert result == 42 assert call_count[0] == 3 sleep.assert_has_calls([mock.call(0), mock.call(1)])
def _retry_and_handle(self, msg, conn, fn): """retry a function call within the context of exception_handler.""" def reopen_conn_on_error(error): if isinstance(error, REOPENABLE_ERRORS): logger.warning('Reopening connection after {!r}', error) self.close(conn) self.open(conn) return with self.exception_handler(msg): return retry.retry_target( target=fn, predicate=_ErrorCounter(self.get_retries(conn)).count_error, sleep_generator=self._retry_generator(), deadline=None, on_error=reopen_conn_on_error)
def test_retry_target_w_on_error(utcnow, sleep): predicate = retry.if_exception_type(ValueError) call_count = {"target": 0} to_raise = ValueError() def target(): call_count["target"] += 1 if call_count["target"] < 3: raise to_raise return 42 on_error = mock.Mock() result = retry.retry_target(target, predicate, range(10), None, on_error=on_error) assert result == 42 assert call_count["target"] == 3 on_error.assert_has_calls([mock.call(to_raise), mock.call(to_raise)]) sleep.assert_has_calls([mock.call(0), mock.call(1)])
def test_retry_target_bad_sleep_generator(): with pytest.raises(ValueError, match="Sleep generator"): retry.retry_target(mock.sentinel.target, mock.sentinel.predicate, [], None)