From f552e400b8290f6dadc15a8c879a0b3193ddd412 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 15 Sep 2022 09:23:42 -0400 Subject: [PATCH 1/9] chore: update to gapic-generator-python-1.4.2 (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: update to gapic-generator-python-1.4.2 (REST transport test fixes) PiperOrigin-RevId: 474313212 Source-Link: https://github.com/googleapis/googleapis/commit/cec7333497696a744a6b56ce39dfd8146421b631 Source-Link: https://github.com/googleapis/googleapis-gen/commit/47afba9d36b84cbbaa85d6e3bc34ef65efe624ee Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNDdhZmJhOWQzNmI4NGNiYmFhODVkNmUzYmMzNGVmNjVlZmU2MjRlZSJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Explicitly set transport to grpc for python targets PiperOrigin-RevId: 474394710 Source-Link: https://github.com/googleapis/googleapis/commit/8f81accbe688b16b62c2d1c4f94ef8f7880c7dc9 Source-Link: https://github.com/googleapis/googleapis-gen/commit/811c263cd4688659caf6678501ba033cb889e026 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODExYzI2M2NkNDY4ODY1OWNhZjY2Nzg1MDFiYTAzM2NiODg5ZTAyNiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- google/cloud/run_v2/gapic_metadata.json | 65 - .../cloud/run_v2/services/revisions/client.py | 5 - .../services/revisions/transports/__init__.py | 5 - .../cloud/run_v2/services/services/client.py | 5 - .../services/services/transports/__init__.py | 5 - .../snippet_metadata_run_v2.json | 1052 +----- tests/unit/gapic/run_v2/test_revisions.py | 1016 +----- tests/unit/gapic/run_v2/test_services.py | 3023 +---------------- 8 files changed, 266 insertions(+), 4910 deletions(-) diff --git a/google/cloud/run_v2/gapic_metadata.json b/google/cloud/run_v2/gapic_metadata.json index e8920ee..995df8c 100644 --- a/google/cloud/run_v2/gapic_metadata.json +++ b/google/cloud/run_v2/gapic_metadata.json @@ -46,26 +46,6 @@ ] } } - }, - "rest": { - "libraryClient": "RevisionsClient", - "rpcs": { - "DeleteRevision": { - "methods": [ - "delete_revision" - ] - }, - "GetRevision": { - "methods": [ - "get_revision" - ] - }, - "ListRevisions": { - "methods": [ - "list_revisions" - ] - } - } } } }, @@ -160,51 +140,6 @@ ] } } - }, - "rest": { - "libraryClient": "ServicesClient", - "rpcs": { - "CreateService": { - "methods": [ - "create_service" - ] - }, - "DeleteService": { - "methods": [ - "delete_service" - ] - }, - "GetIamPolicy": { - "methods": [ - "get_iam_policy" - ] - }, - "GetService": { - "methods": [ - "get_service" - ] - }, - "ListServices": { - "methods": [ - "list_services" - ] - }, - "SetIamPolicy": { - "methods": [ - "set_iam_policy" - ] - }, - "TestIamPermissions": { - "methods": [ - "test_iam_permissions" - ] - }, - "UpdateService": { - "methods": [ - "update_service" - ] - } - } } } } diff --git a/google/cloud/run_v2/services/revisions/client.py b/google/cloud/run_v2/services/revisions/client.py index 2ed4c32..6668526 100644 --- a/google/cloud/run_v2/services/revisions/client.py +++ b/google/cloud/run_v2/services/revisions/client.py @@ -47,7 +47,6 @@ from .transports.base import RevisionsTransport, DEFAULT_CLIENT_INFO from .transports.grpc import RevisionsGrpcTransport from .transports.grpc_asyncio import RevisionsGrpcAsyncIOTransport -from .transports.rest import RevisionsRestTransport class RevisionsClientMeta(type): @@ -61,7 +60,6 @@ class RevisionsClientMeta(type): _transport_registry = OrderedDict() # type: Dict[str, Type[RevisionsTransport]] _transport_registry["grpc"] = RevisionsGrpcTransport _transport_registry["grpc_asyncio"] = RevisionsGrpcAsyncIOTransport - _transport_registry["rest"] = RevisionsRestTransport def get_transport_class( cls, @@ -464,9 +462,6 @@ def __init__( transport (Union[str, RevisionsTransport]): The transport to use. If set to None, a transport is chosen automatically. - NOTE: "rest" transport functionality is currently in a - beta state (preview). We welcome your feedback via an - issue in this library's source repository. client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the diff --git a/google/cloud/run_v2/services/revisions/transports/__init__.py b/google/cloud/run_v2/services/revisions/transports/__init__.py index a67304d..ff3df68 100644 --- a/google/cloud/run_v2/services/revisions/transports/__init__.py +++ b/google/cloud/run_v2/services/revisions/transports/__init__.py @@ -19,20 +19,15 @@ from .base import RevisionsTransport from .grpc import RevisionsGrpcTransport from .grpc_asyncio import RevisionsGrpcAsyncIOTransport -from .rest import RevisionsRestTransport -from .rest import RevisionsRestInterceptor # Compile a registry of transports. _transport_registry = OrderedDict() # type: Dict[str, Type[RevisionsTransport]] _transport_registry["grpc"] = RevisionsGrpcTransport _transport_registry["grpc_asyncio"] = RevisionsGrpcAsyncIOTransport -_transport_registry["rest"] = RevisionsRestTransport __all__ = ( "RevisionsTransport", "RevisionsGrpcTransport", "RevisionsGrpcAsyncIOTransport", - "RevisionsRestTransport", - "RevisionsRestInterceptor", ) diff --git a/google/cloud/run_v2/services/services/client.py b/google/cloud/run_v2/services/services/client.py index 0ad702c..4248686 100644 --- a/google/cloud/run_v2/services/services/client.py +++ b/google/cloud/run_v2/services/services/client.py @@ -50,7 +50,6 @@ from .transports.base import ServicesTransport, DEFAULT_CLIENT_INFO from .transports.grpc import ServicesGrpcTransport from .transports.grpc_asyncio import ServicesGrpcAsyncIOTransport -from .transports.rest import ServicesRestTransport class ServicesClientMeta(type): @@ -64,7 +63,6 @@ class ServicesClientMeta(type): _transport_registry = OrderedDict() # type: Dict[str, Type[ServicesTransport]] _transport_registry["grpc"] = ServicesGrpcTransport _transport_registry["grpc_asyncio"] = ServicesGrpcAsyncIOTransport - _transport_registry["rest"] = ServicesRestTransport def get_transport_class( cls, @@ -467,9 +465,6 @@ def __init__( transport (Union[str, ServicesTransport]): The transport to use. If set to None, a transport is chosen automatically. - NOTE: "rest" transport functionality is currently in a - beta state (preview). We welcome your feedback via an - issue in this library's source repository. client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the diff --git a/google/cloud/run_v2/services/services/transports/__init__.py b/google/cloud/run_v2/services/services/transports/__init__.py index 9c2d606..7597c5d 100644 --- a/google/cloud/run_v2/services/services/transports/__init__.py +++ b/google/cloud/run_v2/services/services/transports/__init__.py @@ -19,20 +19,15 @@ from .base import ServicesTransport from .grpc import ServicesGrpcTransport from .grpc_asyncio import ServicesGrpcAsyncIOTransport -from .rest import ServicesRestTransport -from .rest import ServicesRestInterceptor # Compile a registry of transports. _transport_registry = OrderedDict() # type: Dict[str, Type[ServicesTransport]] _transport_registry["grpc"] = ServicesGrpcTransport _transport_registry["grpc_asyncio"] = ServicesGrpcAsyncIOTransport -_transport_registry["rest"] = ServicesRestTransport __all__ = ( "ServicesTransport", "ServicesGrpcTransport", "ServicesGrpcAsyncIOTransport", - "ServicesRestTransport", - "ServicesRestInterceptor", ) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index f9b04b1..fe7fed3 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,87 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.RevisionsClient", - "shortName": "RevisionsClient" - }, - "fullName": "google.cloud.run_v2.RevisionsClient.delete_revision", - "method": { - "fullName": "google.cloud.run.v2.Revisions.DeleteRevision", - "service": { - "fullName": "google.cloud.run.v2.Revisions", - "shortName": "Revisions" - }, - "shortName": "DeleteRevision" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.DeleteRevisionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "delete_revision" - }, - "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync.py" }, { "canonical": true, @@ -374,87 +294,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Revisions_GetRevision_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.RevisionsClient", - "shortName": "RevisionsClient" - }, - "fullName": "google.cloud.run_v2.RevisionsClient.get_revision", - "method": { - "fullName": "google.cloud.run.v2.Revisions.GetRevision", - "service": { - "fullName": "google.cloud.run.v2.Revisions", - "shortName": "Revisions" - }, - "shortName": "GetRevision" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.GetRevisionRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.cloud.run_v2.types.Revision", - "shortName": "get_revision" - }, - "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +330,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync.py" }, { "canonical": true, @@ -615,87 +455,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.RevisionsClient", - "shortName": "RevisionsClient" - }, - "fullName": "google.cloud.run_v2.RevisionsClient.list_revisions", - "method": { - "fullName": "google.cloud.run.v2.Revisions.ListRevisions", - "service": { - "fullName": "google.cloud.run.v2.Revisions", - "shortName": "Revisions" - }, - "shortName": "ListRevisions" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.ListRevisionsRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.cloud.run_v2.services.revisions.pagers.ListRevisionsPager", - "shortName": "list_revisions" - }, - "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +491,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync.py" }, { "canonical": true, @@ -872,7 +632,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_3c405c33.py", + "file": "run_v2_generated_services_create_service_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -908,125 +668,37 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_3c405c33.py" + "title": "run_v2_generated_services_create_service_sync.py" }, { "canonical": true, "clientMethod": { + "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.create_service", + "fullName": "google.cloud.run_v2.ServicesAsyncClient.delete_service", "method": { - "fullName": "google.cloud.run.v2.Services.CreateService", + "fullName": "google.cloud.run.v2.Services.DeleteService", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "CreateService" + "shortName": "DeleteService" }, "parameters": [ { "name": "request", - "type": "google.cloud.run_v2.types.CreateServiceRequest" + "type": "google.cloud.run_v2.types.DeleteServiceRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { - "name": "service", - "type": "google.cloud.run_v2.types.Service" - }, - { - "name": "service_id", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "create_service" - }, - "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_8031b824.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_CreateService_sync", - "segments": [ - { - "end": 56, - "start": 27, - "type": "FULL" - }, - { - "end": 56, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 46, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 53, - "start": 47, - "type": "REQUEST_EXECUTION" - }, - { - "end": 57, - "start": 54, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_create_service_sync_8031b824.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" - }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.delete_service", - "method": { - "fullName": "google.cloud.run.v2.Services.DeleteService", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "DeleteService" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.DeleteServiceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" + "name": "retry", + "type": "google.api_core.retry.Retry" }, { "name": "timeout", @@ -1121,7 +793,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", + "file": "run_v2_generated_services_delete_service_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1157,87 +829,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.delete_service", - "method": { - "fullName": "google.cloud.run.v2.Services.DeleteService", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "DeleteService" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.DeleteServiceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "delete_service" - }, - "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_DeleteService_sync", - "segments": [ - { - "end": 55, - "start": 27, - "type": "FULL" - }, - { - "end": 55, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 52, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 56, - "start": 53, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" + "title": "run_v2_generated_services_delete_service_sync.py" }, { "canonical": true, @@ -1354,83 +946,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", - "segments": [ - { - "end": 52, - "start": 27, - "type": "FULL" - }, - { - "end": 52, - "start": 27, - "type": "SHORT" - }, - { - "end": 41, - "start": 39, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 46, - "start": 42, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 49, - "start": 47, - "type": "REQUEST_EXECUTION" - }, - { - "end": 53, - "start": 50, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.get_iam_policy", - "method": { - "fullName": "google.cloud.run.v2.Services.GetIamPolicy", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "GetIamPolicy" - }, - "parameters": [ - { - "name": "request", - "type": "google.iam.v1.iam_policy_pb2.GetIamPolicyRequest" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.iam.v1.policy_pb2.Policy", - "shortName": "get_iam_policy" - }, - "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", + "file": "run_v2_generated_services_get_iam_policy_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1466,7 +982,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" + "title": "run_v2_generated_services_get_iam_policy_sync.py" }, { "canonical": true, @@ -1508,262 +1024,21 @@ } ], "resultType": "google.cloud.run_v2.types.Service", - "shortName": "get_service" - }, - "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_async.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetService_async", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_get_service_async.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.get_service", - "method": { - "fullName": "google.cloud.run.v2.Services.GetService", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "GetService" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.GetServiceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.cloud.run_v2.types.Service", - "shortName": "get_service" - }, - "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetService_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.get_service", - "method": { - "fullName": "google.cloud.run.v2.Services.GetService", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "GetService" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.GetServiceRequest" - }, - { - "name": "name", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.cloud.run_v2.types.Service", - "shortName": "get_service" - }, - "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_18284d02.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetService_sync", - "segments": [ - { - "end": 51, - "start": 27, - "type": "FULL" - }, - { - "end": 51, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 45, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 48, - "start": 46, - "type": "REQUEST_EXECUTION" - }, - { - "end": 52, - "start": 49, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_get_service_sync_18284d02.py" - }, - { - "canonical": true, - "clientMethod": { - "async": true, - "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" - }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.list_services", - "method": { - "fullName": "google.cloud.run.v2.Services.ListServices", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "ListServices" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.ListServicesRequest" - }, - { - "name": "parent", - "type": "str" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesAsyncPager", - "shortName": "list_services" + "shortName": "get_service" }, - "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_async.py", + "description": "Sample for GetService", + "file": "run_v2_generated_services_get_service_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_ListServices_async", + "regionTag": "run_v2_generated_Services_GetService_async", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1783,12 +1058,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_async.py" + "title": "run_v2_generated_services_get_service_async.py" }, { "canonical": true, @@ -1797,22 +1072,22 @@ "fullName": "google.cloud.run_v2.ServicesClient", "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.list_services", + "fullName": "google.cloud.run_v2.ServicesClient.get_service", "method": { - "fullName": "google.cloud.run.v2.Services.ListServices", + "fullName": "google.cloud.run.v2.Services.GetService", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "ListServices" + "shortName": "GetService" }, "parameters": [ { "name": "request", - "type": "google.cloud.run_v2.types.ListServicesRequest" + "type": "google.cloud.run_v2.types.GetServiceRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -1828,22 +1103,22 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", - "shortName": "list_services" + "resultType": "google.cloud.run_v2.types.Service", + "shortName": "get_service" }, - "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_c5743712.py", + "description": "Sample for GetService", + "file": "run_v2_generated_services_get_service_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_ListServices_sync", + "regionTag": "run_v2_generated_Services_GetService_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1863,21 +1138,22 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_c5743712.py" + "title": "run_v2_generated_services_get_service_sync.py" }, { "canonical": true, "clientMethod": { + "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.list_services", + "fullName": "google.cloud.run_v2.ServicesAsyncClient.list_services", "method": { "fullName": "google.cloud.run.v2.Services.ListServices", "service": { @@ -1908,14 +1184,14 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", + "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesAsyncPager", "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", + "file": "run_v2_generated_services_list_services_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_ListServices_sync", + "regionTag": "run_v2_generated_Services_ListServices_async", "segments": [ { "end": 52, @@ -1948,29 +1224,32 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" + "title": "run_v2_generated_services_list_services_async.py" }, { "canonical": true, "clientMethod": { - "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.set_iam_policy", + "fullName": "google.cloud.run_v2.ServicesClient.list_services", "method": { - "fullName": "google.cloud.run.v2.Services.SetIamPolicy", + "fullName": "google.cloud.run.v2.Services.ListServices", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "SetIamPolicy" + "shortName": "ListServices" }, "parameters": [ { "name": "request", - "type": "google.iam.v1.iam_policy_pb2.SetIamPolicyRequest" + "type": "google.cloud.run_v2.types.ListServicesRequest" + }, + { + "name": "parent", + "type": "str" }, { "name": "retry", @@ -1985,14 +1264,14 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.iam.v1.policy_pb2.Policy", - "shortName": "set_iam_policy" + "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", + "shortName": "list_services" }, - "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_async.py", + "description": "Sample for ListServices", + "file": "run_v2_generated_services_list_services_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_SetIamPolicy_async", + "regionTag": "run_v2_generated_Services_ListServices_sync", "segments": [ { "end": 52, @@ -2005,36 +1284,37 @@ "type": "SHORT" }, { - "end": 41, - "start": 39, + "end": 40, + "start": 38, "type": "CLIENT_INITIALIZATION" }, { - "end": 46, - "start": 42, + "end": 45, + "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 49, - "start": 47, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { "end": 53, - "start": 50, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_async.py" + "title": "run_v2_generated_services_list_services_sync.py" }, { "canonical": true, "clientMethod": { + "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.set_iam_policy", + "fullName": "google.cloud.run_v2.ServicesAsyncClient.set_iam_policy", "method": { "fullName": "google.cloud.run.v2.Services.SetIamPolicy", "service": { @@ -2065,10 +1345,10 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", + "file": "run_v2_generated_services_set_iam_policy_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", + "regionTag": "run_v2_generated_Services_SetIamPolicy_async", "segments": [ { "end": 52, @@ -2101,7 +1381,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" + "title": "run_v2_generated_services_set_iam_policy_async.py" }, { "canonical": true, @@ -2141,7 +1421,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", + "file": "run_v2_generated_services_set_iam_policy_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2177,7 +1457,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" + "title": "run_v2_generated_services_set_iam_policy_sync.py" }, { "canonical": true, @@ -2294,83 +1574,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", - "segments": [ - { - "end": 53, - "start": 27, - "type": "FULL" - }, - { - "end": 53, - "start": 27, - "type": "SHORT" - }, - { - "end": 41, - "start": 39, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 47, - "start": 42, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 50, - "start": 48, - "type": "REQUEST_EXECUTION" - }, - { - "end": 54, - "start": 51, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.test_iam_permissions", - "method": { - "fullName": "google.cloud.run.v2.Services.TestIamPermissions", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "TestIamPermissions" - }, - "parameters": [ - { - "name": "request", - "type": "google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse", - "shortName": "test_iam_permissions" - }, - "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", + "file": "run_v2_generated_services_test_iam_permissions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2406,7 +1610,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" + "title": "run_v2_generated_services_test_iam_permissions_sync.py" }, { "canonical": true, @@ -2531,87 +1735,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_9076a854.py", - "language": "PYTHON", - "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_UpdateService_sync", - "segments": [ - { - "end": 54, - "start": 27, - "type": "FULL" - }, - { - "end": 54, - "start": 27, - "type": "SHORT" - }, - { - "end": 40, - "start": 38, - "type": "CLIENT_INITIALIZATION" - }, - { - "end": 44, - "start": 41, - "type": "REQUEST_INITIALIZATION" - }, - { - "end": 51, - "start": 45, - "type": "REQUEST_EXECUTION" - }, - { - "end": 55, - "start": 52, - "type": "RESPONSE_HANDLING" - } - ], - "title": "run_v2_generated_services_update_service_sync_9076a854.py" - }, - { - "canonical": true, - "clientMethod": { - "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" - }, - "fullName": "google.cloud.run_v2.ServicesClient.update_service", - "method": { - "fullName": "google.cloud.run.v2.Services.UpdateService", - "service": { - "fullName": "google.cloud.run.v2.Services", - "shortName": "Services" - }, - "shortName": "UpdateService" - }, - "parameters": [ - { - "name": "request", - "type": "google.cloud.run_v2.types.UpdateServiceRequest" - }, - { - "name": "service", - "type": "google.cloud.run_v2.types.Service" - }, - { - "name": "retry", - "type": "google.api_core.retry.Retry" - }, - { - "name": "timeout", - "type": "float" - }, - { - "name": "metadata", - "type": "Sequence[Tuple[str, str]" - } - ], - "resultType": "google.api_core.operation.Operation", - "shortName": "update_service" - }, - "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_2652a462.py", + "file": "run_v2_generated_services_update_service_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2647,7 +1771,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_2652a462.py" + "title": "run_v2_generated_services_update_service_sync.py" } ] } diff --git a/tests/unit/gapic/run_v2/test_revisions.py b/tests/unit/gapic/run_v2/test_revisions.py index c081633..b49691c 100644 --- a/tests/unit/gapic/run_v2/test_revisions.py +++ b/tests/unit/gapic/run_v2/test_revisions.py @@ -24,17 +24,10 @@ import grpc from grpc.experimental import aio -from collections.abc import Iterable -from google.protobuf import json_format -import json import math import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers -from requests import Response -from requests import Request, PreparedRequest -from requests.sessions import Session -from google.protobuf import json_format from google.api import launch_stage_pb2 # type: ignore from google.api_core import client_options @@ -108,7 +101,6 @@ def test__get_default_mtls_endpoint(): [ (RevisionsClient, "grpc"), (RevisionsAsyncClient, "grpc_asyncio"), - (RevisionsClient, "rest"), ], ) def test_revisions_client_from_service_account_info(client_class, transport_name): @@ -122,11 +114,7 @@ def test_revisions_client_from_service_account_info(client_class, transport_name assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") @pytest.mark.parametrize( @@ -134,7 +122,6 @@ def test_revisions_client_from_service_account_info(client_class, transport_name [ (transports.RevisionsGrpcTransport, "grpc"), (transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.RevisionsRestTransport, "rest"), ], ) def test_revisions_client_service_account_always_use_jwt( @@ -160,7 +147,6 @@ def test_revisions_client_service_account_always_use_jwt( [ (RevisionsClient, "grpc"), (RevisionsAsyncClient, "grpc_asyncio"), - (RevisionsClient, "rest"), ], ) def test_revisions_client_from_service_account_file(client_class, transport_name): @@ -181,18 +167,13 @@ def test_revisions_client_from_service_account_file(client_class, transport_name assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") def test_revisions_client_get_transport_class(): transport = RevisionsClient.get_transport_class() available_transports = [ transports.RevisionsGrpcTransport, - transports.RevisionsRestTransport, ] assert transport in available_transports @@ -209,7 +190,6 @@ def test_revisions_client_get_transport_class(): transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio", ), - (RevisionsClient, transports.RevisionsRestTransport, "rest"), ], ) @mock.patch.object( @@ -351,8 +331,6 @@ def test_revisions_client_client_options(client_class, transport_class, transpor "grpc_asyncio", "false", ), - (RevisionsClient, transports.RevisionsRestTransport, "rest", "true"), - (RevisionsClient, transports.RevisionsRestTransport, "rest", "false"), ], ) @mock.patch.object( @@ -546,7 +524,6 @@ def test_revisions_client_get_mtls_endpoint_and_cert_source(client_class): transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio", ), - (RevisionsClient, transports.RevisionsRestTransport, "rest"), ], ) def test_revisions_client_client_options_scopes( @@ -582,7 +559,6 @@ def test_revisions_client_client_options_scopes( "grpc_asyncio", grpc_helpers_async, ), - (RevisionsClient, transports.RevisionsRestTransport, "rest", None), ], ) def test_revisions_client_client_options_credentials_file( @@ -1510,919 +1486,6 @@ async def test_delete_revision_flattened_error_async(): ) -@pytest.mark.parametrize( - "request_type", - [ - revision.GetRevisionRequest, - dict, - ], -) -def test_get_revision_rest(request_type): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = revision.Revision( - name="name_value", - uid="uid_value", - generation=1068, - launch_stage=launch_stage_pb2.LaunchStage.UNIMPLEMENTED, - service="service_value", - max_instance_request_concurrency=3436, - service_account="service_account_value", - execution_environment=vendor_settings.ExecutionEnvironment.EXECUTION_ENVIRONMENT_GEN1, - encryption_key="encryption_key_value", - reconciling=True, - observed_generation=2021, - log_uri="log_uri_value", - etag="etag_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = revision.Revision.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_revision(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, revision.Revision) - assert response.name == "name_value" - assert response.uid == "uid_value" - assert response.generation == 1068 - assert response.launch_stage == launch_stage_pb2.LaunchStage.UNIMPLEMENTED - assert response.service == "service_value" - assert response.max_instance_request_concurrency == 3436 - assert response.service_account == "service_account_value" - assert ( - response.execution_environment - == vendor_settings.ExecutionEnvironment.EXECUTION_ENVIRONMENT_GEN1 - ) - assert response.encryption_key == "encryption_key_value" - assert response.reconciling is True - assert response.observed_generation == 2021 - assert response.log_uri == "log_uri_value" - assert response.etag == "etag_value" - - -def test_get_revision_rest_required_fields(request_type=revision.GetRevisionRequest): - transport_class = transports.RevisionsRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_revision._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_revision._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = revision.Revision() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = revision.Revision.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_revision(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_get_revision_rest_unset_required_fields(): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.get_revision._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_revision_rest_interceptors(null_interceptor): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), - ) - client = RevisionsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RevisionsRestInterceptor, "post_get_revision" - ) as post, mock.patch.object( - transports.RevisionsRestInterceptor, "pre_get_revision" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = revision.GetRevisionRequest.pb(revision.GetRevisionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = revision.Revision.to_json(revision.Revision()) - - request = revision.GetRevisionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = revision.Revision() - - client.get_revision( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_revision_rest_bad_request( - transport: str = "rest", request_type=revision.GetRevisionRequest -): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_revision(request) - - -def test_get_revision_rest_flattened(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = revision.Revision() - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = revision.Revision.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_revision(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{name=projects/*/locations/*/services/*/revisions/*}" - % client.transport._host, - args[1], - ) - - -def test_get_revision_rest_flattened_error(transport: str = "rest"): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_revision( - revision.GetRevisionRequest(), - name="name_value", - ) - - -def test_get_revision_rest_error(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - revision.ListRevisionsRequest, - dict, - ], -) -def test_list_revisions_rest(request_type): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = revision.ListRevisionsResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = revision.ListRevisionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_revisions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListRevisionsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_revisions_rest_required_fields( - request_type=revision.ListRevisionsRequest, -): - transport_class = transports.RevisionsRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_revisions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_revisions._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "show_deleted", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = revision.ListRevisionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = revision.ListRevisionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_revisions(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_revisions_rest_unset_required_fields(): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_revisions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "showDeleted", - ) - ) - & set(("parent",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_revisions_rest_interceptors(null_interceptor): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), - ) - client = RevisionsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.RevisionsRestInterceptor, "post_list_revisions" - ) as post, mock.patch.object( - transports.RevisionsRestInterceptor, "pre_list_revisions" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = revision.ListRevisionsRequest.pb(revision.ListRevisionsRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = revision.ListRevisionsResponse.to_json( - revision.ListRevisionsResponse() - ) - - request = revision.ListRevisionsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = revision.ListRevisionsResponse() - - client.list_revisions( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_revisions_rest_bad_request( - transport: str = "rest", request_type=revision.ListRevisionsRequest -): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_revisions(request) - - -def test_list_revisions_rest_flattened(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = revision.ListRevisionsResponse() - - # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/locations/sample2/services/sample3" - } - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = revision.ListRevisionsResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_revisions(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{parent=projects/*/locations/*/services/*}/revisions" - % client.transport._host, - args[1], - ) - - -def test_list_revisions_rest_flattened_error(transport: str = "rest"): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_revisions( - revision.ListRevisionsRequest(), - parent="parent_value", - ) - - -def test_list_revisions_rest_pager(transport: str = "rest"): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - revision.ListRevisionsResponse( - revisions=[ - revision.Revision(), - revision.Revision(), - revision.Revision(), - ], - next_page_token="abc", - ), - revision.ListRevisionsResponse( - revisions=[], - next_page_token="def", - ), - revision.ListRevisionsResponse( - revisions=[ - revision.Revision(), - ], - next_page_token="ghi", - ), - revision.ListRevisionsResponse( - revisions=[ - revision.Revision(), - revision.Revision(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(revision.ListRevisionsResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = { - "parent": "projects/sample1/locations/sample2/services/sample3" - } - - pager = client.list_revisions(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, revision.Revision) for i in results) - - pages = list(client.list_revisions(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - revision.DeleteRevisionRequest, - dict, - ], -) -def test_delete_revision_rest(request_type): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_revision(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_delete_revision_rest_required_fields( - request_type=revision.DeleteRevisionRequest, -): - transport_class = transports.RevisionsRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_revision._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_revision._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "etag", - "validate_only", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.delete_revision(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_delete_revision_rest_unset_required_fields(): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.delete_revision._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "etag", - "validateOnly", - ) - ) - & set(("name",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_revision_rest_interceptors(null_interceptor): - transport = transports.RevisionsRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), - ) - client = RevisionsClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.RevisionsRestInterceptor, "post_delete_revision" - ) as post, mock.patch.object( - transports.RevisionsRestInterceptor, "pre_delete_revision" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = revision.DeleteRevisionRequest.pb(revision.DeleteRevisionRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = revision.DeleteRevisionRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.delete_revision( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_delete_revision_rest_bad_request( - transport: str = "rest", request_type=revision.DeleteRevisionRequest -): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_revision(request) - - -def test_delete_revision_rest_flattened(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" - } - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.delete_revision(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{name=projects/*/locations/*/services/*/revisions/*}" - % client.transport._host, - args[1], - ) - - -def test_delete_revision_rest_flattened_error(transport: str = "rest"): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_revision( - revision.DeleteRevisionRequest(), - name="name_value", - ) - - -def test_delete_revision_rest_error(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.RevisionsGrpcTransport( @@ -2504,7 +1567,6 @@ def test_transport_get_channel(): [ transports.RevisionsGrpcTransport, transports.RevisionsGrpcAsyncIOTransport, - transports.RevisionsRestTransport, ], ) def test_transport_adc(transport_class): @@ -2519,7 +1581,6 @@ def test_transport_adc(transport_class): "transport_name", [ "grpc", - "rest", ], ) def test_transport_kind(transport_name): @@ -2656,7 +1717,6 @@ def test_revisions_transport_auth_adc(transport_class): [ transports.RevisionsGrpcTransport, transports.RevisionsGrpcAsyncIOTransport, - transports.RevisionsRestTransport, ], ) def test_revisions_transport_auth_gdch_credentials(transport_class): @@ -2751,40 +1811,11 @@ def test_revisions_grpc_transport_client_cert_source_for_mtls(transport_class): ) -def test_revisions_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.RevisionsRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -def test_revisions_rest_lro_client(): - client = RevisionsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.AbstractOperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - @pytest.mark.parametrize( "transport_name", [ "grpc", "grpc_asyncio", - "rest", ], ) def test_revisions_host_no_port(transport_name): @@ -2793,11 +1824,7 @@ def test_revisions_host_no_port(transport_name): client_options=client_options.ClientOptions(api_endpoint="run.googleapis.com"), transport=transport_name, ) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") @pytest.mark.parametrize( @@ -2805,7 +1832,6 @@ def test_revisions_host_no_port(transport_name): [ "grpc", "grpc_asyncio", - "rest", ], ) def test_revisions_host_with_port(transport_name): @@ -2816,39 +1842,7 @@ def test_revisions_host_with_port(transport_name): ), transport=transport_name, ) - assert client.transport._host == ( - "run.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_revisions_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = RevisionsClient( - credentials=creds1, - transport=transport_name, - ) - client2 = RevisionsClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.get_revision._session - session2 = client2.transport.get_revision._session - assert session1 != session2 - session1 = client1.transport.list_revisions._session - session2 = client2.transport.list_revisions._session - assert session1 != session2 - session1 = client1.transport.delete_revision._session - session2 = client2.transport.delete_revision._session - assert session1 != session2 + assert client.transport._host == ("run.googleapis.com:8000") def test_revisions_grpc_transport_channel(): @@ -3304,7 +2298,6 @@ async def test_transport_close_async(): def test_transport_close(): transports = { - "rest": "_session", "grpc": "_grpc_channel", } @@ -3322,7 +2315,6 @@ def test_transport_close(): def test_client_ctx(): transports = [ - "rest", "grpc", ] for transport in transports: diff --git a/tests/unit/gapic/run_v2/test_services.py b/tests/unit/gapic/run_v2/test_services.py index 910dae2..f791bb2 100644 --- a/tests/unit/gapic/run_v2/test_services.py +++ b/tests/unit/gapic/run_v2/test_services.py @@ -24,17 +24,10 @@ import grpc from grpc.experimental import aio -from collections.abc import Iterable -from google.protobuf import json_format -import json import math import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers -from requests import Response -from requests import Request, PreparedRequest -from requests.sessions import Session -from google.protobuf import json_format from google.api import launch_stage_pb2 # type: ignore from google.api_core import client_options @@ -116,7 +109,6 @@ def test__get_default_mtls_endpoint(): [ (ServicesClient, "grpc"), (ServicesAsyncClient, "grpc_asyncio"), - (ServicesClient, "rest"), ], ) def test_services_client_from_service_account_info(client_class, transport_name): @@ -130,11 +122,7 @@ def test_services_client_from_service_account_info(client_class, transport_name) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") @pytest.mark.parametrize( @@ -142,7 +130,6 @@ def test_services_client_from_service_account_info(client_class, transport_name) [ (transports.ServicesGrpcTransport, "grpc"), (transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.ServicesRestTransport, "rest"), ], ) def test_services_client_service_account_always_use_jwt( @@ -168,7 +155,6 @@ def test_services_client_service_account_always_use_jwt( [ (ServicesClient, "grpc"), (ServicesAsyncClient, "grpc_asyncio"), - (ServicesClient, "rest"), ], ) def test_services_client_from_service_account_file(client_class, transport_name): @@ -189,18 +175,13 @@ def test_services_client_from_service_account_file(client_class, transport_name) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") def test_services_client_get_transport_class(): transport = ServicesClient.get_transport_class() available_transports = [ transports.ServicesGrpcTransport, - transports.ServicesRestTransport, ] assert transport in available_transports @@ -213,7 +194,6 @@ def test_services_client_get_transport_class(): [ (ServicesClient, transports.ServicesGrpcTransport, "grpc"), (ServicesAsyncClient, transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), - (ServicesClient, transports.ServicesRestTransport, "rest"), ], ) @mock.patch.object( @@ -355,8 +335,6 @@ def test_services_client_client_options(client_class, transport_class, transport "grpc_asyncio", "false", ), - (ServicesClient, transports.ServicesRestTransport, "rest", "true"), - (ServicesClient, transports.ServicesRestTransport, "rest", "false"), ], ) @mock.patch.object( @@ -546,7 +524,6 @@ def test_services_client_get_mtls_endpoint_and_cert_source(client_class): [ (ServicesClient, transports.ServicesGrpcTransport, "grpc"), (ServicesAsyncClient, transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), - (ServicesClient, transports.ServicesRestTransport, "rest"), ], ) def test_services_client_client_options_scopes( @@ -582,7 +559,6 @@ def test_services_client_client_options_scopes( "grpc_asyncio", grpc_helpers_async, ), - (ServicesClient, transports.ServicesRestTransport, "rest", None), ], ) def test_services_client_client_options_credentials_file( @@ -2437,2789 +2413,222 @@ def test_test_iam_permissions_from_dict_foreign(): call.assert_called() -@pytest.mark.parametrize( - "request_type", - [ - gcr_service.CreateServiceRequest, - dict, - ], -) -def test_create_service_rest(request_type): - client = ServicesClient( +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ServicesGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["service"] = { - "name": "name_value", - "description": "description_value", - "uid": "uid_value", - "generation": 1068, - "labels": {}, - "annotations": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "delete_time": {}, - "expire_time": {}, - "creator": "creator_value", - "last_modifier": "last_modifier_value", - "client": "client_value", - "client_version": "client_version_value", - "ingress": 1, - "launch_stage": 6, - "binary_authorization": { - "use_default": True, - "breakglass_justification": "breakglass_justification_value", - }, - "template": { - "revision": "revision_value", - "labels": {}, - "annotations": {}, - "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, - "vpc_access": {"connector": "connector_value", "egress": 1}, - "timeout": {"seconds": 751, "nanos": 543}, - "service_account": "service_account_value", - "containers": [ - { - "name": "name_value", - "image": "image_value", - "command": ["command_value1", "command_value2"], - "args": ["args_value1", "args_value2"], - "env": [ - { - "name": "name_value", - "value": "value_value", - "value_source": { - "secret_key_ref": { - "secret": "secret_value", - "version": "version_value", - } - }, - } - ], - "resources": {"limits": {}, "cpu_idle": True}, - "ports": [{"name": "name_value", "container_port": 1511}], - "volume_mounts": [ - {"name": "name_value", "mount_path": "mount_path_value"} - ], - } - ], - "volumes": [ - { - "name": "name_value", - "secret": { - "secret": "secret_value", - "items": [ - { - "path": "path_value", - "version": "version_value", - "mode": 421, - } - ], - "default_mode": 1257, - }, - "cloud_sql_instance": { - "instances": ["instances_value1", "instances_value2"] - }, - } - ], - "execution_environment": 1, - "encryption_key": "encryption_key_value", - "max_instance_request_concurrency": 3436, - }, - "traffic": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - } - ], - "observed_generation": 2021, - "terminal_condition": { - "type_": "type__value", - "state": 1, - "message": "message_value", - "last_transition_time": {}, - "severity": 1, - "reason": 1, - "revision_reason": 1, - "execution_reason": 1, - }, - "conditions": {}, - "latest_ready_revision": "latest_ready_revision_value", - "latest_created_revision": "latest_created_revision_value", - "traffic_statuses": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - "uri": "uri_value", - } - ], - "uri": "uri_value", - "reconciling": True, - "etag": "etag_value", - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.create_service(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_create_service_rest_required_fields( - request_type=gcr_service.CreateServiceRequest, -): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["parent"] = "" - request_init["service_id"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, + with pytest.raises(ValueError): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - ) - - # verify fields with default values are dropped - assert "serviceId" not in jsonified_request - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_service._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - assert "serviceId" in jsonified_request - assert jsonified_request["serviceId"] == request_init["service_id"] - jsonified_request["parent"] = "parent_value" - jsonified_request["serviceId"] = "service_id_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).create_service._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "service_id", - "validate_only", - ) + # It is an error to provide a credentials file and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - assert "serviceId" in jsonified_request - assert jsonified_request["serviceId"] == "service_id_value" + with pytest.raises(ValueError): + client = ServicesClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) - client = ServicesClient( + # It is an error to provide an api_key and a transport instance. + transport = transports.ServicesGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.create_service(request) - - expected_params = [ - ( - "serviceId", - "", - ), - ] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServicesClient( + client_options=options, + transport=transport, + ) + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServicesClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) -def test_create_service_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials + # It is an error to provide scopes and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), ) - - unset_fields = transport.create_service._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "serviceId", - "validateOnly", - ) - ) - & set( - ( - "parent", - "service", - "serviceId", - ) + with pytest.raises(ValueError): + client = ServicesClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, ) - ) -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_service_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServicesGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), ) client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.ServicesRestInterceptor, "post_create_service" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_create_service" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = gcr_service.CreateServiceRequest.pb( - gcr_service.CreateServiceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = gcr_service.CreateServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.create_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) + assert client.transport is transport - pre.assert_called_once() - post.assert_called_once() +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel -def test_create_service_rest_bad_request( - transport: str = "rest", request_type=gcr_service.CreateServiceRequest -): - client = ServicesClient( + transport = transports.ServicesGrpcAsyncIOTransport( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, ) + channel = transport.grpc_channel + assert channel - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request_init["service"] = { - "name": "name_value", - "description": "description_value", - "uid": "uid_value", - "generation": 1068, - "labels": {}, - "annotations": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "delete_time": {}, - "expire_time": {}, - "creator": "creator_value", - "last_modifier": "last_modifier_value", - "client": "client_value", - "client_version": "client_version_value", - "ingress": 1, - "launch_stage": 6, - "binary_authorization": { - "use_default": True, - "breakglass_justification": "breakglass_justification_value", - }, - "template": { - "revision": "revision_value", - "labels": {}, - "annotations": {}, - "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, - "vpc_access": {"connector": "connector_value", "egress": 1}, - "timeout": {"seconds": 751, "nanos": 543}, - "service_account": "service_account_value", - "containers": [ - { - "name": "name_value", - "image": "image_value", - "command": ["command_value1", "command_value2"], - "args": ["args_value1", "args_value2"], - "env": [ - { - "name": "name_value", - "value": "value_value", - "value_source": { - "secret_key_ref": { - "secret": "secret_value", - "version": "version_value", - } - }, - } - ], - "resources": {"limits": {}, "cpu_idle": True}, - "ports": [{"name": "name_value", "container_port": 1511}], - "volume_mounts": [ - {"name": "name_value", "mount_path": "mount_path_value"} - ], - } - ], - "volumes": [ - { - "name": "name_value", - "secret": { - "secret": "secret_value", - "items": [ - { - "path": "path_value", - "version": "version_value", - "mode": 421, - } - ], - "default_mode": 1257, - }, - "cloud_sql_instance": { - "instances": ["instances_value1", "instances_value2"] - }, - } - ], - "execution_environment": 1, - "encryption_key": "encryption_key_value", - "max_instance_request_concurrency": 3436, - }, - "traffic": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - } - ], - "observed_generation": 2021, - "terminal_condition": { - "type_": "type__value", - "state": 1, - "message": "message_value", - "last_transition_time": {}, - "severity": 1, - "reason": 1, - "revision_reason": 1, - "execution_reason": 1, - }, - "conditions": {}, - "latest_ready_revision": "latest_ready_revision_value", - "latest_created_revision": "latest_created_revision_value", - "traffic_statuses": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - "uri": "uri_value", - } - ], - "uri": "uri_value", - "reconciling": True, - "etag": "etag_value", - } - request = request_type(**request_init) - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.create_service(request) +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServicesGrpcTransport, + transports.ServicesGrpcAsyncIOTransport, + ], +) +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_create_service_rest_flattened(): +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + ], +) +def test_transport_kind(transport_name): + transport = ServicesClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. client = ServicesClient( credentials=ga_credentials.AnonymousCredentials(), - transport="rest", ) + assert isinstance( + client.transport, + transports.ServicesGrpcTransport, + ) + - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") +def test_services_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ServicesTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - service=gcr_service.Service(name="name_value"), - service_id="service_id_value", +def test_services_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.run_v2.services.services.transports.ServicesTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ServicesTransport( + credentials=ga_credentials.AnonymousCredentials(), ) - mock_args.update(sample_request) - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_service", + "get_service", + "list_services", + "update_service", + "delete_service", + "get_iam_policy", + "set_iam_policy", + "test_iam_permissions", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) - client.create_service(**mock_args) + with pytest.raises(NotImplementedError): + transport.close() - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{parent=projects/*/locations/*}/services" % client.transport._host, - args[1], - ) + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() -def test_create_service_rest_flattened_error(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_service( - gcr_service.CreateServiceRequest(), - parent="parent_value", - service=gcr_service.Service(name="name_value"), - service_id="service_id_value", +def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServicesTransport( + 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_create_service_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) +def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServicesTransport() + adc.assert_called_once() + + +def test_services_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) + ServicesClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) @pytest.mark.parametrize( - "request_type", + "transport_class", [ - service.GetServiceRequest, - dict, - ], -) -def test_get_service_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = service.Service( - name="name_value", - description="description_value", - uid="uid_value", - generation=1068, - creator="creator_value", - last_modifier="last_modifier_value", - client="client_value", - client_version="client_version_value", - ingress=vendor_settings.IngressTraffic.INGRESS_TRAFFIC_ALL, - launch_stage=launch_stage_pb2.LaunchStage.UNIMPLEMENTED, - observed_generation=2021, - latest_ready_revision="latest_ready_revision_value", - latest_created_revision="latest_created_revision_value", - uri="uri_value", - reconciling=True, - etag="etag_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = service.Service.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_service(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, service.Service) - assert response.name == "name_value" - assert response.description == "description_value" - assert response.uid == "uid_value" - assert response.generation == 1068 - assert response.creator == "creator_value" - assert response.last_modifier == "last_modifier_value" - assert response.client == "client_value" - assert response.client_version == "client_version_value" - assert response.ingress == vendor_settings.IngressTraffic.INGRESS_TRAFFIC_ALL - assert response.launch_stage == launch_stage_pb2.LaunchStage.UNIMPLEMENTED - assert response.observed_generation == 2021 - assert response.latest_ready_revision == "latest_ready_revision_value" - assert response.latest_created_revision == "latest_created_revision_value" - assert response.uri == "uri_value" - assert response.reconciling is True - assert response.etag == "etag_value" - - -def test_get_service_rest_required_fields(request_type=service.GetServiceRequest): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_service._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_service._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = service.Service() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = service.Service.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_service(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_get_service_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.get_service._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_service_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ServicesRestInterceptor, "post_get_service" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_get_service" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = service.GetServiceRequest.pb(service.GetServiceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = service.Service.to_json(service.Service()) - - request = service.GetServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = service.Service() - - client.get_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_service_rest_bad_request( - transport: str = "rest", request_type=service.GetServiceRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_service(request) - - -def test_get_service_rest_flattened(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = service.Service() - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/services/sample3"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = service.Service.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.get_service(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{name=projects/*/locations/*/services/*}" % client.transport._host, - args[1], - ) - - -def test_get_service_rest_flattened_error(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_service( - service.GetServiceRequest(), - name="name_value", - ) - - -def test_get_service_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - service.ListServicesRequest, - dict, - ], -) -def test_list_services_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = service.ListServicesResponse( - next_page_token="next_page_token_value", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = service.ListServicesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.list_services(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListServicesPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_services_rest_required_fields(request_type=service.ListServicesRequest): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["parent"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_services._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["parent"] = "parent_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).list_services._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "page_size", - "page_token", - "show_deleted", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = service.ListServicesResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = service.ListServicesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.list_services(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_list_services_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.list_services._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "pageSize", - "pageToken", - "showDeleted", - ) - ) - & set(("parent",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_services_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ServicesRestInterceptor, "post_list_services" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_list_services" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = service.ListServicesRequest.pb(service.ListServicesRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = service.ListServicesResponse.to_json( - service.ListServicesResponse() - ) - - request = service.ListServicesRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = service.ListServicesResponse() - - client.list_services( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_list_services_rest_bad_request( - transport: str = "rest", request_type=service.ListServicesRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1/locations/sample2"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.list_services(request) - - -def test_list_services_rest_flattened(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = service.ListServicesResponse() - - # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1/locations/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - parent="parent_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = service.ListServicesResponse.pb(return_value) - json_return_value = json_format.MessageToJson(pb_return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.list_services(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{parent=projects/*/locations/*}/services" % client.transport._host, - args[1], - ) - - -def test_list_services_rest_flattened_error(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_services( - service.ListServicesRequest(), - parent="parent_value", - ) - - -def test_list_services_rest_pager(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - service.ListServicesResponse( - services=[ - service.Service(), - service.Service(), - service.Service(), - ], - next_page_token="abc", - ), - service.ListServicesResponse( - services=[], - next_page_token="def", - ), - service.ListServicesResponse( - services=[ - service.Service(), - ], - next_page_token="ghi", - ), - service.ListServicesResponse( - services=[ - service.Service(), - service.Service(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple(service.ListServicesResponse.to_json(x) for x in response) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = {"parent": "projects/sample1/locations/sample2"} - - pager = client.list_services(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, service.Service) for i in results) - - pages = list(client.list_services(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - - -@pytest.mark.parametrize( - "request_type", - [ - gcr_service.UpdateServiceRequest, - dict, - ], -) -def test_update_service_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = { - "service": {"name": "projects/sample1/locations/sample2/services/sample3"} - } - request_init["service"] = { - "name": "projects/sample1/locations/sample2/services/sample3", - "description": "description_value", - "uid": "uid_value", - "generation": 1068, - "labels": {}, - "annotations": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "delete_time": {}, - "expire_time": {}, - "creator": "creator_value", - "last_modifier": "last_modifier_value", - "client": "client_value", - "client_version": "client_version_value", - "ingress": 1, - "launch_stage": 6, - "binary_authorization": { - "use_default": True, - "breakglass_justification": "breakglass_justification_value", - }, - "template": { - "revision": "revision_value", - "labels": {}, - "annotations": {}, - "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, - "vpc_access": {"connector": "connector_value", "egress": 1}, - "timeout": {"seconds": 751, "nanos": 543}, - "service_account": "service_account_value", - "containers": [ - { - "name": "name_value", - "image": "image_value", - "command": ["command_value1", "command_value2"], - "args": ["args_value1", "args_value2"], - "env": [ - { - "name": "name_value", - "value": "value_value", - "value_source": { - "secret_key_ref": { - "secret": "secret_value", - "version": "version_value", - } - }, - } - ], - "resources": {"limits": {}, "cpu_idle": True}, - "ports": [{"name": "name_value", "container_port": 1511}], - "volume_mounts": [ - {"name": "name_value", "mount_path": "mount_path_value"} - ], - } - ], - "volumes": [ - { - "name": "name_value", - "secret": { - "secret": "secret_value", - "items": [ - { - "path": "path_value", - "version": "version_value", - "mode": 421, - } - ], - "default_mode": 1257, - }, - "cloud_sql_instance": { - "instances": ["instances_value1", "instances_value2"] - }, - } - ], - "execution_environment": 1, - "encryption_key": "encryption_key_value", - "max_instance_request_concurrency": 3436, - }, - "traffic": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - } - ], - "observed_generation": 2021, - "terminal_condition": { - "type_": "type__value", - "state": 1, - "message": "message_value", - "last_transition_time": {}, - "severity": 1, - "reason": 1, - "revision_reason": 1, - "execution_reason": 1, - }, - "conditions": {}, - "latest_ready_revision": "latest_ready_revision_value", - "latest_created_revision": "latest_created_revision_value", - "traffic_statuses": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - "uri": "uri_value", - } - ], - "uri": "uri_value", - "reconciling": True, - "etag": "etag_value", - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.update_service(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_update_service_rest_required_fields( - request_type=gcr_service.UpdateServiceRequest, -): - transport_class = transports.ServicesRestTransport - - request_init = {} - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_service._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).update_service._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "allow_missing", - "validate_only", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "patch", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.update_service(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_update_service_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.update_service._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "allowMissing", - "validateOnly", - ) - ) - & set(("service",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_service_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.ServicesRestInterceptor, "post_update_service" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_update_service" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = gcr_service.UpdateServiceRequest.pb( - gcr_service.UpdateServiceRequest() - ) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = gcr_service.UpdateServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.update_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_update_service_rest_bad_request( - transport: str = "rest", request_type=gcr_service.UpdateServiceRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = { - "service": {"name": "projects/sample1/locations/sample2/services/sample3"} - } - request_init["service"] = { - "name": "projects/sample1/locations/sample2/services/sample3", - "description": "description_value", - "uid": "uid_value", - "generation": 1068, - "labels": {}, - "annotations": {}, - "create_time": {"seconds": 751, "nanos": 543}, - "update_time": {}, - "delete_time": {}, - "expire_time": {}, - "creator": "creator_value", - "last_modifier": "last_modifier_value", - "client": "client_value", - "client_version": "client_version_value", - "ingress": 1, - "launch_stage": 6, - "binary_authorization": { - "use_default": True, - "breakglass_justification": "breakglass_justification_value", - }, - "template": { - "revision": "revision_value", - "labels": {}, - "annotations": {}, - "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, - "vpc_access": {"connector": "connector_value", "egress": 1}, - "timeout": {"seconds": 751, "nanos": 543}, - "service_account": "service_account_value", - "containers": [ - { - "name": "name_value", - "image": "image_value", - "command": ["command_value1", "command_value2"], - "args": ["args_value1", "args_value2"], - "env": [ - { - "name": "name_value", - "value": "value_value", - "value_source": { - "secret_key_ref": { - "secret": "secret_value", - "version": "version_value", - } - }, - } - ], - "resources": {"limits": {}, "cpu_idle": True}, - "ports": [{"name": "name_value", "container_port": 1511}], - "volume_mounts": [ - {"name": "name_value", "mount_path": "mount_path_value"} - ], - } - ], - "volumes": [ - { - "name": "name_value", - "secret": { - "secret": "secret_value", - "items": [ - { - "path": "path_value", - "version": "version_value", - "mode": 421, - } - ], - "default_mode": 1257, - }, - "cloud_sql_instance": { - "instances": ["instances_value1", "instances_value2"] - }, - } - ], - "execution_environment": 1, - "encryption_key": "encryption_key_value", - "max_instance_request_concurrency": 3436, - }, - "traffic": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - } - ], - "observed_generation": 2021, - "terminal_condition": { - "type_": "type__value", - "state": 1, - "message": "message_value", - "last_transition_time": {}, - "severity": 1, - "reason": 1, - "revision_reason": 1, - "execution_reason": 1, - }, - "conditions": {}, - "latest_ready_revision": "latest_ready_revision_value", - "latest_created_revision": "latest_created_revision_value", - "traffic_statuses": [ - { - "type_": 1, - "revision": "revision_value", - "percent": 753, - "tag": "tag_value", - "uri": "uri_value", - } - ], - "uri": "uri_value", - "reconciling": True, - "etag": "etag_value", - } - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.update_service(request) - - -def test_update_service_rest_flattened(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = { - "service": {"name": "projects/sample1/locations/sample2/services/sample3"} - } - - # get truthy value for each flattened field - mock_args = dict( - service=gcr_service.Service(name="name_value"), - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.update_service(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{service.name=projects/*/locations/*/services/*}" - % client.transport._host, - args[1], - ) - - -def test_update_service_rest_flattened_error(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.update_service( - gcr_service.UpdateServiceRequest(), - service=gcr_service.Service(name="name_value"), - ) - - -def test_update_service_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - service.DeleteServiceRequest, - dict, - ], -) -def test_delete_service_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.delete_service(request) - - # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" - - -def test_delete_service_rest_required_fields(request_type=service.DeleteServiceRequest): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["name"] = "" - request = request_type(**request_init) - pb_request = request_type.pb(request) - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_service._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["name"] = "name_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).delete_service._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "etag", - "validate_only", - ) - ) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request_type.pb(request) - transcode_result = { - "uri": "v1/sample_method", - "method": "delete", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.delete_service(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_delete_service_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.delete_service._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "etag", - "validateOnly", - ) - ) - & set(("name",)) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_service_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.ServicesRestInterceptor, "post_delete_service" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_delete_service" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = service.DeleteServiceRequest.pb(service.DeleteServiceRequest()) - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - - request = service.DeleteServiceRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - - client.delete_service( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_delete_service_rest_bad_request( - transport: str = "rest", request_type=service.DeleteServiceRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.delete_service(request) - - -def test_delete_service_rest_flattened(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/locations/sample2/services/sample3"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.delete_service(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v2/{name=projects/*/locations/*/services/*}" % client.transport._host, - args[1], - ) - - -def test_delete_service_rest_flattened_error(transport: str = "rest"): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_service( - service.DeleteServiceRequest(), - name="name_value", - ) - - -def test_delete_service_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - iam_policy_pb2.GetIamPolicyRequest, - dict, - ], -) -def test_get_iam_policy_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = policy_pb2.Policy( - version=774, - etag=b"etag_blob", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.get_iam_policy(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, policy_pb2.Policy) - assert response.version == 774 - assert response.etag == b"etag_blob" - - -def test_get_iam_policy_rest_required_fields( - request_type=iam_policy_pb2.GetIamPolicyRequest, -): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["resource"] = "" - request = request_type(**request_init) - pb_request = request - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_iam_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["resource"] = "resource_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).get_iam_policy._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("options",)) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "resource" in jsonified_request - assert jsonified_request["resource"] == "resource_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = policy_pb2.Policy() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request - transcode_result = { - "uri": "v1/sample_method", - "method": "get", - "query_params": pb_request, - } - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.get_iam_policy(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_get_iam_policy_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.get_iam_policy._get_unset_required_fields({}) - assert set(unset_fields) == (set(("options",)) & set(("resource",))) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_iam_policy_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ServicesRestInterceptor, "post_get_iam_policy" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_get_iam_policy" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = iam_policy_pb2.GetIamPolicyRequest() - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) - - request = iam_policy_pb2.GetIamPolicyRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = policy_pb2.Policy() - - client.get_iam_policy( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_get_iam_policy_rest_bad_request( - transport: str = "rest", request_type=iam_policy_pb2.GetIamPolicyRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.get_iam_policy(request) - - -def test_get_iam_policy_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - iam_policy_pb2.SetIamPolicyRequest, - dict, - ], -) -def test_set_iam_policy_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = policy_pb2.Policy( - version=774, - etag=b"etag_blob", - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.set_iam_policy(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, policy_pb2.Policy) - assert response.version == 774 - assert response.etag == b"etag_blob" - - -def test_set_iam_policy_rest_required_fields( - request_type=iam_policy_pb2.SetIamPolicyRequest, -): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["resource"] = "" - request = request_type(**request_init) - pb_request = request - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).set_iam_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["resource"] = "resource_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).set_iam_policy._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "resource" in jsonified_request - assert jsonified_request["resource"] == "resource_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = policy_pb2.Policy() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.set_iam_policy(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_set_iam_policy_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.set_iam_policy._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "resource", - "policy", - ) - ) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_set_iam_policy_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ServicesRestInterceptor, "post_set_iam_policy" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_set_iam_policy" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = iam_policy_pb2.SetIamPolicyRequest() - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) - - request = iam_policy_pb2.SetIamPolicyRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = policy_pb2.Policy() - - client.set_iam_policy( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_set_iam_policy_rest_bad_request( - transport: str = "rest", request_type=iam_policy_pb2.SetIamPolicyRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.set_iam_policy(request) - - -def test_set_iam_policy_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -@pytest.mark.parametrize( - "request_type", - [ - iam_policy_pb2.TestIamPermissionsRequest, - dict, - ], -) -def test_test_iam_permissions_rest(request_type): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = iam_policy_pb2.TestIamPermissionsResponse( - permissions=["permissions_value"], - ) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - response = client.test_iam_permissions(request) - - # Establish that the response is the type that we expect. - assert isinstance(response, iam_policy_pb2.TestIamPermissionsResponse) - assert response.permissions == ["permissions_value"] - - -def test_test_iam_permissions_rest_required_fields( - request_type=iam_policy_pb2.TestIamPermissionsRequest, -): - transport_class = transports.ServicesRestTransport - - request_init = {} - request_init["resource"] = "" - request_init["permissions"] = "" - request = request_type(**request_init) - pb_request = request - jsonified_request = json.loads( - json_format.MessageToJson( - pb_request, - including_default_value_fields=False, - use_integers_for_enums=False, - ) - ) - - # verify fields with default values are dropped - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).test_iam_permissions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with default values are now present - - jsonified_request["resource"] = "resource_value" - jsonified_request["permissions"] = "permissions_value" - - unset_fields = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ).test_iam_permissions._get_unset_required_fields(jsonified_request) - jsonified_request.update(unset_fields) - - # verify required fields with non-default values are left alone - assert "resource" in jsonified_request - assert jsonified_request["resource"] == "resource_value" - assert "permissions" in jsonified_request - assert jsonified_request["permissions"] == "permissions_value" - - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = request_type(**request_init) - - # Designate an appropriate value for the returned response. - return_value = iam_policy_pb2.TestIamPermissionsResponse() - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # We need to mock transcode() because providing default values - # for required fields will fail the real version if the http_options - # expect actual values for those fields. - with mock.patch.object(path_template, "transcode") as transcode: - # A uri without fields and an empty body will force all the - # request fields to show up in the query_params. - pb_request = request - transcode_result = { - "uri": "v1/sample_method", - "method": "post", - "query_params": pb_request, - } - transcode_result["body"] = pb_request - transcode.return_value = transcode_result - - response_value = Response() - response_value.status_code = 200 - - pb_return_value = return_value - json_return_value = json_format.MessageToJson(pb_return_value) - - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - response = client.test_iam_permissions(request) - - expected_params = [] - actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params - - -def test_test_iam_permissions_rest_unset_required_fields(): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials - ) - - unset_fields = transport.test_iam_permissions._get_unset_required_fields({}) - assert set(unset_fields) == ( - set(()) - & set( - ( - "resource", - "permissions", - ) - ) - ) - - -@pytest.mark.parametrize("null_interceptor", [True, False]) -def test_test_iam_permissions_rest_interceptors(null_interceptor): - transport = transports.ServicesRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), - ) - client = ServicesClient(transport=transport) - with mock.patch.object( - type(client.transport._session), "request" - ) as req, mock.patch.object( - path_template, "transcode" - ) as transcode, mock.patch.object( - transports.ServicesRestInterceptor, "post_test_iam_permissions" - ) as post, mock.patch.object( - transports.ServicesRestInterceptor, "pre_test_iam_permissions" - ) as pre: - pre.assert_not_called() - post.assert_not_called() - pb_message = iam_policy_pb2.TestIamPermissionsRequest() - transcode.return_value = { - "method": "post", - "uri": "my_uri", - "body": pb_message, - "query_params": pb_message, - } - - req.return_value = Response() - req.return_value.status_code = 200 - req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - iam_policy_pb2.TestIamPermissionsResponse() - ) - - request = iam_policy_pb2.TestIamPermissionsRequest() - metadata = [ - ("key", "val"), - ("cephalopod", "squid"), - ] - pre.return_value = request, metadata - post.return_value = iam_policy_pb2.TestIamPermissionsResponse() - - client.test_iam_permissions( - request, - metadata=[ - ("key", "val"), - ("cephalopod", "squid"), - ], - ) - - pre.assert_called_once() - post.assert_called_once() - - -def test_test_iam_permissions_rest_bad_request( - transport: str = "rest", request_type=iam_policy_pb2.TestIamPermissionsRequest -): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # send a request that will satisfy transcoding - request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} - request = request_type(**request_init) - - # Mock the http request call within the method and fake a BadRequest error. - with mock.patch.object(Session, "request") as req, pytest.raises( - core_exceptions.BadRequest - ): - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 400 - response_value.request = Request() - req.return_value = response_value - client.test_iam_permissions(request) - - -def test_test_iam_permissions_rest_error(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), transport="rest" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ServicesClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ServicesClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ServicesClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ServicesClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = ServicesClient(transport=transport) - assert client.transport is transport - - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.ServicesGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.ServicesGrpcTransport, - transports.ServicesGrpcAsyncIOTransport, - transports.ServicesRestTransport, - ], -) -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() - - -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - "rest", - ], -) -def test_transport_kind(transport_name): - transport = ServicesClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.ServicesGrpcTransport, - ) - - -def test_services_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ServicesTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) - - -def test_services_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.run_v2.services.services.transports.ServicesTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.ServicesTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "create_service", - "get_service", - "list_services", - "update_service", - "delete_service", - "get_iam_policy", - "set_iam_policy", - "test_iam_permissions", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client - - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ServicesTransport( - 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_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ServicesTransport() - adc.assert_called_once() - - -def test_services_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) - ServicesClient() - 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.ServicesGrpcTransport, - transports.ServicesGrpcAsyncIOTransport, + transports.ServicesGrpcTransport, + transports.ServicesGrpcAsyncIOTransport, ], ) def test_services_transport_auth_adc(transport_class): @@ -5240,7 +2649,6 @@ def test_services_transport_auth_adc(transport_class): [ transports.ServicesGrpcTransport, transports.ServicesGrpcAsyncIOTransport, - transports.ServicesRestTransport, ], ) def test_services_transport_auth_gdch_credentials(transport_class): @@ -5335,40 +2743,11 @@ def test_services_grpc_transport_client_cert_source_for_mtls(transport_class): ) -def test_services_http_transport_client_cert_source_for_mtls(): - cred = ga_credentials.AnonymousCredentials() - with mock.patch( - "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" - ) as mock_configure_mtls_channel: - transports.ServicesRestTransport( - credentials=cred, client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -def test_services_rest_lro_client(): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - transport = client.transport - - # Ensure that we have a api-core operations client. - assert isinstance( - transport.operations_client, - operations_v1.AbstractOperationsClient, - ) - - # Ensure that subsequent calls to the property send the exact same object. - assert transport.operations_client is transport.operations_client - - @pytest.mark.parametrize( "transport_name", [ "grpc", "grpc_asyncio", - "rest", ], ) def test_services_host_no_port(transport_name): @@ -5377,11 +2756,7 @@ def test_services_host_no_port(transport_name): client_options=client_options.ClientOptions(api_endpoint="run.googleapis.com"), transport=transport_name, ) - assert client.transport._host == ( - "run.googleapis.com:443" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com" - ) + assert client.transport._host == ("run.googleapis.com:443") @pytest.mark.parametrize( @@ -5389,7 +2764,6 @@ def test_services_host_no_port(transport_name): [ "grpc", "grpc_asyncio", - "rest", ], ) def test_services_host_with_port(transport_name): @@ -5400,54 +2774,7 @@ def test_services_host_with_port(transport_name): ), transport=transport_name, ) - assert client.transport._host == ( - "run.googleapis.com:8000" - if transport_name in ["grpc", "grpc_asyncio"] - else "https://run.googleapis.com:8000" - ) - - -@pytest.mark.parametrize( - "transport_name", - [ - "rest", - ], -) -def test_services_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = ServicesClient( - credentials=creds1, - transport=transport_name, - ) - client2 = ServicesClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.create_service._session - session2 = client2.transport.create_service._session - assert session1 != session2 - session1 = client1.transport.get_service._session - session2 = client2.transport.get_service._session - assert session1 != session2 - session1 = client1.transport.list_services._session - session2 = client2.transport.list_services._session - assert session1 != session2 - session1 = client1.transport.update_service._session - session2 = client2.transport.update_service._session - assert session1 != session2 - session1 = client1.transport.delete_service._session - session2 = client2.transport.delete_service._session - assert session1 != session2 - session1 = client1.transport.get_iam_policy._session - session2 = client2.transport.get_iam_policy._session - assert session1 != session2 - session1 = client1.transport.set_iam_policy._session - session2 = client2.transport.set_iam_policy._session - assert session1 != session2 - session1 = client1.transport.test_iam_permissions._session - session2 = client2.transport.test_iam_permissions._session - assert session1 != session2 + assert client.transport._host == ("run.googleapis.com:8000") def test_services_grpc_transport_channel(): @@ -5903,7 +3230,6 @@ async def test_transport_close_async(): def test_transport_close(): transports = { - "rest": "_session", "grpc": "_grpc_channel", } @@ -5921,7 +3247,6 @@ def test_transport_close(): def test_client_ctx(): transports = [ - "rest", "grpc", ] for transport in transports: From 1f1dd2ac333cc66a1976005319c2b732fb3f06dd Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 16 Sep 2022 11:18:56 -0400 Subject: [PATCH 2/9] chore: restore rest support removed in #47 (#48) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: enable REST transport for Python Preview clients PiperOrigin-RevId: 474571730 Source-Link: https://github.com/googleapis/googleapis/commit/5a9ee4d5deca8e3da550b0419ed336e22521fc8e Source-Link: https://github.com/googleapis/googleapis-gen/commit/ceafe521f137680fdee2f9ca9e1947cdd825070d Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiY2VhZmU1MjFmMTM3NjgwZmRlZTJmOWNhOWUxOTQ3Y2RkODI1MDcwZCJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat: Add Secure Boot support to TPU v2alpha1 API PiperOrigin-RevId: 474644226 Source-Link: https://github.com/googleapis/googleapis/commit/f90b329a7eb583a21a20796892b993e91e8ccf34 Source-Link: https://github.com/googleapis/googleapis-gen/commit/4ad8763bde676f92a3eb70753ae1cfed0e81387e Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNGFkODc2M2JkZTY3NmY5MmEzZWI3MDc1M2FlMWNmZWQwZTgxMzg3ZSJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- google/cloud/run_v2/gapic_metadata.json | 65 + .../cloud/run_v2/services/revisions/client.py | 5 + .../services/revisions/transports/__init__.py | 5 + .../cloud/run_v2/services/services/client.py | 5 + .../services/services/transports/__init__.py | 5 + .../snippet_metadata_run_v2.json | 1056 +++++- tests/unit/gapic/run_v2/test_revisions.py | 1016 +++++- tests/unit/gapic/run_v2/test_services.py | 3023 ++++++++++++++++- 8 files changed, 4912 insertions(+), 268 deletions(-) diff --git a/google/cloud/run_v2/gapic_metadata.json b/google/cloud/run_v2/gapic_metadata.json index 995df8c..e8920ee 100644 --- a/google/cloud/run_v2/gapic_metadata.json +++ b/google/cloud/run_v2/gapic_metadata.json @@ -46,6 +46,26 @@ ] } } + }, + "rest": { + "libraryClient": "RevisionsClient", + "rpcs": { + "DeleteRevision": { + "methods": [ + "delete_revision" + ] + }, + "GetRevision": { + "methods": [ + "get_revision" + ] + }, + "ListRevisions": { + "methods": [ + "list_revisions" + ] + } + } } } }, @@ -140,6 +160,51 @@ ] } } + }, + "rest": { + "libraryClient": "ServicesClient", + "rpcs": { + "CreateService": { + "methods": [ + "create_service" + ] + }, + "DeleteService": { + "methods": [ + "delete_service" + ] + }, + "GetIamPolicy": { + "methods": [ + "get_iam_policy" + ] + }, + "GetService": { + "methods": [ + "get_service" + ] + }, + "ListServices": { + "methods": [ + "list_services" + ] + }, + "SetIamPolicy": { + "methods": [ + "set_iam_policy" + ] + }, + "TestIamPermissions": { + "methods": [ + "test_iam_permissions" + ] + }, + "UpdateService": { + "methods": [ + "update_service" + ] + } + } } } } diff --git a/google/cloud/run_v2/services/revisions/client.py b/google/cloud/run_v2/services/revisions/client.py index 6668526..2ed4c32 100644 --- a/google/cloud/run_v2/services/revisions/client.py +++ b/google/cloud/run_v2/services/revisions/client.py @@ -47,6 +47,7 @@ from .transports.base import RevisionsTransport, DEFAULT_CLIENT_INFO from .transports.grpc import RevisionsGrpcTransport from .transports.grpc_asyncio import RevisionsGrpcAsyncIOTransport +from .transports.rest import RevisionsRestTransport class RevisionsClientMeta(type): @@ -60,6 +61,7 @@ class RevisionsClientMeta(type): _transport_registry = OrderedDict() # type: Dict[str, Type[RevisionsTransport]] _transport_registry["grpc"] = RevisionsGrpcTransport _transport_registry["grpc_asyncio"] = RevisionsGrpcAsyncIOTransport + _transport_registry["rest"] = RevisionsRestTransport def get_transport_class( cls, @@ -462,6 +464,9 @@ def __init__( transport (Union[str, RevisionsTransport]): The transport to use. If set to None, a transport is chosen automatically. + NOTE: "rest" transport functionality is currently in a + beta state (preview). We welcome your feedback via an + issue in this library's source repository. client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the diff --git a/google/cloud/run_v2/services/revisions/transports/__init__.py b/google/cloud/run_v2/services/revisions/transports/__init__.py index ff3df68..a67304d 100644 --- a/google/cloud/run_v2/services/revisions/transports/__init__.py +++ b/google/cloud/run_v2/services/revisions/transports/__init__.py @@ -19,15 +19,20 @@ from .base import RevisionsTransport from .grpc import RevisionsGrpcTransport from .grpc_asyncio import RevisionsGrpcAsyncIOTransport +from .rest import RevisionsRestTransport +from .rest import RevisionsRestInterceptor # Compile a registry of transports. _transport_registry = OrderedDict() # type: Dict[str, Type[RevisionsTransport]] _transport_registry["grpc"] = RevisionsGrpcTransport _transport_registry["grpc_asyncio"] = RevisionsGrpcAsyncIOTransport +_transport_registry["rest"] = RevisionsRestTransport __all__ = ( "RevisionsTransport", "RevisionsGrpcTransport", "RevisionsGrpcAsyncIOTransport", + "RevisionsRestTransport", + "RevisionsRestInterceptor", ) diff --git a/google/cloud/run_v2/services/services/client.py b/google/cloud/run_v2/services/services/client.py index 4248686..0ad702c 100644 --- a/google/cloud/run_v2/services/services/client.py +++ b/google/cloud/run_v2/services/services/client.py @@ -50,6 +50,7 @@ from .transports.base import ServicesTransport, DEFAULT_CLIENT_INFO from .transports.grpc import ServicesGrpcTransport from .transports.grpc_asyncio import ServicesGrpcAsyncIOTransport +from .transports.rest import ServicesRestTransport class ServicesClientMeta(type): @@ -63,6 +64,7 @@ class ServicesClientMeta(type): _transport_registry = OrderedDict() # type: Dict[str, Type[ServicesTransport]] _transport_registry["grpc"] = ServicesGrpcTransport _transport_registry["grpc_asyncio"] = ServicesGrpcAsyncIOTransport + _transport_registry["rest"] = ServicesRestTransport def get_transport_class( cls, @@ -465,6 +467,9 @@ def __init__( transport (Union[str, ServicesTransport]): The transport to use. If set to None, a transport is chosen automatically. + NOTE: "rest" transport functionality is currently in a + beta state (preview). We welcome your feedback via an + issue in this library's source repository. client_options (google.api_core.client_options.ClientOptions): Custom options for the client. It won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the diff --git a/google/cloud/run_v2/services/services/transports/__init__.py b/google/cloud/run_v2/services/services/transports/__init__.py index 7597c5d..9c2d606 100644 --- a/google/cloud/run_v2/services/services/transports/__init__.py +++ b/google/cloud/run_v2/services/services/transports/__init__.py @@ -19,15 +19,20 @@ from .base import ServicesTransport from .grpc import ServicesGrpcTransport from .grpc_asyncio import ServicesGrpcAsyncIOTransport +from .rest import ServicesRestTransport +from .rest import ServicesRestInterceptor # Compile a registry of transports. _transport_registry = OrderedDict() # type: Dict[str, Type[ServicesTransport]] _transport_registry["grpc"] = ServicesGrpcTransport _transport_registry["grpc_asyncio"] = ServicesGrpcAsyncIOTransport +_transport_registry["rest"] = ServicesRestTransport __all__ = ( "ServicesTransport", "ServicesGrpcTransport", "ServicesGrpcAsyncIOTransport", + "ServicesRestTransport", + "ServicesRestInterceptor", ) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index fe7fed3..f9b04b1 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,87 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.RevisionsClient", + "shortName": "RevisionsClient" + }, + "fullName": "google.cloud.run_v2.RevisionsClient.delete_revision", + "method": { + "fullName": "google.cloud.run.v2.Revisions.DeleteRevision", + "service": { + "fullName": "google.cloud.run.v2.Revisions", + "shortName": "Revisions" + }, + "shortName": "DeleteRevision" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.DeleteRevisionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_revision" + }, + "description": "Sample for DeleteRevision", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -294,7 +374,87 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Revisions_GetRevision_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.RevisionsClient", + "shortName": "RevisionsClient" + }, + "fullName": "google.cloud.run_v2.RevisionsClient.get_revision", + "method": { + "fullName": "google.cloud.run.v2.Revisions.GetRevision", + "service": { + "fullName": "google.cloud.run.v2.Revisions", + "shortName": "Revisions" + }, + "shortName": "GetRevision" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.GetRevisionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.run_v2.types.Revision", + "shortName": "get_revision" + }, + "description": "Sample for GetRevision", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -330,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -455,7 +615,87 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.RevisionsClient", + "shortName": "RevisionsClient" + }, + "fullName": "google.cloud.run_v2.RevisionsClient.list_revisions", + "method": { + "fullName": "google.cloud.run.v2.Revisions.ListRevisions", + "service": { + "fullName": "google.cloud.run.v2.Revisions", + "shortName": "Revisions" + }, + "shortName": "ListRevisions" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.ListRevisionsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.run_v2.services.revisions.pagers.ListRevisionsPager", + "shortName": "list_revisions" + }, + "description": "Sample for ListRevisions", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -491,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, @@ -632,7 +872,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync.py", + "file": "run_v2_generated_services_create_service_sync_3c405c33.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -668,42 +908,130 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync.py" + "title": "run_v2_generated_services_create_service_sync_3c405c33.py" }, { "canonical": true, "clientMethod": { - "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.delete_service", + "fullName": "google.cloud.run_v2.ServicesClient.create_service", "method": { - "fullName": "google.cloud.run.v2.Services.DeleteService", + "fullName": "google.cloud.run.v2.Services.CreateService", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "DeleteService" + "shortName": "CreateService" }, "parameters": [ { "name": "request", - "type": "google.cloud.run_v2.types.DeleteServiceRequest" + "type": "google.cloud.run_v2.types.CreateServiceRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { - "name": "retry", - "type": "google.api_core.retry.Retry" + "name": "service", + "type": "google.cloud.run_v2.types.Service" }, { - "name": "timeout", - "type": "float" - }, + "name": "service_id", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "create_service" + }, + "description": "Sample for CreateService", + "file": "run_v2_generated_services_create_service_sync_8031b824.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_CreateService_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_create_service_sync_8031b824.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" + }, + "fullName": "google.cloud.run_v2.ServicesAsyncClient.delete_service", + "method": { + "fullName": "google.cloud.run.v2.Services.DeleteService", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "DeleteService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.DeleteServiceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, { "name": "metadata", "type": "Sequence[Tuple[str, str]" @@ -793,7 +1121,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync.py", + "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -829,7 +1157,87 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync.py" + "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.delete_service", + "method": { + "fullName": "google.cloud.run.v2.Services.DeleteService", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "DeleteService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.DeleteServiceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "delete_service" + }, + "description": "Sample for DeleteService", + "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_DeleteService_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" }, { "canonical": true, @@ -946,7 +1354,83 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync.py", + "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.get_iam_policy", + "method": { + "fullName": "google.cloud.run.v2.Services.GetIamPolicy", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "GetIamPolicy" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.GetIamPolicyRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "get_iam_policy" + }, + "description": "Sample for GetIamPolicy", + "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -982,7 +1466,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync.py" + "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" }, { "canonical": true, @@ -1026,19 +1510,260 @@ "resultType": "google.cloud.run_v2.types.Service", "shortName": "get_service" }, - "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_async.py", + "description": "Sample for GetService", + "file": "run_v2_generated_services_get_service_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_GetService_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_get_service_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.get_service", + "method": { + "fullName": "google.cloud.run.v2.Services.GetService", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "GetService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.GetServiceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.run_v2.types.Service", + "shortName": "get_service" + }, + "description": "Sample for GetService", + "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_GetService_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.get_service", + "method": { + "fullName": "google.cloud.run.v2.Services.GetService", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "GetService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.GetServiceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.run_v2.types.Service", + "shortName": "get_service" + }, + "description": "Sample for GetService", + "file": "run_v2_generated_services_get_service_sync_18284d02.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_GetService_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_get_service_sync_18284d02.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" + }, + "fullName": "google.cloud.run_v2.ServicesAsyncClient.list_services", + "method": { + "fullName": "google.cloud.run.v2.Services.ListServices", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "ListServices" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.ListServicesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesAsyncPager", + "shortName": "list_services" + }, + "description": "Sample for ListServices", + "file": "run_v2_generated_services_list_services_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetService_async", + "regionTag": "run_v2_generated_Services_ListServices_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1058,12 +1783,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_async.py" + "title": "run_v2_generated_services_list_services_async.py" }, { "canonical": true, @@ -1072,22 +1797,22 @@ "fullName": "google.cloud.run_v2.ServicesClient", "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.get_service", + "fullName": "google.cloud.run_v2.ServicesClient.list_services", "method": { - "fullName": "google.cloud.run.v2.Services.GetService", + "fullName": "google.cloud.run.v2.Services.ListServices", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "GetService" + "shortName": "ListServices" }, "parameters": [ { "name": "request", - "type": "google.cloud.run_v2.types.GetServiceRequest" + "type": "google.cloud.run_v2.types.ListServicesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -1103,22 +1828,22 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.run_v2.types.Service", - "shortName": "get_service" + "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", + "shortName": "list_services" }, - "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync.py", + "description": "Sample for ListServices", + "file": "run_v2_generated_services_list_services_sync_c5743712.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_GetService_sync", + "regionTag": "run_v2_generated_Services_ListServices_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1138,22 +1863,21 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync.py" + "title": "run_v2_generated_services_list_services_sync_c5743712.py" }, { "canonical": true, "clientMethod": { - "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.list_services", + "fullName": "google.cloud.run_v2.ServicesClient.list_services", "method": { "fullName": "google.cloud.run.v2.Services.ListServices", "service": { @@ -1184,14 +1908,14 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesAsyncPager", + "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_async.py", + "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_ListServices_async", + "regionTag": "run_v2_generated_Services_ListServices_sync", "segments": [ { "end": 52, @@ -1224,32 +1948,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_async.py" + "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" }, { "canonical": true, "clientMethod": { + "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesClient", - "shortName": "ServicesClient" + "fullName": "google.cloud.run_v2.ServicesAsyncClient", + "shortName": "ServicesAsyncClient" }, - "fullName": "google.cloud.run_v2.ServicesClient.list_services", + "fullName": "google.cloud.run_v2.ServicesAsyncClient.set_iam_policy", "method": { - "fullName": "google.cloud.run.v2.Services.ListServices", + "fullName": "google.cloud.run.v2.Services.SetIamPolicy", "service": { "fullName": "google.cloud.run.v2.Services", "shortName": "Services" }, - "shortName": "ListServices" + "shortName": "SetIamPolicy" }, "parameters": [ { "name": "request", - "type": "google.cloud.run_v2.types.ListServicesRequest" - }, - { - "name": "parent", - "type": "str" + "type": "google.iam.v1.iam_policy_pb2.SetIamPolicyRequest" }, { "name": "retry", @@ -1264,14 +1985,14 @@ "type": "Sequence[Tuple[str, str]" } ], - "resultType": "google.cloud.run_v2.services.services.pagers.ListServicesPager", - "shortName": "list_services" + "resultType": "google.iam.v1.policy_pb2.Policy", + "shortName": "set_iam_policy" }, - "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync.py", + "description": "Sample for SetIamPolicy", + "file": "run_v2_generated_services_set_iam_policy_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_ListServices_sync", + "regionTag": "run_v2_generated_Services_SetIamPolicy_async", "segments": [ { "end": 52, @@ -1284,37 +2005,36 @@ "type": "SHORT" }, { - "end": 40, - "start": 38, + "end": 41, + "start": 39, "type": "CLIENT_INITIALIZATION" }, { - "end": 45, - "start": 41, + "end": 46, + "start": 42, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { "end": 53, - "start": 49, + "start": 50, "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync.py" + "title": "run_v2_generated_services_set_iam_policy_async.py" }, { "canonical": true, "clientMethod": { - "async": true, "client": { - "fullName": "google.cloud.run_v2.ServicesAsyncClient", - "shortName": "ServicesAsyncClient" + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" }, - "fullName": "google.cloud.run_v2.ServicesAsyncClient.set_iam_policy", + "fullName": "google.cloud.run_v2.ServicesClient.set_iam_policy", "method": { "fullName": "google.cloud.run.v2.Services.SetIamPolicy", "service": { @@ -1345,10 +2065,10 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_async.py", + "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "run_v2_generated_Services_SetIamPolicy_async", + "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", "segments": [ { "end": 52, @@ -1381,7 +2101,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_async.py" + "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" }, { "canonical": true, @@ -1421,7 +2141,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync.py", + "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -1457,7 +2177,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync.py" + "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" }, { "canonical": true, @@ -1574,7 +2294,83 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 41, + "start": 39, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 42, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.test_iam_permissions", + "method": { + "fullName": "google.cloud.run.v2.Services.TestIamPermissions", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "TestIamPermissions" + }, + "parameters": [ + { + "name": "request", + "type": "google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse", + "shortName": "test_iam_permissions" + }, + "description": "Sample for TestIamPermissions", + "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -1610,7 +2406,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" }, { "canonical": true, @@ -1735,7 +2531,87 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync.py", + "file": "run_v2_generated_services_update_service_sync_9076a854.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "run_v2_generated_Services_UpdateService_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "run_v2_generated_services_update_service_sync_9076a854.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.run_v2.ServicesClient", + "shortName": "ServicesClient" + }, + "fullName": "google.cloud.run_v2.ServicesClient.update_service", + "method": { + "fullName": "google.cloud.run.v2.Services.UpdateService", + "service": { + "fullName": "google.cloud.run.v2.Services", + "shortName": "Services" + }, + "shortName": "UpdateService" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.run_v2.types.UpdateServiceRequest" + }, + { + "name": "service", + "type": "google.cloud.run_v2.types.Service" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "update_service" + }, + "description": "Sample for UpdateService", + "file": "run_v2_generated_services_update_service_sync_2652a462.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -1771,7 +2647,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync.py" + "title": "run_v2_generated_services_update_service_sync_2652a462.py" } ] } diff --git a/tests/unit/gapic/run_v2/test_revisions.py b/tests/unit/gapic/run_v2/test_revisions.py index b49691c..c081633 100644 --- a/tests/unit/gapic/run_v2/test_revisions.py +++ b/tests/unit/gapic/run_v2/test_revisions.py @@ -24,10 +24,17 @@ import grpc from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json import math import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format from google.api import launch_stage_pb2 # type: ignore from google.api_core import client_options @@ -101,6 +108,7 @@ def test__get_default_mtls_endpoint(): [ (RevisionsClient, "grpc"), (RevisionsAsyncClient, "grpc_asyncio"), + (RevisionsClient, "rest"), ], ) def test_revisions_client_from_service_account_info(client_class, transport_name): @@ -114,7 +122,11 @@ def test_revisions_client_from_service_account_info(client_class, transport_name assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) @pytest.mark.parametrize( @@ -122,6 +134,7 @@ def test_revisions_client_from_service_account_info(client_class, transport_name [ (transports.RevisionsGrpcTransport, "grpc"), (transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.RevisionsRestTransport, "rest"), ], ) def test_revisions_client_service_account_always_use_jwt( @@ -147,6 +160,7 @@ def test_revisions_client_service_account_always_use_jwt( [ (RevisionsClient, "grpc"), (RevisionsAsyncClient, "grpc_asyncio"), + (RevisionsClient, "rest"), ], ) def test_revisions_client_from_service_account_file(client_class, transport_name): @@ -167,13 +181,18 @@ def test_revisions_client_from_service_account_file(client_class, transport_name assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) def test_revisions_client_get_transport_class(): transport = RevisionsClient.get_transport_class() available_transports = [ transports.RevisionsGrpcTransport, + transports.RevisionsRestTransport, ] assert transport in available_transports @@ -190,6 +209,7 @@ def test_revisions_client_get_transport_class(): transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio", ), + (RevisionsClient, transports.RevisionsRestTransport, "rest"), ], ) @mock.patch.object( @@ -331,6 +351,8 @@ def test_revisions_client_client_options(client_class, transport_class, transpor "grpc_asyncio", "false", ), + (RevisionsClient, transports.RevisionsRestTransport, "rest", "true"), + (RevisionsClient, transports.RevisionsRestTransport, "rest", "false"), ], ) @mock.patch.object( @@ -524,6 +546,7 @@ def test_revisions_client_get_mtls_endpoint_and_cert_source(client_class): transports.RevisionsGrpcAsyncIOTransport, "grpc_asyncio", ), + (RevisionsClient, transports.RevisionsRestTransport, "rest"), ], ) def test_revisions_client_client_options_scopes( @@ -559,6 +582,7 @@ def test_revisions_client_client_options_scopes( "grpc_asyncio", grpc_helpers_async, ), + (RevisionsClient, transports.RevisionsRestTransport, "rest", None), ], ) def test_revisions_client_client_options_credentials_file( @@ -1486,6 +1510,919 @@ async def test_delete_revision_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + revision.GetRevisionRequest, + dict, + ], +) +def test_get_revision_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = revision.Revision( + name="name_value", + uid="uid_value", + generation=1068, + launch_stage=launch_stage_pb2.LaunchStage.UNIMPLEMENTED, + service="service_value", + max_instance_request_concurrency=3436, + service_account="service_account_value", + execution_environment=vendor_settings.ExecutionEnvironment.EXECUTION_ENVIRONMENT_GEN1, + encryption_key="encryption_key_value", + reconciling=True, + observed_generation=2021, + log_uri="log_uri_value", + etag="etag_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = revision.Revision.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_revision(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, revision.Revision) + assert response.name == "name_value" + assert response.uid == "uid_value" + assert response.generation == 1068 + assert response.launch_stage == launch_stage_pb2.LaunchStage.UNIMPLEMENTED + assert response.service == "service_value" + assert response.max_instance_request_concurrency == 3436 + assert response.service_account == "service_account_value" + assert ( + response.execution_environment + == vendor_settings.ExecutionEnvironment.EXECUTION_ENVIRONMENT_GEN1 + ) + assert response.encryption_key == "encryption_key_value" + assert response.reconciling is True + assert response.observed_generation == 2021 + assert response.log_uri == "log_uri_value" + assert response.etag == "etag_value" + + +def test_get_revision_rest_required_fields(request_type=revision.GetRevisionRequest): + transport_class = transports.RevisionsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_revision._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_revision._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = revision.Revision() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = revision.Revision.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_revision(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_revision_rest_unset_required_fields(): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_revision._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_revision_rest_interceptors(null_interceptor): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), + ) + client = RevisionsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RevisionsRestInterceptor, "post_get_revision" + ) as post, mock.patch.object( + transports.RevisionsRestInterceptor, "pre_get_revision" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = revision.GetRevisionRequest.pb(revision.GetRevisionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = revision.Revision.to_json(revision.Revision()) + + request = revision.GetRevisionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = revision.Revision() + + client.get_revision( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_revision_rest_bad_request( + transport: str = "rest", request_type=revision.GetRevisionRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_revision(request) + + +def test_get_revision_rest_flattened(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = revision.Revision() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = revision.Revision.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_revision(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/services/*/revisions/*}" + % client.transport._host, + args[1], + ) + + +def test_get_revision_rest_flattened_error(transport: str = "rest"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_revision( + revision.GetRevisionRequest(), + name="name_value", + ) + + +def test_get_revision_rest_error(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + revision.ListRevisionsRequest, + dict, + ], +) +def test_list_revisions_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = revision.ListRevisionsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = revision.ListRevisionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_revisions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListRevisionsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_revisions_rest_required_fields( + request_type=revision.ListRevisionsRequest, +): + transport_class = transports.RevisionsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_revisions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_revisions._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "show_deleted", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = revision.ListRevisionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = revision.ListRevisionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_revisions(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_revisions_rest_unset_required_fields(): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_revisions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + "showDeleted", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_revisions_rest_interceptors(null_interceptor): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), + ) + client = RevisionsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.RevisionsRestInterceptor, "post_list_revisions" + ) as post, mock.patch.object( + transports.RevisionsRestInterceptor, "pre_list_revisions" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = revision.ListRevisionsRequest.pb(revision.ListRevisionsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = revision.ListRevisionsResponse.to_json( + revision.ListRevisionsResponse() + ) + + request = revision.ListRevisionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = revision.ListRevisionsResponse() + + client.list_revisions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_revisions_rest_bad_request( + transport: str = "rest", request_type=revision.ListRevisionsRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_revisions(request) + + +def test_list_revisions_rest_flattened(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = revision.ListRevisionsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/services/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = revision.ListRevisionsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_revisions(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=projects/*/locations/*/services/*}/revisions" + % client.transport._host, + args[1], + ) + + +def test_list_revisions_rest_flattened_error(transport: str = "rest"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_revisions( + revision.ListRevisionsRequest(), + parent="parent_value", + ) + + +def test_list_revisions_rest_pager(transport: str = "rest"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + revision.ListRevisionsResponse( + revisions=[ + revision.Revision(), + revision.Revision(), + revision.Revision(), + ], + next_page_token="abc", + ), + revision.ListRevisionsResponse( + revisions=[], + next_page_token="def", + ), + revision.ListRevisionsResponse( + revisions=[ + revision.Revision(), + ], + next_page_token="ghi", + ), + revision.ListRevisionsResponse( + revisions=[ + revision.Revision(), + revision.Revision(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(revision.ListRevisionsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/services/sample3" + } + + pager = client.list_revisions(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, revision.Revision) for i in results) + + pages = list(client.list_revisions(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + revision.DeleteRevisionRequest, + dict, + ], +) +def test_delete_revision_rest(request_type): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_revision(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_delete_revision_rest_required_fields( + request_type=revision.DeleteRevisionRequest, +): + transport_class = transports.RevisionsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_revision._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_revision._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "etag", + "validate_only", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_revision(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_revision_rest_unset_required_fields(): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_revision._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "etag", + "validateOnly", + ) + ) + & set(("name",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_revision_rest_interceptors(null_interceptor): + transport = transports.RevisionsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.RevisionsRestInterceptor(), + ) + client = RevisionsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.RevisionsRestInterceptor, "post_delete_revision" + ) as post, mock.patch.object( + transports.RevisionsRestInterceptor, "pre_delete_revision" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = revision.DeleteRevisionRequest.pb(revision.DeleteRevisionRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = revision.DeleteRevisionRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.delete_revision( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_revision_rest_bad_request( + transport: str = "rest", request_type=revision.DeleteRevisionRequest +): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_revision(request) + + +def test_delete_revision_rest_flattened(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/services/sample3/revisions/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_revision(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/services/*/revisions/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_revision_rest_flattened_error(transport: str = "rest"): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_revision( + revision.DeleteRevisionRequest(), + name="name_value", + ) + + +def test_delete_revision_rest_error(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.RevisionsGrpcTransport( @@ -1567,6 +2504,7 @@ def test_transport_get_channel(): [ transports.RevisionsGrpcTransport, transports.RevisionsGrpcAsyncIOTransport, + transports.RevisionsRestTransport, ], ) def test_transport_adc(transport_class): @@ -1581,6 +2519,7 @@ def test_transport_adc(transport_class): "transport_name", [ "grpc", + "rest", ], ) def test_transport_kind(transport_name): @@ -1717,6 +2656,7 @@ def test_revisions_transport_auth_adc(transport_class): [ transports.RevisionsGrpcTransport, transports.RevisionsGrpcAsyncIOTransport, + transports.RevisionsRestTransport, ], ) def test_revisions_transport_auth_gdch_credentials(transport_class): @@ -1811,11 +2751,40 @@ def test_revisions_grpc_transport_client_cert_source_for_mtls(transport_class): ) +def test_revisions_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.RevisionsRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_revisions_rest_lro_client(): + client = RevisionsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + @pytest.mark.parametrize( "transport_name", [ "grpc", "grpc_asyncio", + "rest", ], ) def test_revisions_host_no_port(transport_name): @@ -1824,7 +2793,11 @@ def test_revisions_host_no_port(transport_name): client_options=client_options.ClientOptions(api_endpoint="run.googleapis.com"), transport=transport_name, ) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) @pytest.mark.parametrize( @@ -1832,6 +2805,7 @@ def test_revisions_host_no_port(transport_name): [ "grpc", "grpc_asyncio", + "rest", ], ) def test_revisions_host_with_port(transport_name): @@ -1842,7 +2816,39 @@ def test_revisions_host_with_port(transport_name): ), transport=transport_name, ) - assert client.transport._host == ("run.googleapis.com:8000") + assert client.transport._host == ( + "run.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_revisions_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = RevisionsClient( + credentials=creds1, + transport=transport_name, + ) + client2 = RevisionsClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_revision._session + session2 = client2.transport.get_revision._session + assert session1 != session2 + session1 = client1.transport.list_revisions._session + session2 = client2.transport.list_revisions._session + assert session1 != session2 + session1 = client1.transport.delete_revision._session + session2 = client2.transport.delete_revision._session + assert session1 != session2 def test_revisions_grpc_transport_channel(): @@ -2298,6 +3304,7 @@ async def test_transport_close_async(): def test_transport_close(): transports = { + "rest": "_session", "grpc": "_grpc_channel", } @@ -2315,6 +3322,7 @@ def test_transport_close(): def test_client_ctx(): transports = [ + "rest", "grpc", ] for transport in transports: diff --git a/tests/unit/gapic/run_v2/test_services.py b/tests/unit/gapic/run_v2/test_services.py index f791bb2..910dae2 100644 --- a/tests/unit/gapic/run_v2/test_services.py +++ b/tests/unit/gapic/run_v2/test_services.py @@ -24,10 +24,17 @@ import grpc from grpc.experimental import aio +from collections.abc import Iterable +from google.protobuf import json_format +import json import math import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule from proto.marshal.rules import wrappers +from requests import Response +from requests import Request, PreparedRequest +from requests.sessions import Session +from google.protobuf import json_format from google.api import launch_stage_pb2 # type: ignore from google.api_core import client_options @@ -109,6 +116,7 @@ def test__get_default_mtls_endpoint(): [ (ServicesClient, "grpc"), (ServicesAsyncClient, "grpc_asyncio"), + (ServicesClient, "rest"), ], ) def test_services_client_from_service_account_info(client_class, transport_name): @@ -122,7 +130,11 @@ def test_services_client_from_service_account_info(client_class, transport_name) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) @pytest.mark.parametrize( @@ -130,6 +142,7 @@ def test_services_client_from_service_account_info(client_class, transport_name) [ (transports.ServicesGrpcTransport, "grpc"), (transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ServicesRestTransport, "rest"), ], ) def test_services_client_service_account_always_use_jwt( @@ -155,6 +168,7 @@ def test_services_client_service_account_always_use_jwt( [ (ServicesClient, "grpc"), (ServicesAsyncClient, "grpc_asyncio"), + (ServicesClient, "rest"), ], ) def test_services_client_from_service_account_file(client_class, transport_name): @@ -175,13 +189,18 @@ def test_services_client_from_service_account_file(client_class, transport_name) assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) def test_services_client_get_transport_class(): transport = ServicesClient.get_transport_class() available_transports = [ transports.ServicesGrpcTransport, + transports.ServicesRestTransport, ] assert transport in available_transports @@ -194,6 +213,7 @@ def test_services_client_get_transport_class(): [ (ServicesClient, transports.ServicesGrpcTransport, "grpc"), (ServicesAsyncClient, transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), + (ServicesClient, transports.ServicesRestTransport, "rest"), ], ) @mock.patch.object( @@ -335,6 +355,8 @@ def test_services_client_client_options(client_class, transport_class, transport "grpc_asyncio", "false", ), + (ServicesClient, transports.ServicesRestTransport, "rest", "true"), + (ServicesClient, transports.ServicesRestTransport, "rest", "false"), ], ) @mock.patch.object( @@ -524,6 +546,7 @@ def test_services_client_get_mtls_endpoint_and_cert_source(client_class): [ (ServicesClient, transports.ServicesGrpcTransport, "grpc"), (ServicesAsyncClient, transports.ServicesGrpcAsyncIOTransport, "grpc_asyncio"), + (ServicesClient, transports.ServicesRestTransport, "rest"), ], ) def test_services_client_client_options_scopes( @@ -559,6 +582,7 @@ def test_services_client_client_options_scopes( "grpc_asyncio", grpc_helpers_async, ), + (ServicesClient, transports.ServicesRestTransport, "rest", None), ], ) def test_services_client_client_options_credentials_file( @@ -2413,222 +2437,2789 @@ def test_test_iam_permissions_from_dict_foreign(): call.assert_called() -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.ServicesGrpcTransport( +@pytest.mark.parametrize( + "request_type", + [ + gcr_service.CreateServiceRequest, + dict, + ], +) +def test_create_service_rest(request_type): + client = ServicesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ServicesClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["service"] = { + "name": "name_value", + "description": "description_value", + "uid": "uid_value", + "generation": 1068, + "labels": {}, + "annotations": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "delete_time": {}, + "expire_time": {}, + "creator": "creator_value", + "last_modifier": "last_modifier_value", + "client": "client_value", + "client_version": "client_version_value", + "ingress": 1, + "launch_stage": 6, + "binary_authorization": { + "use_default": True, + "breakglass_justification": "breakglass_justification_value", + }, + "template": { + "revision": "revision_value", + "labels": {}, + "annotations": {}, + "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, + "vpc_access": {"connector": "connector_value", "egress": 1}, + "timeout": {"seconds": 751, "nanos": 543}, + "service_account": "service_account_value", + "containers": [ + { + "name": "name_value", + "image": "image_value", + "command": ["command_value1", "command_value2"], + "args": ["args_value1", "args_value2"], + "env": [ + { + "name": "name_value", + "value": "value_value", + "value_source": { + "secret_key_ref": { + "secret": "secret_value", + "version": "version_value", + } + }, + } + ], + "resources": {"limits": {}, "cpu_idle": True}, + "ports": [{"name": "name_value", "container_port": 1511}], + "volume_mounts": [ + {"name": "name_value", "mount_path": "mount_path_value"} + ], + } + ], + "volumes": [ + { + "name": "name_value", + "secret": { + "secret": "secret_value", + "items": [ + { + "path": "path_value", + "version": "version_value", + "mode": 421, + } + ], + "default_mode": 1257, + }, + "cloud_sql_instance": { + "instances": ["instances_value1", "instances_value2"] + }, + } + ], + "execution_environment": 1, + "encryption_key": "encryption_key_value", + "max_instance_request_concurrency": 3436, + }, + "traffic": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + } + ], + "observed_generation": 2021, + "terminal_condition": { + "type_": "type__value", + "state": 1, + "message": "message_value", + "last_transition_time": {}, + "severity": 1, + "reason": 1, + "revision_reason": 1, + "execution_reason": 1, + }, + "conditions": {}, + "latest_ready_revision": "latest_ready_revision_value", + "latest_created_revision": "latest_created_revision_value", + "traffic_statuses": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + "uri": "uri_value", + } + ], + "uri": "uri_value", + "reconciling": True, + "etag": "etag_value", + } + request = request_type(**request_init) - # It is an error to provide an api_key and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ServicesClient( - client_options=options, - transport=transport, - ) + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") - # It is an error to provide an api_key and a credential. - options = mock.Mock() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = ServicesClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() - ) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) - # It is an error to provide scopes and a transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = ServicesClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_service(request) + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + +def test_create_service_rest_required_fields( + request_type=gcr_service.CreateServiceRequest, +): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["service_id"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) ) - client = ServicesClient(transport=transport) - assert client.transport is transport + # verify fields with default values are dropped + assert "serviceId" not in jsonified_request -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.ServicesGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "serviceId" in jsonified_request + assert jsonified_request["serviceId"] == request_init["service_id"] + + jsonified_request["parent"] = "parent_value" + jsonified_request["serviceId"] = "service_id_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_service._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "service_id", + "validate_only", + ) ) - channel = transport.grpc_channel - assert channel + jsonified_request.update(unset_fields) - transport = transports.ServicesGrpcAsyncIOTransport( + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "serviceId" in jsonified_request + assert jsonified_request["serviceId"] == "service_id_value" + + client = ServicesClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - channel = transport.grpc_channel - assert channel + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) -@pytest.mark.parametrize( - "transport_class", - [ - transports.ServicesGrpcTransport, - transports.ServicesGrpcAsyncIOTransport, - ], -) -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() + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_service(request) -@pytest.mark.parametrize( - "transport_name", - [ - "grpc", - ], -) -def test_transport_kind(transport_name): - transport = ServicesClient.get_transport_class(transport_name)( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert transport.kind == transport_name + expected_params = [ + ( + "serviceId", + "", + ), + ] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = ServicesClient( - credentials=ga_credentials.AnonymousCredentials(), +def test_create_service_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials ) - assert isinstance( - client.transport, - transports.ServicesGrpcTransport, + + unset_fields = transport.create_service._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "serviceId", + "validateOnly", + ) + ) + & set( + ( + "parent", + "service", + "serviceId", + ) + ) ) -def test_services_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.ServicesTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_service_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ServicesRestInterceptor, "post_create_service" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_create_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = gcr_service.CreateServiceRequest.pb( + gcr_service.CreateServiceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() ) + request = gcr_service.CreateServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() -def test_services_base_transport(): - # Instantiate the base transport. - with mock.patch( - "google.cloud.run_v2.services.services.transports.ServicesTransport.__init__" - ) as Transport: - Transport.return_value = None - transport = transports.ServicesTransport( - credentials=ga_credentials.AnonymousCredentials(), + client.create_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], ) - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "create_service", - "get_service", - "list_services", - "update_service", - "delete_service", - "get_iam_policy", - "set_iam_policy", - "test_iam_permissions", + pre.assert_called_once() + post.assert_called_once() + + +def test_create_service_rest_bad_request( + transport: str = "rest", request_type=gcr_service.CreateServiceRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - with pytest.raises(NotImplementedError): - transport.close() + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["service"] = { + "name": "name_value", + "description": "description_value", + "uid": "uid_value", + "generation": 1068, + "labels": {}, + "annotations": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "delete_time": {}, + "expire_time": {}, + "creator": "creator_value", + "last_modifier": "last_modifier_value", + "client": "client_value", + "client_version": "client_version_value", + "ingress": 1, + "launch_stage": 6, + "binary_authorization": { + "use_default": True, + "breakglass_justification": "breakglass_justification_value", + }, + "template": { + "revision": "revision_value", + "labels": {}, + "annotations": {}, + "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, + "vpc_access": {"connector": "connector_value", "egress": 1}, + "timeout": {"seconds": 751, "nanos": 543}, + "service_account": "service_account_value", + "containers": [ + { + "name": "name_value", + "image": "image_value", + "command": ["command_value1", "command_value2"], + "args": ["args_value1", "args_value2"], + "env": [ + { + "name": "name_value", + "value": "value_value", + "value_source": { + "secret_key_ref": { + "secret": "secret_value", + "version": "version_value", + } + }, + } + ], + "resources": {"limits": {}, "cpu_idle": True}, + "ports": [{"name": "name_value", "container_port": 1511}], + "volume_mounts": [ + {"name": "name_value", "mount_path": "mount_path_value"} + ], + } + ], + "volumes": [ + { + "name": "name_value", + "secret": { + "secret": "secret_value", + "items": [ + { + "path": "path_value", + "version": "version_value", + "mode": 421, + } + ], + "default_mode": 1257, + }, + "cloud_sql_instance": { + "instances": ["instances_value1", "instances_value2"] + }, + } + ], + "execution_environment": 1, + "encryption_key": "encryption_key_value", + "max_instance_request_concurrency": 3436, + }, + "traffic": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + } + ], + "observed_generation": 2021, + "terminal_condition": { + "type_": "type__value", + "state": 1, + "message": "message_value", + "last_transition_time": {}, + "severity": 1, + "reason": 1, + "revision_reason": 1, + "execution_reason": 1, + }, + "conditions": {}, + "latest_ready_revision": "latest_ready_revision_value", + "latest_created_revision": "latest_created_revision_value", + "traffic_statuses": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + "uri": "uri_value", + } + ], + "uri": "uri_value", + "reconciling": True, + "etag": "etag_value", + } + request = request_type(**request_init) - # Additionally, the LRO client (a property) should - # also raise NotImplementedError - with pytest.raises(NotImplementedError): - transport.operations_client + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_service(request) - # Catch all for all remaining methods and properties - remainder = [ - "kind", - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() +def test_create_service_rest_flattened(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) -def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ServicesTransport( - 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", + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + service=gcr_service.Service(name="name_value"), + service_id="service_id_value", ) + mock_args.update(sample_request) + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value -def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" - ) as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.ServicesTransport() - adc.assert_called_once() + client.create_service(**mock_args) + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=projects/*/locations/*}/services" % client.transport._host, + args[1], + ) -def test_services_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) - ServicesClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=("https://www.googleapis.com/auth/cloud-platform",), - quota_project_id=None, + +def test_create_service_rest_flattened_error(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_service( + gcr_service.CreateServiceRequest(), + parent="parent_value", + service=gcr_service.Service(name="name_value"), + service_id="service_id_value", ) +def test_create_service_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + @pytest.mark.parametrize( - "transport_class", + "request_type", [ - transports.ServicesGrpcTransport, - transports.ServicesGrpcAsyncIOTransport, + service.GetServiceRequest, + dict, + ], +) +def test_get_service_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = service.Service( + name="name_value", + description="description_value", + uid="uid_value", + generation=1068, + creator="creator_value", + last_modifier="last_modifier_value", + client="client_value", + client_version="client_version_value", + ingress=vendor_settings.IngressTraffic.INGRESS_TRAFFIC_ALL, + launch_stage=launch_stage_pb2.LaunchStage.UNIMPLEMENTED, + observed_generation=2021, + latest_ready_revision="latest_ready_revision_value", + latest_created_revision="latest_created_revision_value", + uri="uri_value", + reconciling=True, + etag="etag_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = service.Service.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_service(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, service.Service) + assert response.name == "name_value" + assert response.description == "description_value" + assert response.uid == "uid_value" + assert response.generation == 1068 + assert response.creator == "creator_value" + assert response.last_modifier == "last_modifier_value" + assert response.client == "client_value" + assert response.client_version == "client_version_value" + assert response.ingress == vendor_settings.IngressTraffic.INGRESS_TRAFFIC_ALL + assert response.launch_stage == launch_stage_pb2.LaunchStage.UNIMPLEMENTED + assert response.observed_generation == 2021 + assert response.latest_ready_revision == "latest_ready_revision_value" + assert response.latest_created_revision == "latest_created_revision_value" + assert response.uri == "uri_value" + assert response.reconciling is True + assert response.etag == "etag_value" + + +def test_get_service_rest_required_fields(request_type=service.GetServiceRequest): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = service.Service() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = service.Service.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_service(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_service_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_service._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_service_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ServicesRestInterceptor, "post_get_service" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_get_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = service.GetServiceRequest.pb(service.GetServiceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = service.Service.to_json(service.Service()) + + request = service.GetServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = service.Service() + + client.get_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_service_rest_bad_request( + transport: str = "rest", request_type=service.GetServiceRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_service(request) + + +def test_get_service_rest_flattened(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = service.Service() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/locations/sample2/services/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = service.Service.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_service(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/services/*}" % client.transport._host, + args[1], + ) + + +def test_get_service_rest_flattened_error(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_service( + service.GetServiceRequest(), + name="name_value", + ) + + +def test_get_service_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + service.ListServicesRequest, + dict, + ], +) +def test_list_services_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = service.ListServicesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = service.ListServicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_services(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServicesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_services_rest_required_fields(request_type=service.ListServicesRequest): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_services._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_services._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + "show_deleted", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = service.ListServicesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = service.ListServicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_services(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_services_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_services._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + "showDeleted", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_services_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ServicesRestInterceptor, "post_list_services" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_list_services" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = service.ListServicesRequest.pb(service.ListServicesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = service.ListServicesResponse.to_json( + service.ListServicesResponse() + ) + + request = service.ListServicesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = service.ListServicesResponse() + + client.list_services( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_services_rest_bad_request( + transport: str = "rest", request_type=service.ListServicesRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_services(request) + + +def test_list_services_rest_flattened(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = service.ListServicesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = service.ListServicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_services(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{parent=projects/*/locations/*}/services" % client.transport._host, + args[1], + ) + + +def test_list_services_rest_flattened_error(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_services( + service.ListServicesRequest(), + parent="parent_value", + ) + + +def test_list_services_rest_pager(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + service.ListServicesResponse( + services=[ + service.Service(), + service.Service(), + service.Service(), + ], + next_page_token="abc", + ), + service.ListServicesResponse( + services=[], + next_page_token="def", + ), + service.ListServicesResponse( + services=[ + service.Service(), + ], + next_page_token="ghi", + ), + service.ListServicesResponse( + services=[ + service.Service(), + service.Service(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(service.ListServicesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_services(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, service.Service) for i in results) + + pages = list(client.list_services(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + gcr_service.UpdateServiceRequest, + dict, + ], +) +def test_update_service_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "service": {"name": "projects/sample1/locations/sample2/services/sample3"} + } + request_init["service"] = { + "name": "projects/sample1/locations/sample2/services/sample3", + "description": "description_value", + "uid": "uid_value", + "generation": 1068, + "labels": {}, + "annotations": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "delete_time": {}, + "expire_time": {}, + "creator": "creator_value", + "last_modifier": "last_modifier_value", + "client": "client_value", + "client_version": "client_version_value", + "ingress": 1, + "launch_stage": 6, + "binary_authorization": { + "use_default": True, + "breakglass_justification": "breakglass_justification_value", + }, + "template": { + "revision": "revision_value", + "labels": {}, + "annotations": {}, + "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, + "vpc_access": {"connector": "connector_value", "egress": 1}, + "timeout": {"seconds": 751, "nanos": 543}, + "service_account": "service_account_value", + "containers": [ + { + "name": "name_value", + "image": "image_value", + "command": ["command_value1", "command_value2"], + "args": ["args_value1", "args_value2"], + "env": [ + { + "name": "name_value", + "value": "value_value", + "value_source": { + "secret_key_ref": { + "secret": "secret_value", + "version": "version_value", + } + }, + } + ], + "resources": {"limits": {}, "cpu_idle": True}, + "ports": [{"name": "name_value", "container_port": 1511}], + "volume_mounts": [ + {"name": "name_value", "mount_path": "mount_path_value"} + ], + } + ], + "volumes": [ + { + "name": "name_value", + "secret": { + "secret": "secret_value", + "items": [ + { + "path": "path_value", + "version": "version_value", + "mode": 421, + } + ], + "default_mode": 1257, + }, + "cloud_sql_instance": { + "instances": ["instances_value1", "instances_value2"] + }, + } + ], + "execution_environment": 1, + "encryption_key": "encryption_key_value", + "max_instance_request_concurrency": 3436, + }, + "traffic": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + } + ], + "observed_generation": 2021, + "terminal_condition": { + "type_": "type__value", + "state": 1, + "message": "message_value", + "last_transition_time": {}, + "severity": 1, + "reason": 1, + "revision_reason": 1, + "execution_reason": 1, + }, + "conditions": {}, + "latest_ready_revision": "latest_ready_revision_value", + "latest_created_revision": "latest_created_revision_value", + "traffic_statuses": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + "uri": "uri_value", + } + ], + "uri": "uri_value", + "reconciling": True, + "etag": "etag_value", + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_service(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_update_service_rest_required_fields( + request_type=gcr_service.UpdateServiceRequest, +): + transport_class = transports.ServicesRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_service._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "allow_missing", + "validate_only", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_service(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_service_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_service._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "allowMissing", + "validateOnly", + ) + ) + & set(("service",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_service_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ServicesRestInterceptor, "post_update_service" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_update_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = gcr_service.UpdateServiceRequest.pb( + gcr_service.UpdateServiceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = gcr_service.UpdateServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.update_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_service_rest_bad_request( + transport: str = "rest", request_type=gcr_service.UpdateServiceRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "service": {"name": "projects/sample1/locations/sample2/services/sample3"} + } + request_init["service"] = { + "name": "projects/sample1/locations/sample2/services/sample3", + "description": "description_value", + "uid": "uid_value", + "generation": 1068, + "labels": {}, + "annotations": {}, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "delete_time": {}, + "expire_time": {}, + "creator": "creator_value", + "last_modifier": "last_modifier_value", + "client": "client_value", + "client_version": "client_version_value", + "ingress": 1, + "launch_stage": 6, + "binary_authorization": { + "use_default": True, + "breakglass_justification": "breakglass_justification_value", + }, + "template": { + "revision": "revision_value", + "labels": {}, + "annotations": {}, + "scaling": {"min_instance_count": 1920, "max_instance_count": 1922}, + "vpc_access": {"connector": "connector_value", "egress": 1}, + "timeout": {"seconds": 751, "nanos": 543}, + "service_account": "service_account_value", + "containers": [ + { + "name": "name_value", + "image": "image_value", + "command": ["command_value1", "command_value2"], + "args": ["args_value1", "args_value2"], + "env": [ + { + "name": "name_value", + "value": "value_value", + "value_source": { + "secret_key_ref": { + "secret": "secret_value", + "version": "version_value", + } + }, + } + ], + "resources": {"limits": {}, "cpu_idle": True}, + "ports": [{"name": "name_value", "container_port": 1511}], + "volume_mounts": [ + {"name": "name_value", "mount_path": "mount_path_value"} + ], + } + ], + "volumes": [ + { + "name": "name_value", + "secret": { + "secret": "secret_value", + "items": [ + { + "path": "path_value", + "version": "version_value", + "mode": 421, + } + ], + "default_mode": 1257, + }, + "cloud_sql_instance": { + "instances": ["instances_value1", "instances_value2"] + }, + } + ], + "execution_environment": 1, + "encryption_key": "encryption_key_value", + "max_instance_request_concurrency": 3436, + }, + "traffic": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + } + ], + "observed_generation": 2021, + "terminal_condition": { + "type_": "type__value", + "state": 1, + "message": "message_value", + "last_transition_time": {}, + "severity": 1, + "reason": 1, + "revision_reason": 1, + "execution_reason": 1, + }, + "conditions": {}, + "latest_ready_revision": "latest_ready_revision_value", + "latest_created_revision": "latest_created_revision_value", + "traffic_statuses": [ + { + "type_": 1, + "revision": "revision_value", + "percent": 753, + "tag": "tag_value", + "uri": "uri_value", + } + ], + "uri": "uri_value", + "reconciling": True, + "etag": "etag_value", + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_service(request) + + +def test_update_service_rest_flattened(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "service": {"name": "projects/sample1/locations/sample2/services/sample3"} + } + + # get truthy value for each flattened field + mock_args = dict( + service=gcr_service.Service(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_service(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{service.name=projects/*/locations/*/services/*}" + % client.transport._host, + args[1], + ) + + +def test_update_service_rest_flattened_error(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_service( + gcr_service.UpdateServiceRequest(), + service=gcr_service.Service(name="name_value"), + ) + + +def test_update_service_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + service.DeleteServiceRequest, + dict, + ], +) +def test_delete_service_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_service(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_delete_service_rest_required_fields(request_type=service.DeleteServiceRequest): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_service._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_service._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "etag", + "validate_only", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_service(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_service_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_service._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "etag", + "validateOnly", + ) + ) + & set(("name",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_service_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.ServicesRestInterceptor, "post_delete_service" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_delete_service" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = service.DeleteServiceRequest.pb(service.DeleteServiceRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = service.DeleteServiceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.delete_service( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_delete_service_rest_bad_request( + transport: str = "rest", request_type=service.DeleteServiceRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_service(request) + + +def test_delete_service_rest_flattened(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/locations/sample2/services/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_service(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2/{name=projects/*/locations/*/services/*}" % client.transport._host, + args[1], + ) + + +def test_delete_service_rest_flattened_error(transport: str = "rest"): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_service( + service.DeleteServiceRequest(), + name="name_value", + ) + + +def test_delete_service_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.GetIamPolicyRequest, + dict, + ], +) +def test_get_iam_policy_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_iam_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +def test_get_iam_policy_rest_required_fields( + request_type=iam_policy_pb2.GetIamPolicyRequest, +): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["resource"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_iam_policy._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("options",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_iam_policy(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_iam_policy_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_iam_policy._get_unset_required_fields({}) + assert set(unset_fields) == (set(("options",)) & set(("resource",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_iam_policy_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ServicesRestInterceptor, "post_get_iam_policy" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_get_iam_policy" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.GetIamPolicyRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) + + request = iam_policy_pb2.GetIamPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = policy_pb2.Policy() + + client.get_iam_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_iam_policy_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.GetIamPolicyRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_iam_policy(request) + + +def test_get_iam_policy_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.SetIamPolicyRequest, + dict, + ], +) +def test_set_iam_policy_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy( + version=774, + etag=b"etag_blob", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.set_iam_policy(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, policy_pb2.Policy) + assert response.version == 774 + assert response.etag == b"etag_blob" + + +def test_set_iam_policy_rest_required_fields( + request_type=iam_policy_pb2.SetIamPolicyRequest, +): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["resource"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).set_iam_policy._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = policy_pb2.Policy() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.set_iam_policy(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_set_iam_policy_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.set_iam_policy._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "resource", + "policy", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_iam_policy_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ServicesRestInterceptor, "post_set_iam_policy" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_set_iam_policy" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.SetIamPolicyRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson(policy_pb2.Policy()) + + request = iam_policy_pb2.SetIamPolicyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = policy_pb2.Policy() + + client.set_iam_policy( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_iam_policy_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.SetIamPolicyRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.set_iam_policy(request) + + +def test_set_iam_policy_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + iam_policy_pb2.TestIamPermissionsRequest, + dict, + ], +) +def test_test_iam_permissions_rest(request_type): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = iam_policy_pb2.TestIamPermissionsResponse( + permissions=["permissions_value"], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.test_iam_permissions(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, iam_policy_pb2.TestIamPermissionsResponse) + assert response.permissions == ["permissions_value"] + + +def test_test_iam_permissions_rest_required_fields( + request_type=iam_policy_pb2.TestIamPermissionsRequest, +): + transport_class = transports.ServicesRestTransport + + request_init = {} + request_init["resource"] = "" + request_init["permissions"] = "" + request = request_type(**request_init) + pb_request = request + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_iam_permissions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["resource"] = "resource_value" + jsonified_request["permissions"] = "permissions_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).test_iam_permissions._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "resource" in jsonified_request + assert jsonified_request["resource"] == "resource_value" + assert "permissions" in jsonified_request + assert jsonified_request["permissions"] == "permissions_value" + + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = iam_policy_pb2.TestIamPermissionsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.test_iam_permissions(request) + + expected_params = [] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_test_iam_permissions_rest_unset_required_fields(): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.test_iam_permissions._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "resource", + "permissions", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_test_iam_permissions_rest_interceptors(null_interceptor): + transport = transports.ServicesRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServicesRestInterceptor(), + ) + client = ServicesClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ServicesRestInterceptor, "post_test_iam_permissions" + ) as post, mock.patch.object( + transports.ServicesRestInterceptor, "pre_test_iam_permissions" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = iam_policy_pb2.TestIamPermissionsRequest() + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + iam_policy_pb2.TestIamPermissionsResponse() + ) + + request = iam_policy_pb2.TestIamPermissionsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = iam_policy_pb2.TestIamPermissionsResponse() + + client.test_iam_permissions( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_test_iam_permissions_rest_bad_request( + transport: str = "rest", request_type=iam_policy_pb2.TestIamPermissionsRequest +): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"resource": "projects/sample1/locations/sample2/services/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.test_iam_permissions(request) + + +def test_test_iam_permissions_rest_error(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServicesClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServicesClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = mock.Mock() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServicesClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServicesClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ServicesClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServicesGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ServicesGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServicesGrpcTransport, + transports.ServicesGrpcAsyncIOTransport, + transports.ServicesRestTransport, + ], +) +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() + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "rest", + ], +) +def test_transport_kind(transport_name): + transport = ServicesClient.get_transport_class(transport_name)( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert transport.kind == transport_name + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ServicesGrpcTransport, + ) + + +def test_services_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ServicesTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_services_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.run_v2.services.services.transports.ServicesTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ServicesTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_service", + "get_service", + "list_services", + "update_service", + "delete_service", + "get_iam_policy", + "set_iam_policy", + "test_iam_permissions", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServicesTransport( + 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_services_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.run_v2.services.services.transports.ServicesTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServicesTransport() + adc.assert_called_once() + + +def test_services_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) + ServicesClient() + 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.ServicesGrpcTransport, + transports.ServicesGrpcAsyncIOTransport, ], ) def test_services_transport_auth_adc(transport_class): @@ -2649,6 +5240,7 @@ def test_services_transport_auth_adc(transport_class): [ transports.ServicesGrpcTransport, transports.ServicesGrpcAsyncIOTransport, + transports.ServicesRestTransport, ], ) def test_services_transport_auth_gdch_credentials(transport_class): @@ -2743,11 +5335,40 @@ def test_services_grpc_transport_client_cert_source_for_mtls(transport_class): ) +def test_services_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ServicesRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +def test_services_rest_lro_client(): + client = ServicesClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + @pytest.mark.parametrize( "transport_name", [ "grpc", "grpc_asyncio", + "rest", ], ) def test_services_host_no_port(transport_name): @@ -2756,7 +5377,11 @@ def test_services_host_no_port(transport_name): client_options=client_options.ClientOptions(api_endpoint="run.googleapis.com"), transport=transport_name, ) - assert client.transport._host == ("run.googleapis.com:443") + assert client.transport._host == ( + "run.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com" + ) @pytest.mark.parametrize( @@ -2764,6 +5389,7 @@ def test_services_host_no_port(transport_name): [ "grpc", "grpc_asyncio", + "rest", ], ) def test_services_host_with_port(transport_name): @@ -2774,7 +5400,54 @@ def test_services_host_with_port(transport_name): ), transport=transport_name, ) - assert client.transport._host == ("run.googleapis.com:8000") + assert client.transport._host == ( + "run.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://run.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_services_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ServicesClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ServicesClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_service._session + session2 = client2.transport.create_service._session + assert session1 != session2 + session1 = client1.transport.get_service._session + session2 = client2.transport.get_service._session + assert session1 != session2 + session1 = client1.transport.list_services._session + session2 = client2.transport.list_services._session + assert session1 != session2 + session1 = client1.transport.update_service._session + session2 = client2.transport.update_service._session + assert session1 != session2 + session1 = client1.transport.delete_service._session + session2 = client2.transport.delete_service._session + assert session1 != session2 + session1 = client1.transport.get_iam_policy._session + session2 = client2.transport.get_iam_policy._session + assert session1 != session2 + session1 = client1.transport.set_iam_policy._session + session2 = client2.transport.set_iam_policy._session + assert session1 != session2 + session1 = client1.transport.test_iam_permissions._session + session2 = client2.transport.test_iam_permissions._session + assert session1 != session2 def test_services_grpc_transport_channel(): @@ -3230,6 +5903,7 @@ async def test_transport_close_async(): def test_transport_close(): transports = { + "rest": "_session", "grpc": "_grpc_channel", } @@ -3247,6 +5921,7 @@ def test_transport_close(): def test_client_ctx(): transports = [ + "rest", "grpc", ] for transport in transports: From af1163260a04c571c21b1dab0b019b97d135912f Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 20:56:55 -0400 Subject: [PATCH 3/9] chore: regenerate samples (#49) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add client library support for AssetService v1 SavedQuery APIs Committer: jeffreyai@ PiperOrigin-RevId: 475366952 Source-Link: https://github.com/googleapis/googleapis/commit/7428dad9f642a1b74fe4c4a23efe2d84234ac27f Source-Link: https://github.com/googleapis/googleapis-gen/commit/5629e2ab728443a1a6abb03f34f925d5cd4e0c47 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNTYyOWUyYWI3Mjg0NDNhMWE2YWJiMDNmMzRmOTI1ZDVjZDRlMGM0NyJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: update gapic-generator-python to 1.4.3 with test fixes PiperOrigin-RevId: 475399737 Source-Link: https://github.com/googleapis/googleapis/commit/4c4a9a261e29cbd6123e26bd701449a6dad2e695 Source-Link: https://github.com/googleapis/googleapis-gen/commit/72fdb5ae55a4d6583893a3e57b7ef264850d06cd Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNzJmZGI1YWU1NWE0ZDY1ODM4OTNhM2U1N2I3ZWYyNjQ4NTBkMDZjZCJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- .../snippet_metadata_run_v2.json | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index f9b04b1..c99ef69 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -213,7 +213,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -249,7 +249,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" }, { "canonical": true, @@ -374,7 +374,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -410,7 +410,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -454,7 +454,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" }, { "canonical": true, @@ -615,7 +615,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -651,7 +651,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, @@ -695,7 +695,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" }, { "canonical": true, @@ -872,7 +872,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_3c405c33.py", + "file": "run_v2_generated_services_create_service_sync_8031b824.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -908,7 +908,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_3c405c33.py" + "title": "run_v2_generated_services_create_service_sync_8031b824.py" }, { "canonical": true, @@ -960,7 +960,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_8031b824.py", + "file": "run_v2_generated_services_create_service_sync_3c405c33.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -996,7 +996,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_8031b824.py" + "title": "run_v2_generated_services_create_service_sync_3c405c33.py" }, { "canonical": true, @@ -1121,7 +1121,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", + "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1157,7 +1157,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" + "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" }, { "canonical": true, @@ -1201,7 +1201,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", + "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1237,7 +1237,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" + "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" }, { "canonical": true, @@ -1354,7 +1354,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", + "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1390,7 +1390,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" + "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" }, { "canonical": true, @@ -1430,7 +1430,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", + "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1466,7 +1466,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" + "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" }, { "canonical": true, @@ -1591,7 +1591,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", + "file": "run_v2_generated_services_get_service_sync_18284d02.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1627,7 +1627,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" + "title": "run_v2_generated_services_get_service_sync_18284d02.py" }, { "canonical": true, @@ -1671,7 +1671,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_18284d02.py", + "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1707,7 +1707,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_18284d02.py" + "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" }, { "canonical": true, @@ -1832,7 +1832,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_c5743712.py", + "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1868,7 +1868,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_c5743712.py" + "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" }, { "canonical": true, @@ -1912,7 +1912,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", + "file": "run_v2_generated_services_list_services_sync_c5743712.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1948,7 +1948,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" + "title": "run_v2_generated_services_list_services_sync_c5743712.py" }, { "canonical": true, @@ -2065,7 +2065,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", + "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2101,7 +2101,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" + "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" }, { "canonical": true, @@ -2141,7 +2141,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", + "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2177,7 +2177,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" + "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" }, { "canonical": true, @@ -2294,7 +2294,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2330,7 +2330,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" }, { "canonical": true, @@ -2370,7 +2370,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2406,7 +2406,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" }, { "canonical": true, @@ -2531,7 +2531,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_9076a854.py", + "file": "run_v2_generated_services_update_service_sync_2652a462.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2567,7 +2567,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_9076a854.py" + "title": "run_v2_generated_services_update_service_sync_2652a462.py" }, { "canonical": true, @@ -2611,7 +2611,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_2652a462.py", + "file": "run_v2_generated_services_update_service_sync_9076a854.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2647,7 +2647,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_2652a462.py" + "title": "run_v2_generated_services_update_service_sync_9076a854.py" } ] } From 457db0065bae1750a587551a64a99249e6b8694d Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 09:47:23 -0400 Subject: [PATCH 4/9] chore: regenerate samples (#50) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PiperOrigin-RevId: 475580307 Source-Link: https://github.com/googleapis/googleapis/commit/dbc83bd75946f2dbbca5fbb2be13d6afbc635b83 Source-Link: https://github.com/googleapis/googleapis-gen/commit/26c120594d6049d40061023cae345da80181077c Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjZjMTIwNTk0ZDYwNDlkNDAwNjEwMjNjYWUzNDVkYTgwMTgxMDc3YyJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- .../snippet_metadata_run_v2.json | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index c99ef69..3eb853c 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -872,7 +872,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_8031b824.py", + "file": "run_v2_generated_services_create_service_sync_3c405c33.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -908,7 +908,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_8031b824.py" + "title": "run_v2_generated_services_create_service_sync_3c405c33.py" }, { "canonical": true, @@ -960,7 +960,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_3c405c33.py", + "file": "run_v2_generated_services_create_service_sync_8031b824.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -996,7 +996,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_3c405c33.py" + "title": "run_v2_generated_services_create_service_sync_8031b824.py" }, { "canonical": true, @@ -1121,7 +1121,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", + "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1157,7 +1157,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" + "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" }, { "canonical": true, @@ -1201,7 +1201,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", + "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1237,7 +1237,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" + "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" }, { "canonical": true, @@ -1354,7 +1354,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", + "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1390,7 +1390,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" + "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" }, { "canonical": true, @@ -1430,7 +1430,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", + "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1466,7 +1466,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" + "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" }, { "canonical": true, @@ -1591,7 +1591,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_18284d02.py", + "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1627,7 +1627,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_18284d02.py" + "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" }, { "canonical": true, @@ -1671,7 +1671,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", + "file": "run_v2_generated_services_get_service_sync_18284d02.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1707,7 +1707,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" + "title": "run_v2_generated_services_get_service_sync_18284d02.py" }, { "canonical": true, @@ -1832,7 +1832,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", + "file": "run_v2_generated_services_list_services_sync_c5743712.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1868,7 +1868,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" + "title": "run_v2_generated_services_list_services_sync_c5743712.py" }, { "canonical": true, @@ -1912,7 +1912,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_c5743712.py", + "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1948,7 +1948,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_c5743712.py" + "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" }, { "canonical": true, @@ -2065,7 +2065,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", + "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2101,7 +2101,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" + "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" }, { "canonical": true, @@ -2141,7 +2141,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", + "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2177,7 +2177,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" + "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" }, { "canonical": true, @@ -2294,7 +2294,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2330,7 +2330,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" }, { "canonical": true, @@ -2370,7 +2370,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2406,7 +2406,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" }, { "canonical": true, @@ -2531,7 +2531,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_2652a462.py", + "file": "run_v2_generated_services_update_service_sync_9076a854.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2567,7 +2567,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_2652a462.py" + "title": "run_v2_generated_services_update_service_sync_9076a854.py" }, { "canonical": true, @@ -2611,7 +2611,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_9076a854.py", + "file": "run_v2_generated_services_update_service_sync_2652a462.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2647,7 +2647,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_9076a854.py" + "title": "run_v2_generated_services_update_service_sync_2652a462.py" } ] } From fb5749565f36075cb090d69046c598b156936123 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 26 Sep 2022 10:40:01 -0400 Subject: [PATCH 5/9] chore: regenerate samples (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: release SensitiveAction Cloud Logging payload to v1 PiperOrigin-RevId: 476083958 Source-Link: https://github.com/googleapis/googleapis/commit/fafd03f8da224663da0d83ee7c6ed1d84f3cb2e6 Source-Link: https://github.com/googleapis/googleapis-gen/commit/79c1b9ce243374735651e72cdebcbed99f5e4e65 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNzljMWI5Y2UyNDMzNzQ3MzU2NTFlNzJjZGViY2JlZDk5ZjVlNGU2NSJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- .../snippet_metadata_run_v2.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index 3eb853c..f9b04b1 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" }, { "canonical": true, @@ -213,7 +213,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -249,7 +249,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -374,7 +374,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -410,7 +410,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" }, { "canonical": true, @@ -454,7 +454,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -615,7 +615,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -651,7 +651,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" }, { "canonical": true, @@ -695,7 +695,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, From 11fd089dec1294094946c3b5f8625e7c6ca03fe5 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 10:57:37 -0400 Subject: [PATCH 6/9] chore: regenerate samples (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add an enum value for raw locations from Apple platforms PiperOrigin-RevId: 476961484 Source-Link: https://github.com/googleapis/googleapis/commit/695134be07e7f85a59eef40840fe693be51468e6 Source-Link: https://github.com/googleapis/googleapis-gen/commit/49457f9e7aae89cfe0491af4dbd9961a90125d32 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNDk0NTdmOWU3YWFlODljZmUwNDkxYWY0ZGJkOTk2MWE5MDEyNWQzMiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- .../snippet_metadata_run_v2.json | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index f9b04b1..c99ef69 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -213,7 +213,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -249,7 +249,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" }, { "canonical": true, @@ -374,7 +374,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -410,7 +410,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -454,7 +454,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" }, { "canonical": true, @@ -615,7 +615,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -651,7 +651,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, @@ -695,7 +695,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" }, { "canonical": true, @@ -872,7 +872,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_3c405c33.py", + "file": "run_v2_generated_services_create_service_sync_8031b824.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -908,7 +908,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_3c405c33.py" + "title": "run_v2_generated_services_create_service_sync_8031b824.py" }, { "canonical": true, @@ -960,7 +960,7 @@ "shortName": "create_service" }, "description": "Sample for CreateService", - "file": "run_v2_generated_services_create_service_sync_8031b824.py", + "file": "run_v2_generated_services_create_service_sync_3c405c33.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_CreateService_sync", @@ -996,7 +996,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_create_service_sync_8031b824.py" + "title": "run_v2_generated_services_create_service_sync_3c405c33.py" }, { "canonical": true, @@ -1121,7 +1121,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", + "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1157,7 +1157,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" + "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" }, { "canonical": true, @@ -1201,7 +1201,7 @@ "shortName": "delete_service" }, "description": "Sample for DeleteService", - "file": "run_v2_generated_services_delete_service_sync_9c99d0a2.py", + "file": "run_v2_generated_services_delete_service_sync_91d4ca21.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_DeleteService_sync", @@ -1237,7 +1237,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_delete_service_sync_9c99d0a2.py" + "title": "run_v2_generated_services_delete_service_sync_91d4ca21.py" }, { "canonical": true, @@ -1354,7 +1354,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", + "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1390,7 +1390,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" + "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" }, { "canonical": true, @@ -1430,7 +1430,7 @@ "shortName": "get_iam_policy" }, "description": "Sample for GetIamPolicy", - "file": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py", + "file": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetIamPolicy_sync", @@ -1466,7 +1466,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_iam_policy_sync_449f2eb3.py" + "title": "run_v2_generated_services_get_iam_policy_sync_9f45c2a7.py" }, { "canonical": true, @@ -1591,7 +1591,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", + "file": "run_v2_generated_services_get_service_sync_18284d02.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1627,7 +1627,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" + "title": "run_v2_generated_services_get_service_sync_18284d02.py" }, { "canonical": true, @@ -1671,7 +1671,7 @@ "shortName": "get_service" }, "description": "Sample for GetService", - "file": "run_v2_generated_services_get_service_sync_18284d02.py", + "file": "run_v2_generated_services_get_service_sync_1c3ef02e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_GetService_sync", @@ -1707,7 +1707,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_get_service_sync_18284d02.py" + "title": "run_v2_generated_services_get_service_sync_1c3ef02e.py" }, { "canonical": true, @@ -1832,7 +1832,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_c5743712.py", + "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1868,7 +1868,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_c5743712.py" + "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" }, { "canonical": true, @@ -1912,7 +1912,7 @@ "shortName": "list_services" }, "description": "Sample for ListServices", - "file": "run_v2_generated_services_list_services_sync_7dbaf490.py", + "file": "run_v2_generated_services_list_services_sync_c5743712.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_ListServices_sync", @@ -1948,7 +1948,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_list_services_sync_7dbaf490.py" + "title": "run_v2_generated_services_list_services_sync_c5743712.py" }, { "canonical": true, @@ -2065,7 +2065,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", + "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2101,7 +2101,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" + "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" }, { "canonical": true, @@ -2141,7 +2141,7 @@ "shortName": "set_iam_policy" }, "description": "Sample for SetIamPolicy", - "file": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py", + "file": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_SetIamPolicy_sync", @@ -2177,7 +2177,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_set_iam_policy_sync_b88666d6.py" + "title": "run_v2_generated_services_set_iam_policy_sync_c710ebbc.py" }, { "canonical": true, @@ -2294,7 +2294,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2330,7 +2330,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" }, { "canonical": true, @@ -2370,7 +2370,7 @@ "shortName": "test_iam_permissions" }, "description": "Sample for TestIamPermissions", - "file": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py", + "file": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_TestIamPermissions_sync", @@ -2406,7 +2406,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_test_iam_permissions_sync_7c7fb79b.py" + "title": "run_v2_generated_services_test_iam_permissions_sync_048b00bc.py" }, { "canonical": true, @@ -2531,7 +2531,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_9076a854.py", + "file": "run_v2_generated_services_update_service_sync_2652a462.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2567,7 +2567,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_9076a854.py" + "title": "run_v2_generated_services_update_service_sync_2652a462.py" }, { "canonical": true, @@ -2611,7 +2611,7 @@ "shortName": "update_service" }, "description": "Sample for UpdateService", - "file": "run_v2_generated_services_update_service_sync_2652a462.py", + "file": "run_v2_generated_services_update_service_sync_9076a854.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Services_UpdateService_sync", @@ -2647,7 +2647,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_services_update_service_sync_2652a462.py" + "title": "run_v2_generated_services_update_service_sync_9076a854.py" } ] } From 2a50dcdedba240350c764d3ea100bcf84123423d Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 29 Sep 2022 11:24:50 -0400 Subject: [PATCH 7/9] chore: regenerate samples (#56) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: put Locations mixin back PiperOrigin-RevId: 477369320 Source-Link: https://github.com/googleapis/googleapis/commit/6954c4da0f0ca8198157c9ad3507674e2ba608e7 Source-Link: https://github.com/googleapis/googleapis-gen/commit/81e5272671bd1c5c8ac15a44bd25922f0b93eae6 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODFlNTI3MjY3MWJkMWM1YzhhYzE1YTQ0YmQyNTkyMmYwYjkzZWFlNiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot --- .../snippet_metadata_run_v2.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/samples/generated_samples/snippet_metadata_run_v2.json b/samples/generated_samples/snippet_metadata_run_v2.json index c99ef69..635f790 100644 --- a/samples/generated_samples/snippet_metadata_run_v2.json +++ b/samples/generated_samples/snippet_metadata_run_v2.json @@ -133,7 +133,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", + "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -169,7 +169,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" + "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" }, { "canonical": true, @@ -213,7 +213,7 @@ "shortName": "delete_revision" }, "description": "Sample for DeleteRevision", - "file": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py", + "file": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_DeleteRevision_sync", @@ -249,7 +249,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_delete_revision_sync_2da46bc2.py" + "title": "run_v2_generated_revisions_delete_revision_sync_d74b55e0.py" }, { "canonical": true, @@ -374,7 +374,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", + "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -410,7 +410,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" + "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" }, { "canonical": true, @@ -454,7 +454,7 @@ "shortName": "get_revision" }, "description": "Sample for GetRevision", - "file": "run_v2_generated_revisions_get_revision_sync_115a25ad.py", + "file": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_GetRevision_sync", @@ -490,7 +490,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_get_revision_sync_115a25ad.py" + "title": "run_v2_generated_revisions_get_revision_sync_e5e5b0ac.py" }, { "canonical": true, @@ -615,7 +615,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", + "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -651,7 +651,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" + "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" }, { "canonical": true, @@ -695,7 +695,7 @@ "shortName": "list_revisions" }, "description": "Sample for ListRevisions", - "file": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py", + "file": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py", "language": "PYTHON", "origin": "API_DEFINITION", "regionTag": "run_v2_generated_Revisions_ListRevisions_sync", @@ -731,7 +731,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "run_v2_generated_revisions_list_revisions_sync_1d0f1802.py" + "title": "run_v2_generated_revisions_list_revisions_sync_2312de2e.py" }, { "canonical": true, From 7a85bac07e66efd965453fd0ecb093976edca2f2 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 11:25:13 -0400 Subject: [PATCH 8/9] fix(deps): require protobuf >= 3.20.2 (#55) * chore: exclude requirements.txt file from renovate-bot Source-Link: https://github.com/googleapis/synthtool/commit/f58d3135a2fab20e225d98741dbc06d57459b816 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:7a40313731a7cb1454eef6b33d3446ebb121836738dc3ab3d2d3ded5268c35b6 * update constraints files * fix(deps): require protobuf 3.20.2 Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- .github/.OwlBot.lock.yaml | 2 +- .kokoro/requirements.txt | 49 ++++++++++++++++++------------------- setup.py | 2 +- testing/constraints-3.7.txt | 2 +- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index b8dcb4a..3815c98 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,4 +13,4 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:993a058718e84a82fda04c3177e58f0a43281a996c7c395e0a56ccc4d6d210d7 + digest: sha256:7a40313731a7cb1454eef6b33d3446ebb121836738dc3ab3d2d3ded5268c35b6 diff --git a/.kokoro/requirements.txt b/.kokoro/requirements.txt index 385f2d4..d15994b 100644 --- a/.kokoro/requirements.txt +++ b/.kokoro/requirements.txt @@ -325,31 +325,30 @@ platformdirs==2.5.2 \ --hash=sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788 \ --hash=sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19 # via virtualenv -protobuf==3.20.1 \ - --hash=sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf \ - --hash=sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f \ - --hash=sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f \ - --hash=sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7 \ - --hash=sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996 \ - --hash=sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067 \ - --hash=sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c \ - --hash=sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7 \ - --hash=sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9 \ - --hash=sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c \ - --hash=sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739 \ - --hash=sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91 \ - --hash=sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c \ - --hash=sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153 \ - --hash=sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9 \ - --hash=sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388 \ - --hash=sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e \ - --hash=sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab \ - --hash=sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde \ - --hash=sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531 \ - --hash=sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8 \ - --hash=sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7 \ - --hash=sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20 \ - --hash=sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3 +protobuf==3.20.2 \ + --hash=sha256:03d76b7bd42ac4a6e109742a4edf81ffe26ffd87c5993126d894fe48a120396a \ + --hash=sha256:09e25909c4297d71d97612f04f41cea8fa8510096864f2835ad2f3b3df5a5559 \ + --hash=sha256:18e34a10ae10d458b027d7638a599c964b030c1739ebd035a1dfc0e22baa3bfe \ + --hash=sha256:291fb4307094bf5ccc29f424b42268640e00d5240bf0d9b86bf3079f7576474d \ + --hash=sha256:2c0b040d0b5d5d207936ca2d02f00f765906622c07d3fa19c23a16a8ca71873f \ + --hash=sha256:384164994727f274cc34b8abd41a9e7e0562801361ee77437099ff6dfedd024b \ + --hash=sha256:3cb608e5a0eb61b8e00fe641d9f0282cd0eedb603be372f91f163cbfbca0ded0 \ + --hash=sha256:5d9402bf27d11e37801d1743eada54372f986a372ec9679673bfcc5c60441151 \ + --hash=sha256:712dca319eee507a1e7df3591e639a2b112a2f4a62d40fe7832a16fd19151750 \ + --hash=sha256:7a5037af4e76c975b88c3becdf53922b5ffa3f2cddf657574a4920a3b33b80f3 \ + --hash=sha256:8228e56a865c27163d5d1d1771d94b98194aa6917bcfb6ce139cbfa8e3c27334 \ + --hash=sha256:84a1544252a933ef07bb0b5ef13afe7c36232a774affa673fc3636f7cee1db6c \ + --hash=sha256:84fe5953b18a383fd4495d375fe16e1e55e0a3afe7b4f7b4d01a3a0649fcda9d \ + --hash=sha256:9c673c8bfdf52f903081816b9e0e612186684f4eb4c17eeb729133022d6032e3 \ + --hash=sha256:9f876a69ca55aed879b43c295a328970306e8e80a263ec91cf6e9189243c613b \ + --hash=sha256:a9e5ae5a8e8985c67e8944c23035a0dff2c26b0f5070b2f55b217a1c33bbe8b1 \ + --hash=sha256:b4fdb29c5a7406e3f7ef176b2a7079baa68b5b854f364c21abe327bbeec01cdb \ + --hash=sha256:c184485e0dfba4dfd451c3bd348c2e685d6523543a0f91b9fd4ae90eb09e8422 \ + --hash=sha256:c9cdf251c582c16fd6a9f5e95836c90828d51b0069ad22f463761d27c6c19019 \ + --hash=sha256:e39cf61bb8582bda88cdfebc0db163b774e7e03364bbf9ce1ead13863e81e359 \ + --hash=sha256:e8fbc522303e09036c752a0afcc5c0603e917222d8bedc02813fd73b4b4ed804 \ + --hash=sha256:f34464ab1207114e73bba0794d1257c150a2b89b7a9faf504e00af7c9fd58978 \ + --hash=sha256:f52dabc96ca99ebd2169dadbe018824ebda08a795c7684a0b7d203a290f3adb0 # via # gcp-docuploader # gcp-releasetool diff --git a/setup.py b/setup.py index 3368810..4b0aa4b 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ dependencies = [ "google-api-core[grpc] >= 1.33.0, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*", "proto-plus >= 1.22.0, <2.0.0dev", - "protobuf >= 3.20.1, <5.0.0dev", + "protobuf >= 3.20.2, <5.0.0dev", "grpc-google-iam-v1 >= 0.12.4, <1.0.0dev", ] diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt index 14eab6a..70f3b1e 100644 --- a/testing/constraints-3.7.txt +++ b/testing/constraints-3.7.txt @@ -7,4 +7,4 @@ google-api-core==1.33.0 proto-plus==1.22.0 grpc-google-iam-v1==0.12.4 -protobuf==3.20.1 +protobuf==3.20.2 From 891c836649d24764c0c59b9478c951c04ddeee9a Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 20:16:37 -0400 Subject: [PATCH 9/9] chore(main): release 0.4.1 (#57) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb827b4..87408a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.4.1](https://github.com/googleapis/python-run/compare/v0.4.0...v0.4.1) (2022-10-03) + + +### Bug Fixes + +* **deps:** Require protobuf >= 3.20.2 ([#55](https://github.com/googleapis/python-run/issues/55)) ([7a85bac](https://github.com/googleapis/python-run/commit/7a85bac07e66efd965453fd0ecb093976edca2f2)) + ## [0.4.0](https://github.com/googleapis/python-run/compare/v0.3.0...v0.4.0) (2022-09-13) diff --git a/setup.py b/setup.py index 4b0aa4b..da458b2 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ name = "google-cloud-run" description = "Cloud Run API client library" -version = "0.4.0" +version = "0.4.1" release_status = "Development Status :: 4 - Beta" url = "https://github.com/googleapis/python-run" dependencies = [