Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions google/cloud/storage/_experimental/asyncio/async_grpc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"""An async client for interacting with Google Cloud Storage using the gRPC API."""

from google.cloud import _storage_v2 as storage_v2
from google.cloud._storage_v2.services.storage.transports.base import (
DEFAULT_CLIENT_INFO,
)


class AsyncGrpcClient:
Expand All @@ -30,7 +33,7 @@ class AsyncGrpcClient:
The client info used to send a user-agent string along with API
requests. If ``None``, then default info will be used.

:type client_options: :class:`~google.api_core.client_options.ClientOptions` or :class:`dict`
:type client_options: :class:`~google.api_core.client_options.ClientOptions`
:param client_options: (Optional) Client options used to set user options
on the client.

Expand All @@ -39,7 +42,6 @@ class AsyncGrpcClient:
(Optional) Whether to attempt to use DirectPath for gRPC connections.
Defaults to ``True``.
"""

def __init__(
self,
credentials=None,
Expand All @@ -65,8 +67,15 @@ def _create_async_grpc_client(
transport_cls = storage_v2.StorageAsyncClient.get_transport_class(
"grpc_asyncio"
)

if client_info is None:
client_info = DEFAULT_CLIENT_INFO
primary_user_agent = client_info.to_user_agent()

channel = transport_cls.create_channel(
attempt_direct_path=attempt_direct_path, credentials=credentials
attempt_direct_path=attempt_direct_path,
credentials=credentials,
options=(("grpc.primary_user_agent", primary_user_agent),),
)
transport = transport_cls(channel=channel)

Expand Down
67 changes: 56 additions & 11 deletions tests/unit/asyncio/test_async_grpc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
from unittest import mock
from google.auth import credentials as auth_credentials
from google.auth.credentials import AnonymousCredentials
from google.api_core import client_info as client_info_lib
from google.cloud.storage._experimental.asyncio import async_grpc_client
from google.cloud.storage._experimental.asyncio.async_grpc_client import (
DEFAULT_CLIENT_INFO,
)


def _make_credentials(spec=None):
Expand All @@ -27,32 +32,60 @@ def _make_credentials(spec=None):
class TestAsyncGrpcClient(unittest.TestCase):
@mock.patch("google.cloud._storage_v2.StorageAsyncClient")
def test_constructor_default_options(self, mock_async_storage_client):
from google.cloud.storage._experimental.asyncio import async_grpc_client

# Arrange
mock_transport_cls = mock.MagicMock()
mock_async_storage_client.get_transport_class.return_value = mock_transport_cls
mock_creds = _make_credentials()

primary_user_agent = DEFAULT_CLIENT_INFO.to_user_agent()
expected_options = (("grpc.primary_user_agent", primary_user_agent),)

# Act
async_grpc_client.AsyncGrpcClient(credentials=mock_creds)

# Assert
mock_async_storage_client.get_transport_class.assert_called_once_with(
"grpc_asyncio"
)
mock_transport_cls.create_channel.assert_called_once_with(
attempt_direct_path=True, credentials=mock_creds
attempt_direct_path=True,
credentials=mock_creds,
options=expected_options,
)
mock_channel = mock_transport_cls.create_channel.return_value
mock_transport_cls.assert_called_once_with(channel=mock_channel)
mock_transport = mock_transport_cls.return_value
mock_async_storage_client.assert_called_once_with(
transport=mock_transport,
client_options=None,
client_info=None,
client_info=DEFAULT_CLIENT_INFO,
)

@mock.patch("google.cloud._storage_v2.StorageAsyncClient")
def test_constructor_with_client_info(self, mock_async_storage_client):

mock_transport_cls = mock.MagicMock()
mock_async_storage_client.get_transport_class.return_value = mock_transport_cls
mock_creds = _make_credentials()
client_info = client_info_lib.ClientInfo(
client_library_version="1.2.3",
)

async_grpc_client.AsyncGrpcClient(
credentials=mock_creds, client_info=client_info
)

primary_user_agent = client_info.to_user_agent()
expected_options = (("grpc.primary_user_agent", primary_user_agent),)

mock_transport_cls.create_channel.assert_called_once_with(
attempt_direct_path=True,
credentials=mock_creds,
options=expected_options,
)

@mock.patch("google.cloud._storage_v2.StorageAsyncClient")
def test_constructor_disables_directpath(self, mock_async_storage_client):
from google.cloud.storage._experimental.asyncio import async_grpc_client

mock_transport_cls = mock.MagicMock()
mock_async_storage_client.get_transport_class.return_value = mock_transport_cls
Expand All @@ -62,15 +95,19 @@ def test_constructor_disables_directpath(self, mock_async_storage_client):
credentials=mock_creds, attempt_direct_path=False
)

primary_user_agent = DEFAULT_CLIENT_INFO.to_user_agent()
expected_options = (("grpc.primary_user_agent", primary_user_agent),)

mock_transport_cls.create_channel.assert_called_once_with(
attempt_direct_path=False, credentials=mock_creds
attempt_direct_path=False,
credentials=mock_creds,
options=expected_options,
)
mock_channel = mock_transport_cls.create_channel.return_value
mock_transport_cls.assert_called_once_with(channel=mock_channel)

@mock.patch("google.cloud._storage_v2.StorageAsyncClient")
def test_grpc_client_property(self, mock_grpc_gapic_client):
from google.cloud.storage._experimental.asyncio import async_grpc_client

# Arrange
mock_transport_cls = mock.MagicMock()
Expand All @@ -81,7 +118,8 @@ def test_grpc_client_property(self, mock_grpc_gapic_client):
mock_transport_cls.return_value = mock.sentinel.transport

mock_creds = _make_credentials()
mock_client_info = mock.sentinel.client_info
mock_client_info = mock.MagicMock(spec=client_info_lib.ClientInfo)
mock_client_info.to_user_agent.return_value = "test-user-agent"
mock_client_options = mock.sentinel.client_options
mock_attempt_direct_path = mock.sentinel.attempt_direct_path

Expand All @@ -102,8 +140,11 @@ def test_grpc_client_property(self, mock_grpc_gapic_client):
retrieved_client = client.grpc_client

# Assert
expected_options = (("grpc.primary_user_agent", "test-user-agent"),)
mock_transport_cls.create_channel.assert_called_once_with(
attempt_direct_path=mock_attempt_direct_path, credentials=mock_creds
attempt_direct_path=mock_attempt_direct_path,
credentials=mock_creds,
options=expected_options,
)
mock_transport_cls.assere_with(channel=channel_sentinel)
mock_grpc_gapic_client.assert_called_once_with(
Expand All @@ -115,7 +156,6 @@ def test_grpc_client_property(self, mock_grpc_gapic_client):

@mock.patch("google.cloud._storage_v2.StorageAsyncClient")
def test_grpc_client_with_anon_creds(self, mock_grpc_gapic_client):
from google.cloud.storage._experimental.asyncio import async_grpc_client

# Arrange
mock_transport_cls = mock.MagicMock()
Expand All @@ -133,7 +173,12 @@ def test_grpc_client_with_anon_creds(self, mock_grpc_gapic_client):
# Assert
self.assertIs(retrieved_client, mock_grpc_gapic_client.return_value)

primary_user_agent = DEFAULT_CLIENT_INFO.to_user_agent()
expected_options = (("grpc.primary_user_agent", primary_user_agent),)

mock_transport_cls.create_channel.assert_called_once_with(
attempt_direct_path=True, credentials=anonymous_creds
attempt_direct_path=True,
credentials=anonymous_creds,
options=expected_options,
)
mock_transport_cls.assert_called_once_with(channel=channel_sentinel)