async def test_wrap_method_with_overriding_retry_deadline(
        utcnow, unused_sleep):
    fake_call = grpc_helpers_async.FakeUnaryUnaryCall(42)
    method = mock.Mock(
        spec=aio.UnaryUnaryMultiCallable,
        side_effect=([exceptions.InternalServerError(None)] * 4) + [fake_call],
    )

    default_retry = retry_async.AsyncRetry()
    default_timeout = timeout.ExponentialTimeout(deadline=60)
    wrapped_method = gapic_v1.method_async.wrap_method(method, default_retry,
                                                       default_timeout)

    # Overriding only the retry's deadline should also override the timeout's
    # deadline.
    result = await wrapped_method(retry=default_retry.with_deadline(30))

    assert result == 42
    timeout_args = [call[1]["timeout"] for call in method.call_args_list]
    assert timeout_args == [5.0, 10.0, 20.0, 26.0, 25.0]
    assert utcnow.call_count == (
        1 + 1  # Compute wait_for timeout in retry_async
        + 5  # First to set the deadline.
        + 5  # One for each min(timeout, maximum, (DEADLINE - NOW).seconds)
    )
Example #2
0
def _timeout_from_retry_config(retry_params):
    """Creates a ExponentialTimeout 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
            }

    Returns:
        google.google-api-core.retry.ExponentialTimeout: The default time object for
            the method.
    """
    return timeout.ExponentialTimeout(
        initial=(retry_params["initial_rpc_timeout_millis"] /
                 _MILLIS_PER_SECOND),
        maximum=(retry_params["max_rpc_timeout_millis"] / _MILLIS_PER_SECOND),
        multiplier=retry_params["rpc_timeout_multiplier"],
        deadline=(retry_params["total_timeout_millis"] / _MILLIS_PER_SECOND),
    )
Example #3
0
 def test_with_timeout(self):
     original_timeout = timeout.ExponentialTimeout()
     timeout_ = original_timeout.with_deadline(42)
     assert original_timeout is not timeout_
     assert timeout_._initial == timeout._DEFAULT_INITIAL_TIMEOUT
     assert timeout_._maximum == timeout._DEFAULT_MAXIMUM_TIMEOUT
     assert timeout_._multiplier == timeout._DEFAULT_TIMEOUT_MULTIPLIER
     assert timeout_._deadline == 42
Example #4
0
    def test_apply_passthrough(self):
        target = mock.Mock(spec=['__call__', '__name__'], __name__='target')
        timeout_ = timeout.ExponentialTimeout(42.0, 100, 2)
        wrapped = timeout_(target)

        wrapped(1, 2, meep='moop')

        target.assert_called_once_with(1, 2, meep='moop', timeout=42.0)
Example #5
0
    def test_apply_passthrough(self):
        target = mock.Mock(spec=["__call__", "__name__"], __name__="target")
        timeout_ = timeout.ExponentialTimeout(42.0, 100, 2)
        wrapped = timeout_(target)

        wrapped(1, 2, meep="moop")

        target.assert_called_once_with(1, 2, meep="moop", timeout=42.0)
Example #6
0
    def test_apply(self):
        target = mock.Mock(spec=['__call__', '__name__'], __name__='target')
        timeout_ = timeout.ExponentialTimeout(1, 10, 2)
        wrapped = timeout_(target)

        wrapped()
        target.assert_called_with(timeout=1)

        wrapped()
        target.assert_called_with(timeout=2)

        wrapped()
        target.assert_called_with(timeout=4)
