From 5638e04fd5aadeb61f56f770f264a81d4dbcbf91 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 14 Jul 2022 11:48:12 +0000 Subject: [PATCH] fix(deps): require google-api-core>=1.32.0,>=2.8.0 (#207) - [ ] Regenerate this pull request now. PiperOrigin-RevId: 460590348 Source-Link: https://github.com/googleapis/googleapis/commit/5688bdb18b2702a0e424ee0ed866951382d481ed Source-Link: https://github.com/googleapis/googleapis-gen/commit/c40b027fb36cd05689fc5291d201b5413939082e Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYzQwYjAyN2ZiMzZjZDA1Njg5ZmM1MjkxZDIwMWI1NDEzOTM5MDgyZSJ9 PiperOrigin-RevId: 459095142 Source-Link: https://github.com/googleapis/googleapis/commit/4f1be992601ed740a581a32cedc4e7b6c6a27793 Source-Link: https://github.com/googleapis/googleapis-gen/commit/ae686d9cde4fc3e36d0ac02efb8643b15890c1ed Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYWU2ODZkOWNkZTRmYzNlMzZkMGFjMDJlZmI4NjQzYjE1ODkwYzFlZCJ9 feat: add audience parameter PiperOrigin-RevId: 456827138 Source-Link: https://github.com/googleapis/googleapis/commit/23f1a157189581734c7a77cddfeb7c5bc1e440ae Source-Link: https://github.com/googleapis/googleapis-gen/commit/4075a8514f676691ec156688a5bbf183aa9893ce Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNDA3NWE4NTE0ZjY3NjY5MWVjMTU2Njg4YTViYmYxODNhYTk4OTNjZSJ9 --- .../services/iam_credentials/client.py | 1 + .../iam_credentials/transports/base.py | 16 +- .../iam_credentials/transports/grpc.py | 2 + .../transports/grpc_asyncio.py | 2 + .../iam_v2beta/services/policies/client.py | 1 + .../services/policies/transports/base.py | 16 +- .../services/policies/transports/grpc.py | 2 + .../policies/transports/grpc_asyncio.py | 2 + setup.py | 5 +- testing/constraints-3.6.txt | 10 - testing/constraints-3.7.txt | 2 +- tests/unit/gapic/credentials_v1/__init__.py | 15 - .../credentials_v1/test_iam_credentials.py | 2093 ----------------- .../test_iam_credentials.py | 52 + tests/unit/gapic/iam_v2beta/test_policies.py | 52 + 15 files changed, 138 insertions(+), 2133 deletions(-) delete mode 100644 testing/constraints-3.6.txt delete mode 100644 tests/unit/gapic/credentials_v1/__init__.py delete mode 100644 tests/unit/gapic/credentials_v1/test_iam_credentials.py diff --git a/google/cloud/iam_credentials_v1/services/iam_credentials/client.py b/google/cloud/iam_credentials_v1/services/iam_credentials/client.py index 70f8f04..086a9a9 100644 --- a/google/cloud/iam_credentials_v1/services/iam_credentials/client.py +++ b/google/cloud/iam_credentials_v1/services/iam_credentials/client.py @@ -435,6 +435,7 @@ def __init__( quota_project_id=client_options.quota_project_id, client_info=client_info, always_use_jwt_access=True, + api_audience=client_options.api_audience, ) def generate_access_token( diff --git a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/base.py b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/base.py index 098839b..b5987c5 100644 --- a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/base.py +++ b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/base.py @@ -54,6 +54,7 @@ def __init__( quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, **kwargs, ) -> None: """Instantiate the transport. @@ -81,11 +82,6 @@ def __init__( be used for service account credentials. """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. @@ -106,6 +102,11 @@ def __init__( credentials, _ = google.auth.default( **scopes_kwargs, quota_project_id=quota_project_id ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) # If the credentials are service account credentials, then always try to use self signed JWT. if ( @@ -118,6 +119,11 @@ def __init__( # Save the credentials. self._credentials = credentials + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc.py b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc.py index 0c81c2f..39c547a 100644 --- a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc.py +++ b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc.py @@ -66,6 +66,7 @@ def __init__( quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, ) -> None: """Instantiate the transport. @@ -161,6 +162,7 @@ def __init__( quota_project_id=quota_project_id, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, ) if not self._grpc_channel: diff --git a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc_asyncio.py b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc_asyncio.py index 8492618..fe09ef2 100644 --- a/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc_asyncio.py +++ b/google/cloud/iam_credentials_v1/services/iam_credentials/transports/grpc_asyncio.py @@ -111,6 +111,7 @@ def __init__( quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, ) -> None: """Instantiate the transport. @@ -206,6 +207,7 @@ def __init__( quota_project_id=quota_project_id, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, ) if not self._grpc_channel: diff --git a/google/cloud/iam_v2beta/services/policies/client.py b/google/cloud/iam_v2beta/services/policies/client.py index 971c105..d70c007 100644 --- a/google/cloud/iam_v2beta/services/policies/client.py +++ b/google/cloud/iam_v2beta/services/policies/client.py @@ -423,6 +423,7 @@ def __init__( quota_project_id=client_options.quota_project_id, client_info=client_info, always_use_jwt_access=True, + api_audience=client_options.api_audience, ) def list_policies( diff --git a/google/cloud/iam_v2beta/services/policies/transports/base.py b/google/cloud/iam_v2beta/services/policies/transports/base.py index b77547a..82e5648 100644 --- a/google/cloud/iam_v2beta/services/policies/transports/base.py +++ b/google/cloud/iam_v2beta/services/policies/transports/base.py @@ -56,6 +56,7 @@ def __init__( quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, **kwargs, ) -> None: """Instantiate the transport. @@ -83,11 +84,6 @@ def __init__( be used for service account credentials. """ - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} # Save the scopes. @@ -108,6 +104,11 @@ def __init__( credentials, _ = google.auth.default( **scopes_kwargs, quota_project_id=quota_project_id ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) # If the credentials are service account credentials, then always try to use self signed JWT. if ( @@ -120,6 +121,11 @@ def __init__( # Save the credentials. self._credentials = credentials + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/iam_v2beta/services/policies/transports/grpc.py b/google/cloud/iam_v2beta/services/policies/transports/grpc.py index 52b310f..e0f4471 100644 --- a/google/cloud/iam_v2beta/services/policies/transports/grpc.py +++ b/google/cloud/iam_v2beta/services/policies/transports/grpc.py @@ -60,6 +60,7 @@ def __init__( quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, ) -> None: """Instantiate the transport. @@ -156,6 +157,7 @@ def __init__( quota_project_id=quota_project_id, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, ) if not self._grpc_channel: diff --git a/google/cloud/iam_v2beta/services/policies/transports/grpc_asyncio.py b/google/cloud/iam_v2beta/services/policies/transports/grpc_asyncio.py index 5413011..0e03360 100644 --- a/google/cloud/iam_v2beta/services/policies/transports/grpc_asyncio.py +++ b/google/cloud/iam_v2beta/services/policies/transports/grpc_asyncio.py @@ -105,6 +105,7 @@ def __init__( quota_project_id=None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, ) -> None: """Instantiate the transport. @@ -201,6 +202,7 @@ def __init__( quota_project_id=quota_project_id, client_info=client_info, always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, ) if not self._grpc_channel: diff --git a/setup.py b/setup.py index 77fd080..b1dd2f3 100644 --- a/setup.py +++ b/setup.py @@ -28,10 +28,7 @@ # 'Development Status :: 5 - Production/Stable' release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - # NOTE: Maintainers, please do not require google-api-core>=2.x.x - # Until this issue is closed - # https://github.com/googleapis/google-cloud-python/issues/10566 - "google-api-core[grpc] >= 1.31.5, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0", + "google-api-core[grpc] >= 1.32.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*", "proto-plus >= 1.15.0, <2.0.0dev", "protobuf >= 3.19.0, <4.0.0dev", ] diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt deleted file mode 100644 index ec8ca20..0000000 --- a/testing/constraints-3.6.txt +++ /dev/null @@ -1,10 +0,0 @@ -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List *all* library dependencies and extras in this file. -# Pin the version to the lower bound. -# -# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", -# Then this file should have foo==1.14.0 -google-api-core==1.31.5 -proto-plus==1.15.0 -protobuf==3.19.0 diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt index ec8ca20..317c02d 100644 --- a/testing/constraints-3.7.txt +++ b/testing/constraints-3.7.txt @@ -5,6 +5,6 @@ # # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", # Then this file should have foo==1.14.0 -google-api-core==1.31.5 +google-api-core==1.32.0 proto-plus==1.15.0 protobuf==3.19.0 diff --git a/tests/unit/gapic/credentials_v1/__init__.py b/tests/unit/gapic/credentials_v1/__init__.py deleted file mode 100644 index 4de6597..0000000 --- a/tests/unit/gapic/credentials_v1/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# diff --git a/tests/unit/gapic/credentials_v1/test_iam_credentials.py b/tests/unit/gapic/credentials_v1/test_iam_credentials.py deleted file mode 100644 index ff3e657..0000000 --- a/tests/unit/gapic/credentials_v1/test_iam_credentials.py +++ /dev/null @@ -1,2093 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import math -import os - -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -import google.auth -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.oauth2 import service_account -from google.protobuf import duration_pb2 # type: ignore -from google.protobuf import timestamp_pb2 # type: ignore -import grpc -from grpc.experimental import aio -import mock -from proto.marshal.rules.dates import DurationRule, TimestampRule -import pytest - -from google.cloud.iam_credentials_v1.services.iam_credentials import ( - IAMCredentialsAsyncClient, - IAMCredentialsClient, - transports, -) -from google.cloud.iam_credentials_v1.types import common - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return ( - "foo.googleapis.com" - if ("localhost" in client.DEFAULT_ENDPOINT) - else client.DEFAULT_ENDPOINT - ) - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert IAMCredentialsClient._get_default_mtls_endpoint(None) is None - assert ( - IAMCredentialsClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - IAMCredentialsClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - IAMCredentialsClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - IAMCredentialsClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - IAMCredentialsClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - ) - - -@pytest.mark.parametrize( - "client_class", - [ - IAMCredentialsClient, - IAMCredentialsAsyncClient, - ], -) -def test_iam_credentials_client_from_service_account_info(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_info" - ) as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == "iamcredentials.googleapis.com:443" - - -@pytest.mark.parametrize( - "transport_class,transport_name", - [ - (transports.IAMCredentialsGrpcTransport, "grpc"), - (transports.IAMCredentialsGrpcAsyncIOTransport, "grpc_asyncio"), - ], -) -def test_iam_credentials_client_service_account_always_use_jwt( - transport_class, transport_name -): - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object( - service_account.Credentials, "with_always_use_jwt_access", create=True - ) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize( - "client_class", - [ - IAMCredentialsClient, - IAMCredentialsAsyncClient, - ], -) -def test_iam_credentials_client_from_service_account_file(client_class): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json") - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == "iamcredentials.googleapis.com:443" - - -def test_iam_credentials_client_get_transport_class(): - transport = IAMCredentialsClient.get_transport_class() - available_transports = [ - transports.IAMCredentialsGrpcTransport, - ] - assert transport in available_transports - - transport = IAMCredentialsClient.get_transport_class("grpc") - assert transport == transports.IAMCredentialsGrpcTransport - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (IAMCredentialsClient, transports.IAMCredentialsGrpcTransport, "grpc"), - ( - IAMCredentialsAsyncClient, - transports.IAMCredentialsGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ], -) -@mock.patch.object( - IAMCredentialsClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(IAMCredentialsClient), -) -@mock.patch.object( - IAMCredentialsAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(IAMCredentialsAsyncClient), -) -def test_iam_credentials_client_client_options( - client_class, transport_class, transport_name -): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(IAMCredentialsClient, "get_transport_class") as gtc: - transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(IAMCredentialsClient, "get_transport_class") as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError): - client = client_class() - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} - ): - with pytest.raises(ValueError): - client = client_class() - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name,use_client_cert_env", - [ - (IAMCredentialsClient, transports.IAMCredentialsGrpcTransport, "grpc", "true"), - ( - IAMCredentialsAsyncClient, - transports.IAMCredentialsGrpcAsyncIOTransport, - "grpc_asyncio", - "true", - ), - (IAMCredentialsClient, transports.IAMCredentialsGrpcTransport, "grpc", "false"), - ( - IAMCredentialsAsyncClient, - transports.IAMCredentialsGrpcAsyncIOTransport, - "grpc_asyncio", - "false", - ), - ], -) -@mock.patch.object( - IAMCredentialsClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(IAMCredentialsClient), -) -@mock.patch.object( - IAMCredentialsAsyncClient, - "DEFAULT_ENDPOINT", - modify_default_endpoint(IAMCredentialsAsyncClient), -) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_iam_credentials_client_mtls_env_auto( - client_class, transport_class, transport_name, use_client_cert_env -): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client.DEFAULT_ENDPOINT - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=True, - ): - with mock.patch( - "google.auth.transport.mtls.default_client_cert_source", - return_value=client_cert_source_callback, - ): - if use_client_cert_env == "false": - expected_host = client.DEFAULT_ENDPOINT - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict( - os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} - ): - with mock.patch.object(transport_class, "__init__") as patched: - with mock.patch( - "google.auth.transport.mtls.has_default_client_cert_source", - return_value=False, - ): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (IAMCredentialsClient, transports.IAMCredentialsGrpcTransport, "grpc"), - ( - IAMCredentialsAsyncClient, - transports.IAMCredentialsGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ], -) -def test_iam_credentials_client_client_options_scopes( - client_class, transport_class, transport_name -): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_ENDPOINT, - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -@pytest.mark.parametrize( - "client_class,transport_class,transport_name", - [ - (IAMCredentialsClient, transports.IAMCredentialsGrpcTransport, "grpc"), - ( - IAMCredentialsAsyncClient, - transports.IAMCredentialsGrpcAsyncIOTransport, - "grpc_asyncio", - ), - ], -) -def test_iam_credentials_client_client_options_credentials_file( - client_class, transport_class, transport_name -): - # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client.DEFAULT_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -def test_iam_credentials_client_client_options_from_dict(): - with mock.patch( - "google.cloud.iam_credentials_v1.services.iam_credentials.transports.IAMCredentialsGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = IAMCredentialsClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - ) - - -def test_generate_access_token( - transport: str = "grpc", request_type=common.GenerateAccessTokenRequest -): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateAccessTokenResponse( - access_token="access_token_value", - ) - response = client.generate_access_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateAccessTokenRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.GenerateAccessTokenResponse) - assert response.access_token == "access_token_value" - - -def test_generate_access_token_from_dict(): - test_generate_access_token(request_type=dict) - - -def test_generate_access_token_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - client.generate_access_token() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateAccessTokenRequest() - - -@pytest.mark.asyncio -async def test_generate_access_token_async( - transport: str = "grpc_asyncio", request_type=common.GenerateAccessTokenRequest -): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateAccessTokenResponse( - access_token="access_token_value", - ) - ) - response = await client.generate_access_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateAccessTokenRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.GenerateAccessTokenResponse) - assert response.access_token == "access_token_value" - - -@pytest.mark.asyncio -async def test_generate_access_token_async_from_dict(): - await test_generate_access_token_async(request_type=dict) - - -def test_generate_access_token_field_headers(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.GenerateAccessTokenRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - call.return_value = common.GenerateAccessTokenResponse() - client.generate_access_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_generate_access_token_field_headers_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.GenerateAccessTokenRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateAccessTokenResponse() - ) - await client.generate_access_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -def test_generate_access_token_flattened(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateAccessTokenResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.generate_access_token( - name="name_value", - delegates=["delegates_value"], - scope=["scope_value"], - lifetime=duration_pb2.Duration(seconds=751), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].scope == ["scope_value"] - assert DurationRule().to_proto(args[0].lifetime) == duration_pb2.Duration( - seconds=751 - ) - - -def test_generate_access_token_flattened_error(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.generate_access_token( - common.GenerateAccessTokenRequest(), - name="name_value", - delegates=["delegates_value"], - scope=["scope_value"], - lifetime=duration_pb2.Duration(seconds=751), - ) - - -@pytest.mark.asyncio -async def test_generate_access_token_flattened_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_access_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateAccessTokenResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateAccessTokenResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.generate_access_token( - name="name_value", - delegates=["delegates_value"], - scope=["scope_value"], - lifetime=duration_pb2.Duration(seconds=751), - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].scope == ["scope_value"] - assert DurationRule().to_proto(args[0].lifetime) == duration_pb2.Duration( - seconds=751 - ) - - -@pytest.mark.asyncio -async def test_generate_access_token_flattened_error_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.generate_access_token( - common.GenerateAccessTokenRequest(), - name="name_value", - delegates=["delegates_value"], - scope=["scope_value"], - lifetime=duration_pb2.Duration(seconds=751), - ) - - -def test_generate_id_token( - transport: str = "grpc", request_type=common.GenerateIdTokenRequest -): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateIdTokenResponse( - token="token_value", - ) - response = client.generate_id_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateIdTokenRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.GenerateIdTokenResponse) - assert response.token == "token_value" - - -def test_generate_id_token_from_dict(): - test_generate_id_token(request_type=dict) - - -def test_generate_id_token_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - client.generate_id_token() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateIdTokenRequest() - - -@pytest.mark.asyncio -async def test_generate_id_token_async( - transport: str = "grpc_asyncio", request_type=common.GenerateIdTokenRequest -): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateIdTokenResponse( - token="token_value", - ) - ) - response = await client.generate_id_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == common.GenerateIdTokenRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.GenerateIdTokenResponse) - assert response.token == "token_value" - - -@pytest.mark.asyncio -async def test_generate_id_token_async_from_dict(): - await test_generate_id_token_async(request_type=dict) - - -def test_generate_id_token_field_headers(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.GenerateIdTokenRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - call.return_value = common.GenerateIdTokenResponse() - client.generate_id_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_generate_id_token_field_headers_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.GenerateIdTokenRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateIdTokenResponse() - ) - await client.generate_id_token(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -def test_generate_id_token_flattened(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateIdTokenResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.generate_id_token( - name="name_value", - delegates=["delegates_value"], - audience="audience_value", - include_email=True, - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].audience == "audience_value" - assert args[0].include_email == True - - -def test_generate_id_token_flattened_error(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.generate_id_token( - common.GenerateIdTokenRequest(), - name="name_value", - delegates=["delegates_value"], - audience="audience_value", - include_email=True, - ) - - -@pytest.mark.asyncio -async def test_generate_id_token_flattened_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.generate_id_token), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = common.GenerateIdTokenResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.GenerateIdTokenResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.generate_id_token( - name="name_value", - delegates=["delegates_value"], - audience="audience_value", - include_email=True, - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].audience == "audience_value" - assert args[0].include_email == True - - -@pytest.mark.asyncio -async def test_generate_id_token_flattened_error_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.generate_id_token( - common.GenerateIdTokenRequest(), - name="name_value", - delegates=["delegates_value"], - audience="audience_value", - include_email=True, - ) - - -def test_sign_blob(transport: str = "grpc", request_type=common.SignBlobRequest): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignBlobResponse( - key_id="key_id_value", - signed_blob=b"signed_blob_blob", - ) - response = client.sign_blob(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignBlobRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.SignBlobResponse) - assert response.key_id == "key_id_value" - assert response.signed_blob == b"signed_blob_blob" - - -def test_sign_blob_from_dict(): - test_sign_blob(request_type=dict) - - -def test_sign_blob_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - client.sign_blob() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignBlobRequest() - - -@pytest.mark.asyncio -async def test_sign_blob_async( - transport: str = "grpc_asyncio", request_type=common.SignBlobRequest -): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignBlobResponse( - key_id="key_id_value", - signed_blob=b"signed_blob_blob", - ) - ) - response = await client.sign_blob(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignBlobRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.SignBlobResponse) - assert response.key_id == "key_id_value" - assert response.signed_blob == b"signed_blob_blob" - - -@pytest.mark.asyncio -async def test_sign_blob_async_from_dict(): - await test_sign_blob_async(request_type=dict) - - -def test_sign_blob_field_headers(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.SignBlobRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - call.return_value = common.SignBlobResponse() - client.sign_blob(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_sign_blob_field_headers_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.SignBlobRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignBlobResponse() - ) - await client.sign_blob(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -def test_sign_blob_flattened(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignBlobResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.sign_blob( - name="name_value", - delegates=["delegates_value"], - payload=b"payload_blob", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].payload == b"payload_blob" - - -def test_sign_blob_flattened_error(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.sign_blob( - common.SignBlobRequest(), - name="name_value", - delegates=["delegates_value"], - payload=b"payload_blob", - ) - - -@pytest.mark.asyncio -async def test_sign_blob_flattened_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_blob), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignBlobResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignBlobResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.sign_blob( - name="name_value", - delegates=["delegates_value"], - payload=b"payload_blob", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].payload == b"payload_blob" - - -@pytest.mark.asyncio -async def test_sign_blob_flattened_error_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.sign_blob( - common.SignBlobRequest(), - name="name_value", - delegates=["delegates_value"], - payload=b"payload_blob", - ) - - -def test_sign_jwt(transport: str = "grpc", request_type=common.SignJwtRequest): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignJwtResponse( - key_id="key_id_value", - signed_jwt="signed_jwt_value", - ) - response = client.sign_jwt(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignJwtRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.SignJwtResponse) - assert response.key_id == "key_id_value" - assert response.signed_jwt == "signed_jwt_value" - - -def test_sign_jwt_from_dict(): - test_sign_jwt(request_type=dict) - - -def test_sign_jwt_empty_call(): - # This test is a coverage failsafe to make sure that totally empty calls, - # i.e. request == None and no flattened fields passed, work. - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - client.sign_jwt() - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignJwtRequest() - - -@pytest.mark.asyncio -async def test_sign_jwt_async( - transport: str = "grpc_asyncio", request_type=common.SignJwtRequest -): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignJwtResponse( - key_id="key_id_value", - signed_jwt="signed_jwt_value", - ) - ) - response = await client.sign_jwt(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == common.SignJwtRequest() - - # Establish that the response is the type that we expect. - assert isinstance(response, common.SignJwtResponse) - assert response.key_id == "key_id_value" - assert response.signed_jwt == "signed_jwt_value" - - -@pytest.mark.asyncio -async def test_sign_jwt_async_from_dict(): - await test_sign_jwt_async(request_type=dict) - - -def test_sign_jwt_field_headers(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.SignJwtRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - call.return_value = common.SignJwtResponse() - client.sign_jwt(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -@pytest.mark.asyncio -async def test_sign_jwt_field_headers_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = common.SignJwtRequest() - - request.name = "name/value" - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignJwtResponse() - ) - await client.sign_jwt(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ( - "x-goog-request-params", - "name=name/value", - ) in kw["metadata"] - - -def test_sign_jwt_flattened(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignJwtResponse() - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - client.sign_jwt( - name="name_value", - delegates=["delegates_value"], - payload="payload_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].payload == "payload_value" - - -def test_sign_jwt_flattened_error(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.sign_jwt( - common.SignJwtRequest(), - name="name_value", - delegates=["delegates_value"], - payload="payload_value", - ) - - -@pytest.mark.asyncio -async def test_sign_jwt_flattened_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client.transport.sign_jwt), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = common.SignJwtResponse() - - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( - common.SignJwtResponse() - ) - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = await client.sign_jwt( - name="name_value", - delegates=["delegates_value"], - payload="payload_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - assert args[0].delegates == ["delegates_value"] - assert args[0].payload == "payload_value" - - -@pytest.mark.asyncio -async def test_sign_jwt_flattened_error_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - await client.sign_jwt( - common.SignJwtRequest(), - name="name_value", - delegates=["delegates_value"], - payload="payload_value", - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.IAMCredentialsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.IAMCredentialsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = IAMCredentialsClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.IAMCredentialsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = IAMCredentialsClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.IAMCredentialsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = IAMCredentialsClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.IAMCredentialsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.IAMCredentialsGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.IAMCredentialsGrpcTransport, - transports.IAMCredentialsGrpcAsyncIOTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.IAMCredentialsGrpcTransport, - ) - - -def test_iam_credentials_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.IAMCredentialsTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_iam_credentials_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.iam_credentials_v1.services.iam_credentials.transports.IAMCredentialsTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.IAMCredentialsTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "generate_access_token", - "generate_id_token", - "sign_blob", - "sign_jwt", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - -def test_iam_credentials_base_transport_with_credentials_file(): - # Instantiate the base transport with a credentials file - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch( - "google.cloud.iam_credentials_v1.services.iam_credentials.transports.IAMCredentialsTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.IAMCredentialsTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with( - "credentials.json", - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -def test_iam_credentials_base_transport_with_adc(): - # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( - "google.cloud.iam_credentials_v1.services.iam_credentials.transports.IAMCredentialsTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.IAMCredentialsTransport() - adc.assert_called_once() - - -def test_iam_credentials_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - IAMCredentialsClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.IAMCredentialsGrpcTransport, - transports.IAMCredentialsGrpcAsyncIOTransport, - ], -) -def test_iam_credentials_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.IAMCredentialsGrpcTransport, grpc_helpers), - (transports.IAMCredentialsGrpcAsyncIOTransport, grpc_helpers_async), - ], -) -def test_iam_credentials_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - - create_channel.assert_called_with( - "iamcredentials.googleapis.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - scopes=["1", "2"], - default_host="iamcredentials.googleapis.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.IAMCredentialsGrpcTransport, - transports.IAMCredentialsGrpcAsyncIOTransport, - ], -) -def test_iam_credentials_grpc_transport_client_cert_source_for_mtls(transport_class): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds, - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback, - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, private_key=expected_key - ) - - -def test_iam_credentials_host_no_port(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="iamcredentials.googleapis.com" - ), - ) - assert client.transport._host == "iamcredentials.googleapis.com:443" - - -def test_iam_credentials_host_with_port(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="iamcredentials.googleapis.com:8000" - ), - ) - assert client.transport._host == "iamcredentials.googleapis.com:8000" - - -def test_iam_credentials_grpc_transport_channel(): - channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.IAMCredentialsGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_iam_credentials_grpc_asyncio_transport_channel(): - channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.IAMCredentialsGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize( - "transport_class", - [ - transports.IAMCredentialsGrpcTransport, - transports.IAMCredentialsGrpcAsyncIOTransport, - ], -) -def test_iam_credentials_transport_channel_mtls_with_client_cert_source( - transport_class, -): - with mock.patch( - "grpc.ssl_channel_credentials", autospec=True - ) as grpc_ssl_channel_cred: - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize( - "transport_class", - [ - transports.IAMCredentialsGrpcTransport, - transports.IAMCredentialsGrpcAsyncIOTransport, - ], -) -def test_iam_credentials_transport_channel_mtls_with_adc(transport_class): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object( - transport_class, "create_channel" - ) as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_service_account_path(): - project = "squid" - service_account = "clam" - expected = "projects/{project}/serviceAccounts/{service_account}".format( - project=project, - service_account=service_account, - ) - actual = IAMCredentialsClient.service_account_path(project, service_account) - assert expected == actual - - -def test_parse_service_account_path(): - expected = { - "project": "whelk", - "service_account": "octopus", - } - path = IAMCredentialsClient.service_account_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_service_account_path(path) - assert expected == actual - - -def test_common_billing_account_path(): - billing_account = "oyster" - expected = "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - actual = IAMCredentialsClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "nudibranch", - } - path = IAMCredentialsClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_common_billing_account_path(path) - assert expected == actual - - -def test_common_folder_path(): - folder = "cuttlefish" - expected = "folders/{folder}".format( - folder=folder, - ) - actual = IAMCredentialsClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "mussel", - } - path = IAMCredentialsClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_common_folder_path(path) - assert expected == actual - - -def test_common_organization_path(): - organization = "winkle" - expected = "organizations/{organization}".format( - organization=organization, - ) - actual = IAMCredentialsClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nautilus", - } - path = IAMCredentialsClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_common_organization_path(path) - assert expected == actual - - -def test_common_project_path(): - project = "scallop" - expected = "projects/{project}".format( - project=project, - ) - actual = IAMCredentialsClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "abalone", - } - path = IAMCredentialsClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_common_project_path(path) - assert expected == actual - - -def test_common_location_path(): - project = "squid" - location = "clam" - expected = "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - actual = IAMCredentialsClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "whelk", - "location": "octopus", - } - path = IAMCredentialsClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = IAMCredentialsClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_withDEFAULT_CLIENT_INFO(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object( - transports.IAMCredentialsTransport, "_prep_wrapped_messages" - ) as prep: - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object( - transports.IAMCredentialsTransport, "_prep_wrapped_messages" - ) as prep: - transport_class = IAMCredentialsClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -@pytest.mark.asyncio -async def test_transport_close_async(): - client = IAMCredentialsAsyncClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc_asyncio", - ) - with mock.patch.object( - type(getattr(client.transport, "grpc_channel")), "close" - ) as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close(): - transports = { - "grpc": "_grpc_channel", - } - - for transport, close_name in transports.items(): - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - with mock.patch.object( - type(getattr(client.transport, close_name)), "close" - ) as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - "grpc", - ] - for transport in transports: - client = IAMCredentialsClient( - credentials=ga_credentials.AnonymousCredentials(), transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() diff --git a/tests/unit/gapic/iam_credentials_v1/test_iam_credentials.py b/tests/unit/gapic/iam_credentials_v1/test_iam_credentials.py index 0f8e8f8..0bc68a1 100644 --- a/tests/unit/gapic/iam_credentials_v1/test_iam_credentials.py +++ b/tests/unit/gapic/iam_credentials_v1/test_iam_credentials.py @@ -224,6 +224,7 @@ def test_iam_credentials_client_client_options( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is @@ -241,6 +242,7 @@ def test_iam_credentials_client_client_options( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is @@ -258,6 +260,7 @@ def test_iam_credentials_client_client_options( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has @@ -287,6 +290,25 @@ def test_iam_credentials_client_client_options( quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", ) @@ -354,6 +376,7 @@ def test_iam_credentials_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case ADC client cert is provided. Whether client cert is used depends on @@ -388,6 +411,7 @@ def test_iam_credentials_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case client_cert_source and ADC client cert are not provided. @@ -410,6 +434,7 @@ def test_iam_credentials_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -524,6 +549,7 @@ def test_iam_credentials_client_client_options_scopes( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -562,6 +588,7 @@ def test_iam_credentials_client_client_options_credentials_file( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -582,6 +609,7 @@ def test_iam_credentials_client_client_options_from_dict(): quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -620,6 +648,7 @@ def test_iam_credentials_client_create_channel_credentials_file( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # test that the credentials from file are saved and used as the credentials. @@ -1937,6 +1966,28 @@ def test_iam_credentials_transport_auth_adc(transport_class): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.IAMCredentialsGrpcTransport, + transports.IAMCredentialsGrpcAsyncIOTransport, + ], +) +def test_iam_credentials_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -2402,4 +2453,5 @@ def test_api_key_credentials(client_class, transport_class): quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) diff --git a/tests/unit/gapic/iam_v2beta/test_policies.py b/tests/unit/gapic/iam_v2beta/test_policies.py index 3783cdd..6c1aa76 100644 --- a/tests/unit/gapic/iam_v2beta/test_policies.py +++ b/tests/unit/gapic/iam_v2beta/test_policies.py @@ -224,6 +224,7 @@ def test_policies_client_client_options(client_class, transport_class, transport quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is @@ -241,6 +242,7 @@ def test_policies_client_client_options(client_class, transport_class, transport quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is @@ -258,6 +260,7 @@ def test_policies_client_client_options(client_class, transport_class, transport quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has @@ -287,6 +290,25 @@ def test_policies_client_client_options(client_class, transport_class, transport quota_project_id="octopus", client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", ) @@ -352,6 +374,7 @@ def test_policies_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case ADC client cert is provided. Whether client cert is used depends on @@ -386,6 +409,7 @@ def test_policies_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # Check the case client_cert_source and ADC client cert are not provided. @@ -408,6 +432,7 @@ def test_policies_client_mtls_env_auto( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -514,6 +539,7 @@ def test_policies_client_client_options_scopes( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -547,6 +573,7 @@ def test_policies_client_client_options_credentials_file( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -565,6 +592,7 @@ def test_policies_client_client_options_from_dict(): quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) @@ -598,6 +626,7 @@ def test_policies_client_create_channel_credentials_file( quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, ) # test that the credentials from file are saved and used as the credentials. @@ -2137,6 +2166,28 @@ def test_policies_transport_auth_adc(transport_class): ) +@pytest.mark.parametrize( + "transport_class", + [ + transports.PoliciesGrpcTransport, + transports.PoliciesGrpcAsyncIOTransport, + ], +) +def test_policies_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + @pytest.mark.parametrize( "transport_class,grpc_helpers", [ @@ -2620,4 +2671,5 @@ def test_api_key_credentials(client_class, transport_class): quota_project_id=None, client_info=transports.base.DEFAULT_CLIENT_INFO, always_use_jwt_access=True, + api_audience=None, )