def test__should_recover_true():
    manager = make_manager()

    details = "UNAVAILABLE. Service taking nap."
    exc = exceptions.ServiceUnavailable(details)

    assert manager._should_recover(exc) is True
def test_api_retry_5xx_errors(client_constructor):
    grpc_client = setup_mock_(client_constructor)
    grpc_client.get_quantum_program.side_effect = exceptions.ServiceUnavailable('internal error')

    client = EngineClient(max_retry_delay_seconds=0.3)
    with pytest.raises(TimeoutError, match='Reached max retry attempts.*internal error'):
        client.get_program('proj', 'prog', False)
    assert grpc_client.get_quantum_program.call_count == 3
Example #3
0
def test__commit_with_retry_success_third_attempt(_sleep):
    from google.api_core import exceptions
    from google.cloud.firestore_v1.services.firestore import client as firestore_client
    from google.cloud.firestore_v1.transaction import _commit_with_retry

    # Create a minimal fake GAPIC with a dummy result.
    firestore_api = mock.create_autospec(firestore_client.FirestoreClient,
                                         instance=True)
    # Make sure the first two requests fail and the third succeeds.
    firestore_api.commit.side_effect = [
        exceptions.ServiceUnavailable("Server sleepy."),
        exceptions.ServiceUnavailable("Server groggy."),
        mock.sentinel.commit_response,
    ]

    # Attach the fake GAPIC to a real client.
    client = _make_client("outside")
    client._firestore_api_internal = firestore_api

    # Call function and check result.
    txn_id = b"the-world\x00"
    commit_response = _commit_with_retry(client, mock.sentinel.write_pbs,
                                         txn_id)
    assert commit_response is mock.sentinel.commit_response

    # Verify mocks used.
    # Ensure _sleep is called after commit failures, with intervals of 1 and 2 seconds
    assert _sleep.call_count == 2
    _sleep.assert_any_call(1.0)
    _sleep.assert_any_call(2.0)
    # commit() called same way 3 times.
    commit_call = mock.call(
        request={
            "database": client._database_string,
            "writes": mock.sentinel.write_pbs,
            "transaction": txn_id,
        },
        metadata=client._rpc_metadata,
    )
    assert firestore_api.commit.mock_calls == [
        commit_call, commit_call, commit_call
    ]
def test_api_retry_times(client_constructor, mock_sleep):
    grpc_client = setup_mock_(client_constructor)
    grpc_client.get_quantum_program.side_effect = exceptions.ServiceUnavailable('internal error')

    client = EngineClient(max_retry_delay_seconds=0.3)
    with pytest.raises(TimeoutError, match='Reached max retry attempts.*internal error'):
        client.get_program('proj', 'prog', False)
    assert grpc_client.get_quantum_program.call_count == 3

    assert len(mock_sleep.call_args_list) == 2
    assert all(x == y for (x, _), y in zip(mock_sleep.call_args_list, [(0.1,), (0.2,)]))
Example #5
0
def test_api_retry_5xx_errors(client_constructor):
    client = mock.Mock()
    client_constructor.return_value = client
    client.get_quantum_program.side_effect = exceptions.ServiceUnavailable(
        'internal error')

    engine = cg.Engine(project_id='project-id')
    with pytest.raises(TimeoutError,
                       match='Reached max retry attempts.*internal error'):
        engine.max_retry_delay = 1  # 1 second
        engine.get_program('foo')
    assert client.get_quantum_program.call_count > 1
Example #6
0
    async def test_success_third_attempt(self, _sleep):
        from google.api_core import exceptions

        # Create a minimal fake GAPIC with a dummy result.
        firestore_api = AsyncMock()

        # Make sure the first two requests fail and the third succeeds.
        firestore_api.commit.side_effect = [
            exceptions.ServiceUnavailable("Server sleepy."),
            exceptions.ServiceUnavailable("Server groggy."),
            mock.sentinel.commit_response,
        ]

        # Attach the fake GAPIC to a real client.
        client = _make_client("outside")
        client._firestore_api_internal = firestore_api

        # Call function and check result.
        txn_id = b"the-world\x00"
        commit_response = await self._call_fut(client, mock.sentinel.write_pbs, txn_id)
        self.assertIs(commit_response, mock.sentinel.commit_response)

        # Verify mocks used.
        # Ensure _sleep is called after commit failures, with intervals of 1 and 2 seconds
        self.assertEqual(_sleep.call_count, 2)
        _sleep.assert_any_call(1.0)
        _sleep.assert_any_call(2.0)
        # commit() called same way 3 times.
        commit_call = mock.call(
            request={
                "database": client._database_string,
                "writes": mock.sentinel.write_pbs,
                "transaction": txn_id,
            },
            metadata=client._rpc_metadata,
        )
        self.assertEqual(
            firestore_api.commit.mock_calls, [commit_call, commit_call, commit_call]
        )