def test_wrap_method_with_overriding_retry_deadline(utcnow, unused_sleep):
    method = mock.Mock(
        spec=['__call__'],
        side_effect=([exceptions.InternalServerError(None)] * 4) + [42])
    default_retry = retry.Retry()
    default_timeout = timeout.ExponentialTimeout(deadline=60)
    wrapped_method = google.api_core.gapic_v1.method.wrap_method(
        method, default_retry, default_timeout)

    # Overriding only the retry's deadline should also override the timeout's
    # deadline.
    result = wrapped_method(retry=default_retry.with_deadline(30))

    assert result == 42
    timeout_args = [call[1]['timeout'] for call in method.call_args_list]
    assert timeout_args == [5.0, 10.0, 20.0, 26.0, 25.0]
    assert utcnow.call_count == (
        1 +  # First to set the deadline.
        5 +  # One for each min(timeout, maximum, (DEADLINE - NOW).seconds)
        5)
Example #8
0
    def _do_mutate_retryable_rows(self):
        """Mutate all the rows that are eligible for retry.

        A row is eligible for retry if it has not been tried or if it resulted
        in a transient error in a previous call.

        :rtype: list
        :return: The responses statuses, which is a list of
                 :class:`~google.rpc.status_pb2.Status`.
        :raises: One of the following:

                 * :exc:`~.table._BigtableRetryableError` if any
                   row returned a transient error.
                 * :exc:`RuntimeError` if the number of responses doesn't
                   match the number of rows that were retried
        """
        retryable_rows = []
        index_into_all_rows = []
        for index, status in enumerate(self.responses_statuses):
            if self._is_retryable(status):
                retryable_rows.append(self.rows[index])
                index_into_all_rows.append(index)

        if not retryable_rows:
            # All mutations are either successful or non-retryable now.
            return self.responses_statuses

        mutate_rows_request = _mutate_rows_request(
            self.table_name,
            retryable_rows,
            app_profile_id=self.app_profile_id)
        data_client = self.client.table_data_client
        inner_api_calls = data_client._inner_api_calls
        if "mutate_rows" not in inner_api_calls:
            default_retry = (data_client._method_configs["MutateRows"].retry, )
            if self.timeout is None:
                default_timeout = data_client._method_configs[
                    "MutateRows"].timeout
            else:
                default_timeout = timeout.ExponentialTimeout(
                    deadline=self.timeout)
            data_client._inner_api_calls["mutate_rows"] = wrap_method(
                data_client.transport.mutate_rows,
                default_retry=default_retry,
                default_timeout=default_timeout,
                client_info=data_client._client_info,
            )

        responses = data_client._inner_api_calls["mutate_rows"](
            mutate_rows_request, retry=None)

        num_responses = 0
        num_retryable_responses = 0
        for response in responses:
            for entry in response.entries:
                num_responses += 1
                index = index_into_all_rows[entry.index]
                self.responses_statuses[index] = entry.status
                if self._is_retryable(entry.status):
                    num_retryable_responses += 1
                if entry.status.code == 0:
                    self.rows[index].clear()

        if len(retryable_rows) != num_responses:
            raise RuntimeError(
                "Unexpected number of responses",
                num_responses,
                "Expected",
                len(retryable_rows),
            )

        if num_retryable_responses:
            raise _BigtableRetryableError

        return self.responses_statuses
Example #9
0
 def test_constructor_args(self):
     timeout_ = timeout.ExponentialTimeout(1, 2, 3, 4)
     assert timeout_._initial == 1
     assert timeout_._maximum == 2
     assert timeout_._multiplier == 3
     assert timeout_._deadline == 4
Example #10
0
 def test_constructor(self):
     timeout_ = timeout.ExponentialTimeout()
     assert timeout_._initial == timeout._DEFAULT_INITIAL_TIMEOUT
     assert timeout_._maximum == timeout._DEFAULT_MAXIMUM_TIMEOUT
     assert timeout_._multiplier == timeout._DEFAULT_TIMEOUT_MULTIPLIER
     assert timeout_._deadline == timeout._DEFAULT_DEADLINE
Example #11
0
 def test___str__(self):
     timeout_ = timeout.ExponentialTimeout(1, 2, 3, 4)
     assert str(timeout_) == (
         '<ExponentialTimeout initial=1.0, maximum=2.0, multiplier=3.0, '
         'deadline=4.0>')