def _retry_from_retry_config(retry_params, retry_codes): """Creates a Retry object given a gapic retry configuration. Args: retry_params (dict): The retry parameter values, for example:: { "initial_retry_delay_millis": 1000, "retry_delay_multiplier": 2.5, "max_retry_delay_millis": 120000, "initial_rpc_timeout_millis": 120000, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 120000, "total_timeout_millis": 600000 } retry_codes (sequence[str]): The list of retryable gRPC error code names. Returns: google.api.core.retry.Retry: The default retry object for the method. """ exception_classes = [ _exception_class_for_grpc_status_name(code) for code in retry_codes ] return retry.Retry( retry.if_exception_type(*exception_classes), initial=(retry_params['initial_retry_delay_millis'] / _MILLIS_PER_SECOND), maximum=(retry_params['max_retry_delay_millis'] / _MILLIS_PER_SECOND), multiplier=retry_params['retry_delay_multiplier'], deadline=retry_params['total_timeout_millis'] / _MILLIS_PER_SECOND)
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 test_wrap_method_with_overriding_retry_and_timeout(unusued_sleep): method = mock.Mock(spec=['__call__'], side_effect=[exceptions.NotFound(None), 42]) default_retry = retry.Retry() default_timeout = timeout.ConstantTimeout(60) wrapped_method = google.api.core.gapic_v1.method.wrap_method( method, default_retry, default_timeout) result = wrapped_method(retry=retry.Retry( retry.if_exception_type(exceptions.NotFound)), timeout=timeout.ConstantTimeout(22)) assert result == 42 assert method.call_count == 2 method.assert_called_with(timeout=22, metadata=mock.ANY)
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 test___call___and_execute_retry(self, sleep, uniform): retry_ = retry.Retry(predicate=retry.if_exception_type(ValueError)) target = mock.Mock(spec=['__call__'], side_effect=[ValueError(), 42]) # __name__ is needed by functools.partial. target.__name__ = 'target' decorated = retry_(target) target.assert_not_called() result = decorated('meep') assert result == 42 assert target.call_count == 2 target.assert_has_calls([mock.call('meep'), mock.call('meep')]) sleep.assert_called_once_with(retry_._initial)
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 _blocking_poll(self, timeout=None): """Poll and wait for the Future to be resolved. Args: timeout (int): How long to wait for the operation to complete. If None, wait indefinitely. """ if self._result_set: return retry_ = retry.Retry( predicate=retry.if_exception_type(_OperationNotComplete), deadline=timeout) try: retry_(self._done_or_raise)() except exceptions.RetryError: raise concurrent.futures.TimeoutError( 'Operation did not complete within the designated ' 'timeout.')
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_if_exception_type_multiple(): predicate = retry.if_exception_type(ValueError, TypeError) assert predicate(ValueError()) assert predicate(TypeError()) assert not predicate(RuntimeError())
def test_if_exception_type(): predicate = retry.if_exception_type(ValueError) assert predicate(ValueError()) assert not predicate(TypeError())