Example #7
0
    def test_success_third_attempt(self, _sleep):
        from google.api_core import exceptions
        from google.cloud.firestore_v1.gapic import firestore_client

        # Create a minimal fake GAPIC with a dummy result.
        firestore_api = mock.create_autospec(
            firestore_client.FirestoreClient, instance=True
        )
        # Make sure the first two requests fail and the third succeeds.
        firestore_api.commit.side_effect = [
            exceptions.ServiceUnavailable("Server sleepy."),
            exceptions.ServiceUnavailable("Server groggy."),
            mock.sentinel.commit_response,
        ]

        # Attach the fake GAPIC to a real client.
        client = _make_client("outside")
        client._firestore_api_internal = firestore_api

        # Call function and check result.
        txn_id = b"the-world\x00"
        commit_response = self._call_fut(client, mock.sentinel.write_pbs, txn_id)
        self.assertIs(commit_response, mock.sentinel.commit_response)

        # Verify mocks used.
        self.assertEqual(_sleep.call_count, 2)
        _sleep.assert_any_call(1.0)
        _sleep.assert_any_call(2.0)
        # commit() called same way 3 times.
        commit_call = mock.call(
            client._database_string,
            mock.sentinel.write_pbs,
            transaction=txn_id,
            metadata=client._rpc_metadata,
        )
        self.assertEqual(
            firestore_api.commit.mock_calls, [commit_call, commit_call, commit_call]
        )
def test_retry_nonidempotent(echo):
    # Define our error and OK responses.
    err = exceptions.ServiceUnavailable(message='whups')
    ok = showcase_v1alpha3.EchoResponse(content='foo')
    server = mock.Mock(side_effect=(err, err, ok))

    # Mock the transport to send back the error responses followed by a
    # success response.
    transport = type(echo).get_transport_class()
    with mock.patch.object(
            transport, 'echo',
            new_callable=mock.PropertyMock(return_value=server)):
        with mock.patch.object(time, 'sleep'):
            response = echo.echo({'content': 'bar'})
        assert response.content == 'foo'
        assert server.call_count == 3
Example #9
0
def test_do_not_disclose_cache_contents(begin_transaction, client_context):
    """Regression test for #482.

    https://github.com/googleapis/python-ndb/issues/482
    """
    begin_transaction.side_effect = core_exceptions.ServiceUnavailable("Spurious Error")

    client_context.cache["hello dad"] = "i'm in jail"

    @ndb.transactional()
    def callback():
        pass

    with pytest.raises(Exception) as error_info:
        callback()

    error = error_info.value
    message = "".join(traceback.format_exception_only(type(error), error))
    assert "hello dad" not in message
Example #10
0
    def test_consumer_expected_error(self, caplog):
        caplog.set_level(logging.DEBUG)

        bidi_rpc = mock.create_autospec(bidi.BidiRpc, instance=True)
        bidi_rpc.is_active = True
        bidi_rpc.recv.side_effect = exceptions.ServiceUnavailable('Gone away')

        on_response = mock.Mock(spec=['__call__'])

        consumer = bidi.BackgroundConsumer(bidi_rpc, on_response)

        consumer.start()

        # Wait for the consumer's thread to exit.
        while consumer.is_active:
            pass

        on_response.assert_not_called()
        bidi_rpc.recv.assert_called_once()
        assert 'caught error' in caplog.text
def test_retry_idempotent(identity):
    # Define our error and OK responses.
    err409 = exceptions.Aborted(message='derp de derp')
    err503 = exceptions.ServiceUnavailable(message='whups')
    errwtf = exceptions.Unknown(message='huh?')
    ok = showcase_v1alpha3.User(name='users/0', display_name='Guido')
    server = mock.Mock(side_effect=(err409, err503, errwtf, ok))

    # Mock the transport to send back the error responses followed by a
    # success response.
    transport = type(identity).get_transport_class()
    with mock.patch.object(
            transport,
            'get_user',
            new_callable=mock.PropertyMock(return_value=server)):
        with mock.patch.object(time, 'sleep'):
            response = identity.get_user({'name': 'users/0'})
        assert response.name == 'users/0'
        assert response.display_name == 'Guido'
        assert server.call_count == 4
Example #12
0
def retry_grpc(num_retries: int, fn: Callable[..., ReturnType], *args: Any,
               **kwargs: Any) -> ReturnType:
    """Retries a function call some number of times"""
    time_to_sleep = random.uniform(5, RETRY_SLEEP)
    for i in range(num_retries + 1):
        try:
            return fn(*args, **kwargs)
        except exceptions.InternalServerError as e:
            if i == num_retries:
                raise
            if 'GOAWAY' in str(e) or 'Deadline Exceeded' in str(e):
                logging.exception('Received exception: ')
                if environment.in_gae():
                    logging.warning('Sleeping %.2f seconds and retrying',
                                    time_to_sleep)
                    time.sleep(time_to_sleep)
                    continue
            else:
                raise
    raise exceptions.ServiceUnavailable(
        f"Function unsuccessful {num_retries + 1} times")
    def test_failure_second_attempt(self, _sleep):
        from google.api_core import exceptions
        from google.cloud.firestore_v1.services.firestore import (
            client as firestore_client, )

        # Create a minimal fake GAPIC with a dummy result.
        firestore_api = mock.create_autospec(firestore_client.FirestoreClient,
                                             instance=True)
        # Make sure the first request fails retry-able and second
        # fails non-retryable.
        exc1 = exceptions.ServiceUnavailable("Come back next time.")
        exc2 = exceptions.InternalServerError("Server on fritz.")
        firestore_api.commit.side_effect = [exc1, exc2]

        # Attach the fake GAPIC to a real client.
        client = _make_client("peanut-butter")
        client._firestore_api_internal = firestore_api

        # Call function and check result.
        txn_id = b"the-journey-when-and-where-well-go"
        with self.assertRaises(exceptions.InternalServerError) as exc_info:
            self._call_fut(client, mock.sentinel.write_pbs, txn_id)

        self.assertIs(exc_info.exception, exc2)

        # Verify mocks used.
        _sleep.assert_called_once_with(1.0)
        # commit() called same way 2 times.
        commit_call = mock.call(
            request={
                "database": client._database_string,
                "writes": mock.sentinel.write_pbs,
                "transaction": txn_id,
            },
            metadata=client._rpc_metadata,
        )
        self.assertEqual(firestore_api.commit.mock_calls,
                         [commit_call, commit_call])
Example #14
0
async def test__commit_with_retry_failure_second_attempt(_sleep):
    from google.api_core import exceptions
    from google.cloud.firestore_v1.async_transaction import _commit_with_retry

    # Create a minimal fake GAPIC with a dummy result.
    firestore_api = AsyncMock()

    # Make sure the first request fails retry-able and second
    # fails non-retryable.
    exc1 = exceptions.ServiceUnavailable("Come back next time.")
    exc2 = exceptions.InternalServerError("Server on fritz.")
    firestore_api.commit.side_effect = [exc1, exc2]

    # Attach the fake GAPIC to a real client.
    client = _make_client("peanut-butter")
    client._firestore_api_internal = firestore_api

    # Call function and check result.
    txn_id = b"the-journey-when-and-where-well-go"
    with pytest.raises(exceptions.InternalServerError) as exc_info:
        await _commit_with_retry(client, mock.sentinel.write_pbs, txn_id)

    assert exc_info.value is exc2

    # Verify mocks used.
    _sleep.assert_called_once_with(1.0)
    # commit() called same way 2 times.
    commit_call = mock.call(
        request={
            "database": client._database_string,
            "writes": mock.sentinel.write_pbs,
            "transaction": txn_id,
        },
        metadata=client._rpc_metadata,
    )
    assert firestore_api.commit.mock_calls == [commit_call, commit_call]
Example #15
0
def test_if_transient_error():
    assert retry.if_transient_error(exceptions.InternalServerError(""))
    assert retry.if_transient_error(exceptions.TooManyRequests(""))
    assert retry.if_transient_error(exceptions.ServiceUnavailable(""))
    assert not retry.if_transient_error(exceptions.InvalidArgument(""))
Example #16
0
 def test_unavailable(core_retry):
     error = core_exceptions.ServiceUnavailable("testing")
     core_retry.if_transient_error.return_value = False
     assert _retry.is_transient_error(error) is True
     core_retry.if_transient_error.assert_called_once_with(error)