From f6287f92225645545449fd918a33bc299e7907b0 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Mon, 24 Mar 2025 14:26:21 +0000 Subject: [PATCH 01/30] feat: adds augmented pagination to account for BQ family of APIs --- gapic/schema/wrappers.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 3982afea6c..a84047502b 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1836,7 +1836,8 @@ def paged_result_field(self) -> Optional[Field]: # If the request field lacks any of the expected pagination fields, # then the method is not paginated. - # The request must have page_token and next_page_token as they keep track of pages + # The request must have page_token and response must have next_page_token fields + # because those fields keep track of pagination progress. for source, source_type, name in ( (self.input, str, "page_token"), (self.output, str, "next_page_token"), @@ -1851,7 +1852,24 @@ def paged_result_field(self) -> Optional[Field]: self.input.fields.get("page_size", None), ) page_field_size = next((field for field in page_fields if field), None) - if not page_field_size or page_field_size.type != int: + if not page_field_size: + return None + + # The datatype for page_size/max_results must be one of the following: + # int (page_size) or UInt32Value, Int32Value (max_results) + if page_field_size.type == int or ( + # The following additional checks are for several members of the BQ family of + # APIs, which use legacy wrapper types: "UInt32Value" and "Int32Value"} + # for max_results. + # NOTE: + # bigquery_v2 should be paginated + # but bigquery_connection_v1beta1 should NOT be paginated + isinstance(page_field_size.type, MessageType) + and page_field_size.type.message_pb.name in {"UInt32Value", "Int32Value"} + and self.input.message_pb.name not in {"ListConnectionsRequest"} + ): + pass + else: return None # Return the first repeated field. From 6979a63a2e286911c0ae1f7d3b7cd7c1d88c99c3 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Mon, 24 Mar 2025 19:48:08 +0000 Subject: [PATCH 02/30] updates with several options for an allowlist --- gapic/schema/wrappers.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index a84047502b..6eda22e200 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1478,6 +1478,10 @@ def sample_request(self): req[self.body] = {} # just an empty json. return req +ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE = { + 'google.cloud.bigquery.v2': True, + 'google.cloud.bigquery.connection.v1beta1': False, +} @dataclasses.dataclass(frozen=True) class Method: @@ -1838,6 +1842,7 @@ def paged_result_field(self) -> Optional[Field]: # The request must have page_token and response must have next_page_token fields # because those fields keep track of pagination progress. + for source, source_type, name in ( (self.input, str, "page_token"), (self.output, str, "next_page_token"), @@ -1855,18 +1860,26 @@ def paged_result_field(self) -> Optional[Field]: if not page_field_size: return None - # The datatype for page_size/max_results must be one of the following: - # int (page_size) or UInt32Value, Int32Value (max_results) + # If the field is max_results and uses the UInt32Value and Int32Value wrappers, + # the package must be in the allowlist. + wrappers_allowed = ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE.get(self.input.meta.address.proto_package, False) + + # ALTERNATIVE: + # As opposed to using a dictionary with package names as keys and True/False as values, we could + # Use a set and check to see if the package name is in the list + # WRAPPERS_ALLOWED_PACKAGE_LIST = {"google.cloud.bigquery.v2"} + # self.input.meta.address.proto_package in WRAPPERS_ALLOWED_PACKAGE_LIST + if page_field_size.type == int or ( # The following additional checks are for several members of the BQ family of # APIs, which use legacy wrapper types: "UInt32Value" and "Int32Value"} # for max_results. # NOTE: # bigquery_v2 should be paginated - # but bigquery_connection_v1beta1 should NOT be paginated - isinstance(page_field_size.type, MessageType) + # but bigquery_connection_v1beta1 should NOT be paginated + wrappers_allowed + and isinstance(page_field_size.type, MessageType) and page_field_size.type.message_pb.name in {"UInt32Value", "Int32Value"} - and self.input.message_pb.name not in {"ListConnectionsRequest"} ): pass else: From 18523c426c2340e56ab7b116bfbf54feb8007a84 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 25 Mar 2025 11:10:42 +0000 Subject: [PATCH 03/30] updates comments, syntax formatting, linting --- gapic/schema/wrappers.py | 45 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 6eda22e200..c6b1fb6ec7 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1478,11 +1478,13 @@ def sample_request(self): req[self.body] = {} # just an empty json. return req + ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE = { - 'google.cloud.bigquery.v2': True, - 'google.cloud.bigquery.connection.v1beta1': False, + "google.cloud.bigquery.v2": True, + "google.cloud.bigquery.connection.v1beta1": False, } + @dataclasses.dataclass(frozen=True) class Method: """Description of a method (defined with the ``rpc`` keyword).""" @@ -1499,6 +1501,8 @@ class Method: default_factory=metadata.Metadata, ) + PACKAGES_WITH_ALLOWED_WRAPPERS = {"google.cloud.bigquery.v2"} + def __getattr__(self, name): return getattr(self.method_pb, name) @@ -1836,13 +1840,16 @@ def ident(self) -> metadata.Address: @utils.cached_property def paged_result_field(self) -> Optional[Field]: - """Return the response pagination field if the method is paginated.""" - # If the request field lacks any of the expected pagination fields, - # then the method is not paginated. + """Return the response pagination field if the method is paginated. + + The request field must have a page_token field and a page_size field (or + for legacy APIs, a max_results field) and the response field + must have a next_token_field and a repeated field. + + For the purposes of supporting legacy APIs, additional wrapper types are + allowed. + """ - # The request must have page_token and response must have next_page_token fields - # because those fields keep track of pagination progress. - for source, source_type, name in ( (self.input, str, "page_token"), (self.output, str, "next_page_token"), @@ -1851,7 +1858,7 @@ def paged_result_field(self) -> Optional[Field]: if not field or field.type != source_type: return None - # The request must have max_results or page_size + # The request must have page_size (or max_results if legacy API) page_fields = ( self.input.fields.get("max_results", None), self.input.fields.get("page_size", None), @@ -1859,27 +1866,21 @@ def paged_result_field(self) -> Optional[Field]: page_field_size = next((field for field in page_fields if field), None) if not page_field_size: return None - + # If the field is max_results and uses the UInt32Value and Int32Value wrappers, # the package must be in the allowlist. - wrappers_allowed = ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE.get(self.input.meta.address.proto_package, False) - - # ALTERNATIVE: - # As opposed to using a dictionary with package names as keys and True/False as values, we could - # Use a set and check to see if the package name is in the list - # WRAPPERS_ALLOWED_PACKAGE_LIST = {"google.cloud.bigquery.v2"} - # self.input.meta.address.proto_package in WRAPPERS_ALLOWED_PACKAGE_LIST + package_name = self.input.meta.address.proto_package if page_field_size.type == int or ( - # The following additional checks are for several members of the BQ family of - # APIs, which use legacy wrapper types: "UInt32Value" and "Int32Value"} + # The following additional checks are related to several members of the BQ family of + # APIs, which use the legacy wrapper types: "UInt32Value" and "Int32Value"} # for max_results. # NOTE: # bigquery_v2 should be paginated - # but bigquery_connection_v1beta1 should NOT be paginated - wrappers_allowed - and isinstance(page_field_size.type, MessageType) + # but bigquery_connection_v1beta1 should NOT be paginated + isinstance(page_field_size.type, MessageType) and page_field_size.type.message_pb.name in {"UInt32Value", "Int32Value"} + and package_name in self.PACKAGES_WITH_ALLOWED_WRAPPERS ): pass else: From 2caa968e87cd27c8fe3cac88e40a742572e4beb0 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 25 Mar 2025 11:15:08 +0000 Subject: [PATCH 04/30] updates comments, removes unused variable --- gapic/schema/wrappers.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index c6b1fb6ec7..fd5f5ca839 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1479,12 +1479,6 @@ def sample_request(self): return req -ENABLE_WRAPPER_TYPES_FOR_PAGE_SIZE = { - "google.cloud.bigquery.v2": True, - "google.cloud.bigquery.connection.v1beta1": False, -} - - @dataclasses.dataclass(frozen=True) class Method: """Description of a method (defined with the ``rpc`` keyword).""" @@ -1867,8 +1861,8 @@ def paged_result_field(self) -> Optional[Field]: if not page_field_size: return None - # If the field is max_results and uses the UInt32Value and Int32Value wrappers, - # the package must be in the allowlist. + # If the a legacy API uses the UInt32Value and Int32Value wrappers, + # the service package must be in the allowlist. package_name = self.input.meta.address.proto_package if page_field_size.type == int or ( From 34b6490bc7588674bc16629c5ef3cee4431b869a Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 10:37:01 +0000 Subject: [PATCH 05/30] Updates with validate function --- gapic/schema/wrappers.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index fd5f5ca839..384fae1ed4 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1495,8 +1495,6 @@ class Method: default_factory=metadata.Metadata, ) - PACKAGES_WITH_ALLOWED_WRAPPERS = {"google.cloud.bigquery.v2"} - def __getattr__(self, name): return getattr(self.method_pb, name) @@ -1832,6 +1830,21 @@ def ident(self) -> metadata.Address: """Return the identifier data to be used in templates.""" return self.meta.address + def _validate_paged_field_size_type(value): + """Validates allowed paged_field_size type(s). + + Confirms whether the paged_field_size.type is an allowed wrapper type: + The norm is for type to be int, but an additional check is included to + account for BigQuery legacy APIs which allowed UInt32Value and + Int32Value. + """ + + if page_field_size.type == int or ( + isinstance(value.type, MessageType) + and value.type.message_pb.name in {"UInt32Value", "Int32Value"} + ): + return True + @utils.cached_property def paged_result_field(self) -> Optional[Field]: """Return the response pagination field if the method is paginated. @@ -1861,23 +1874,8 @@ def paged_result_field(self) -> Optional[Field]: if not page_field_size: return None - # If the a legacy API uses the UInt32Value and Int32Value wrappers, - # the service package must be in the allowlist. - package_name = self.input.meta.address.proto_package - - if page_field_size.type == int or ( - # The following additional checks are related to several members of the BQ family of - # APIs, which use the legacy wrapper types: "UInt32Value" and "Int32Value"} - # for max_results. - # NOTE: - # bigquery_v2 should be paginated - # but bigquery_connection_v1beta1 should NOT be paginated - isinstance(page_field_size.type, MessageType) - and page_field_size.type.message_pb.name in {"UInt32Value", "Int32Value"} - and package_name in self.PACKAGES_WITH_ALLOWED_WRAPPERS - ): - pass - else: + # Confirm whether the paged_field_size is an allowed type. + if not _validate_paged_field_size_type(value): return None # Return the first repeated field. From 00db7cee5223e11cfbf5ed69d482512dafa8940d Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 12:05:47 +0000 Subject: [PATCH 06/30] updates paged_result_field with a validation function --- gapic/schema/wrappers.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 384fae1ed4..dfdcc76ce4 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1830,7 +1830,7 @@ def ident(self) -> metadata.Address: """Return the identifier data to be used in templates.""" return self.meta.address - def _validate_paged_field_size_type(value): + def _validate_paged_field_size_type(page_field_size): """Validates allowed paged_field_size type(s). Confirms whether the paged_field_size.type is an allowed wrapper type: @@ -1839,9 +1839,11 @@ def _validate_paged_field_size_type(value): Int32Value. """ - if page_field_size.type == int or ( - isinstance(value.type, MessageType) - and value.type.message_pb.name in {"UInt32Value", "Int32Value"} + _type = page_field_size.type + + if _type == int or ( + isinstance(_type, MessageType) + and _type.message_pb.name in {"UInt32Value", "Int32Value"} ): return True @@ -1871,11 +1873,12 @@ def paged_result_field(self) -> Optional[Field]: self.input.fields.get("page_size", None), ) page_field_size = next((field for field in page_fields if field), None) + if not page_field_size: return None # Confirm whether the paged_field_size is an allowed type. - if not _validate_paged_field_size_type(value): + if not self._validate_paged_field_size_type(page_field_size=page_field_size): return None # Return the first repeated field. From 3bd99de04bea9bae944075eb6c0d857d21ed576d Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 14:02:48 +0000 Subject: [PATCH 07/30] updates validation function with self arg --- gapic/schema/wrappers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index dfdcc76ce4..938f01afc1 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1830,7 +1830,7 @@ def ident(self) -> metadata.Address: """Return the identifier data to be used in templates.""" return self.meta.address - def _validate_paged_field_size_type(page_field_size): + def _validate_paged_field_size_type(self, page_field_size): """Validates allowed paged_field_size type(s). Confirms whether the paged_field_size.type is an allowed wrapper type: From 5227acc12a4f6613a96f2b52c90825435073c78d Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 18:22:14 +0000 Subject: [PATCH 08/30] updates unittests with test__validate_paged_field_size_type --- tests/unit/schema/wrappers/test_method.py | 70 +++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index bd46506e92..929553db65 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -23,6 +23,7 @@ from google.api import routing_pb2 from google.cloud import extended_operations_pb2 as ex_ops_pb2 from google.protobuf import descriptor_pb2 +from google.protobuf import wrappers_pb2 from gapic.schema import metadata from gapic.schema import wrappers @@ -999,3 +1000,72 @@ def test_mixin_rule(): "city": {}, } assert e == m.sample_request + + +# @pytest.mark.parametrize( +# "page_field_size", +# [ +# (True), +# (False), +# ] +# ) + + + +@pytest.mark.parametrize( + "field_type, _type, expected", + [ + (int, 5, True), # int, 5 = int + (float, 1, None), # float, 1 = float + (wrappers_pb2.UInt32Value, 11, True), # wrappers_pb2.UInt32Value, 11 = MessageType + (wrappers_pb2.Int32Value, 11, True), # wrappers_pb2.UInt32Value, 11 = MessageType + (wrappers_pb2.Int32Value, 1, None), # wrappers_pb2.UInt32Value, 1 = float + (wrappers_pb2.Int32Value, 1, None), # wrappers_pb2.UInt32Value, 1 = float + ], +) +def test__validate_paged_field_size_type(field_type, _type, expected): + """Test _validate_paged_field_size_type with wrapper types and type indicators.""" + + # Setup + if _type == 11: + # _type 11 is MESSAGETYPE + # See: https://github.com/googleapis/gapic-generator-python/blob/c8b7229ba2865d6a2f5966aa151be121de81f92d/gapic/schema/wrappers.py#L378C1-L411C10 + # and is only associated with *Int32Value in legacy APIs such as BigQuery. + page_size = make_field( + name="max_results", + type=_type, + message=make_message(name=field_type.DESCRIPTOR.name) + ) + else: + # The other _type values represent int (5) and float (1) + page_size = make_field(name="page_size", type=_type) + + parent = make_field(name="parent", type=9) # str + page_token = make_field(name="page_token", type=9) # str + next_page_token = make_field(name="next_page_token", type=9) # str + + input_msg = make_message( + name="ListFoosRequest", + fields=( + parent, + page_size, + page_token, + ), + ) + + output_msg = make_message( + name="ListFoosResponse", + fields=( + make_field(name="foos", message=make_message("Foo"), repeated=True), + next_page_token, + ), + ) + + method = make_method( + "ListFoos", + input_message=input_msg, + output_message=output_msg, + ) + + actual = method._validate_paged_field_size_type(page_field_size=page_size) + assert actual == expected From 1c4265adecd8197d63c4f4ac4fd6d189a63bc986 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 18:24:47 +0000 Subject: [PATCH 09/30] updates parametrizations for test__validate_paged_field_size_type --- tests/unit/schema/wrappers/test_method.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index 929553db65..dff186b86e 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -1015,12 +1015,12 @@ def test_mixin_rule(): @pytest.mark.parametrize( "field_type, _type, expected", [ - (int, 5, True), # int, 5 = int - (float, 1, None), # float, 1 = float - (wrappers_pb2.UInt32Value, 11, True), # wrappers_pb2.UInt32Value, 11 = MessageType - (wrappers_pb2.Int32Value, 11, True), # wrappers_pb2.UInt32Value, 11 = MessageType - (wrappers_pb2.Int32Value, 1, None), # wrappers_pb2.UInt32Value, 1 = float - (wrappers_pb2.Int32Value, 1, None), # wrappers_pb2.UInt32Value, 1 = float + (int, 5, True), # 5 = int + (float, 1, None), # 1 = float + (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType + (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType + (wrappers_pb2.UInt32Value, 1, None), # 1 = float + (wrappers_pb2.Int32Value, 1, None), # 1 = float ], ) def test__validate_paged_field_size_type(field_type, _type, expected): From e334e8e74723ed8f9b548331143413f11a8a25dc Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 26 Mar 2025 18:29:28 +0000 Subject: [PATCH 10/30] updates order and comments for test__validate_paged_field_size_type --- tests/unit/schema/wrappers/test_method.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index dff186b86e..a07e55c7ea 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -1015,10 +1015,12 @@ def test_mixin_rule(): @pytest.mark.parametrize( "field_type, _type, expected", [ + # valid paged_result_field candidate (int, 5, True), # 5 = int - (float, 1, None), # 1 = float (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType + # invalid paged_result_field candidate + (float, 1, None), # 1 = float (wrappers_pb2.UInt32Value, 1, None), # 1 = float (wrappers_pb2.Int32Value, 1, None), # 1 = float ], @@ -1027,7 +1029,10 @@ def test__validate_paged_field_size_type(field_type, _type, expected): """Test _validate_paged_field_size_type with wrapper types and type indicators.""" # Setup - if _type == 11: + if _type in {5, 1}: + # The _type values represent int (5) and float (1) + page_size = make_field(name="page_size", type=_type) + else: # _type 11 is MESSAGETYPE # See: https://github.com/googleapis/gapic-generator-python/blob/c8b7229ba2865d6a2f5966aa151be121de81f92d/gapic/schema/wrappers.py#L378C1-L411C10 # and is only associated with *Int32Value in legacy APIs such as BigQuery. @@ -1036,9 +1041,6 @@ def test__validate_paged_field_size_type(field_type, _type, expected): type=_type, message=make_message(name=field_type.DESCRIPTOR.name) ) - else: - # The other _type values represent int (5) and float (1) - page_size = make_field(name="page_size", type=_type) parent = make_field(name="parent", type=9) # str page_token = make_field(name="page_token", type=9) # str From 6ce132e800f7c44e2a298888f0c1d86c0ac094d6 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 27 Mar 2025 09:28:39 +0000 Subject: [PATCH 11/30] cleans up comments --- tests/unit/schema/wrappers/test_method.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index a07e55c7ea..de8f1e8eff 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -1002,24 +1002,14 @@ def test_mixin_rule(): assert e == m.sample_request -# @pytest.mark.parametrize( -# "page_field_size", -# [ -# (True), -# (False), -# ] -# ) - - - @pytest.mark.parametrize( "field_type, _type, expected", [ - # valid paged_result_field candidate + # valid paged_result_field candidates (int, 5, True), # 5 = int (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType - # invalid paged_result_field candidate + # invalid paged_result_field candidates (float, 1, None), # 1 = float (wrappers_pb2.UInt32Value, 1, None), # 1 = float (wrappers_pb2.Int32Value, 1, None), # 1 = float @@ -1035,7 +1025,8 @@ def test__validate_paged_field_size_type(field_type, _type, expected): else: # _type 11 is MESSAGETYPE # See: https://github.com/googleapis/gapic-generator-python/blob/c8b7229ba2865d6a2f5966aa151be121de81f92d/gapic/schema/wrappers.py#L378C1-L411C10 - # and is only associated with *Int32Value in legacy APIs such as BigQuery. + # and in this context is associated with *Int32Value in legacy APIs + # such as BigQuery. page_size = make_field( name="max_results", type=_type, From 8895d648c35f44a6e26088795df600997ccb465d Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 27 Mar 2025 10:03:42 +0000 Subject: [PATCH 12/30] adds test to improve code coverage --- tests/unit/schema/wrappers/test_method.py | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index de8f1e8eff..fbf86490cb 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -190,6 +190,61 @@ def test_method_paged_result_field_no_page_field(): assert method.paged_result_field is None +def test_method_paged_result_field_invalid_wrapper_type(): + """Validate paged_result_field() returns None if page_size/max_results wrappertypes + are not allowed types. + """ + + # page_size is not allowed wrappertype + parent = make_field(name="parent", type=9) # str + page_size = make_field(name="page_size", type=1) # float, not allowed type + page_token = make_field(name="page_token", type=9) # str + foos = make_field(name="foos", message=make_message("Foo"), repeated=True) + next_page_token = make_field(name="next_page_token", type=9) # str + + input_msg = make_message( + name="ListFoosRequest", + fields=( + parent, + page_size, + page_token, + ), + ) + output_msg = make_message( + name="ListFoosResponse", + fields=( + foos, + next_page_token, + ), + ) + method = make_method( + "ListFoos", + input_message=input_msg, + output_message=output_msg, + ) + assert method.paged_result_field is None + + # max_results is not allowed wrappertype + max_results = make_field(name="max_results", type=9) # str, not allowed type + + input_msg = make_message( + name="ListFoosRequest", + fields=( + parent, + max_results, + page_token, + ), + ) + + method = make_method( + "ListFoos", + input_message=input_msg, + output_message=output_msg, + ) + + assert method.paged_result_field is None + + def test_method_paged_result_ref_types(): input_msg = make_message( name="ListSquidsRequest", From a8a3ead16d0d339547b17ec037b93dd16c974ee9 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 27 Mar 2025 12:14:21 +0000 Subject: [PATCH 13/30] updates linting --- tests/unit/schema/wrappers/test_method.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index fbf86490cb..0dd0a0c22e 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -1061,13 +1061,13 @@ def test_mixin_rule(): "field_type, _type, expected", [ # valid paged_result_field candidates - (int, 5, True), # 5 = int - (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType - (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType + (int, 5, True), # 5 = int + (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType + (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType # invalid paged_result_field candidates - (float, 1, None), # 1 = float - (wrappers_pb2.UInt32Value, 1, None), # 1 = float - (wrappers_pb2.Int32Value, 1, None), # 1 = float + (float, 1, None), # 1 = float + (wrappers_pb2.UInt32Value, 1, None), # 1 = float + (wrappers_pb2.Int32Value, 1, None), # 1 = float ], ) def test__validate_paged_field_size_type(field_type, _type, expected): @@ -1075,9 +1075,9 @@ def test__validate_paged_field_size_type(field_type, _type, expected): # Setup if _type in {5, 1}: - # The _type values represent int (5) and float (1) + # The _type values represent int (5) and float (1) page_size = make_field(name="page_size", type=_type) - else: + else: # _type 11 is MESSAGETYPE # See: https://github.com/googleapis/gapic-generator-python/blob/c8b7229ba2865d6a2f5966aa151be121de81f92d/gapic/schema/wrappers.py#L378C1-L411C10 # and in this context is associated with *Int32Value in legacy APIs @@ -1085,7 +1085,7 @@ def test__validate_paged_field_size_type(field_type, _type, expected): page_size = make_field( name="max_results", type=_type, - message=make_message(name=field_type.DESCRIPTOR.name) + message=make_message(name=field_type.DESCRIPTOR.name), ) parent = make_field(name="parent", type=9) # str @@ -1100,7 +1100,7 @@ def test__validate_paged_field_size_type(field_type, _type, expected): page_token, ), ) - + output_msg = make_message( name="ListFoosResponse", fields=( From bdfe40fa3621fc834f324f5b52a99707eb2dc343 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 28 Mar 2025 11:27:47 +0000 Subject: [PATCH 14/30] renames _type, add pb_type names, removes now superfluous comments --- gapic/schema/wrappers.py | 10 ++--- tests/unit/schema/wrappers/test_method.py | 46 +++++++++++------------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index 938f01afc1..ef72913bf4 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1830,7 +1830,7 @@ def ident(self) -> metadata.Address: """Return the identifier data to be used in templates.""" return self.meta.address - def _validate_paged_field_size_type(self, page_field_size): + def _validate_paged_field_size_type(self, page_field_size) -> bool: """Validates allowed paged_field_size type(s). Confirms whether the paged_field_size.type is an allowed wrapper type: @@ -1839,11 +1839,11 @@ def _validate_paged_field_size_type(self, page_field_size): Int32Value. """ - _type = page_field_size.type + pb_type = page_field_size.type - if _type == int or ( - isinstance(_type, MessageType) - and _type.message_pb.name in {"UInt32Value", "Int32Value"} + if pb_type == int or ( + isinstance(pb_type, MessageType) + and pb_type.message_pb.name in {"UInt32Value", "Int32Value"} ): return True diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index 0dd0a0c22e..619640524c 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -196,11 +196,11 @@ def test_method_paged_result_field_invalid_wrapper_type(): """ # page_size is not allowed wrappertype - parent = make_field(name="parent", type=9) # str - page_size = make_field(name="page_size", type=1) # float, not allowed type - page_token = make_field(name="page_token", type=9) # str + parent = make_field(name="parent", type="TYPE_STRING") + page_size = make_field(name="page_size", type="TYPE_DOUBLE") # not an allowed type + page_token = make_field(name="page_token", type="TYPE_STRING") foos = make_field(name="foos", message=make_message("Foo"), repeated=True) - next_page_token = make_field(name="next_page_token", type=9) # str + next_page_token = make_field(name="next_page_token", type="TYPE_STRING") input_msg = make_message( name="ListFoosRequest", @@ -225,7 +225,9 @@ def test_method_paged_result_field_invalid_wrapper_type(): assert method.paged_result_field is None # max_results is not allowed wrappertype - max_results = make_field(name="max_results", type=9) # str, not allowed type + max_results = make_field( + name="max_results", type="TYPE_STRING" + ) # not an allowed type input_msg = make_message( name="ListFoosRequest", @@ -1058,39 +1060,37 @@ def test_mixin_rule(): @pytest.mark.parametrize( - "field_type, _type, expected", + "field_type, pb_type, expected", [ # valid paged_result_field candidates - (int, 5, True), # 5 = int - (wrappers_pb2.UInt32Value, 11, True), # 11 = MessageType - (wrappers_pb2.Int32Value, 11, True), # 11 = MessageType + (int, "TYPE_INT32", True), + (wrappers_pb2.UInt32Value, "TYPE_MESSAGE", True), + (wrappers_pb2.Int32Value, "TYPE_MESSAGE", True), # invalid paged_result_field candidates - (float, 1, None), # 1 = float - (wrappers_pb2.UInt32Value, 1, None), # 1 = float - (wrappers_pb2.Int32Value, 1, None), # 1 = float + (float, "TYPE_DOUBLE", None), + (wrappers_pb2.UInt32Value, "TYPE_DOUBLE", None), + (wrappers_pb2.Int32Value, "TYPE_DOUBLE", None), ], ) -def test__validate_paged_field_size_type(field_type, _type, expected): +def test__validate_paged_field_size_type(field_type, pb_type, expected): """Test _validate_paged_field_size_type with wrapper types and type indicators.""" # Setup - if _type in {5, 1}: - # The _type values represent int (5) and float (1) - page_size = make_field(name="page_size", type=_type) + if pb_type in {"TYPE_INT32", "TYPE_DOUBLE"}: + page_size = make_field(name="page_size", type=pb_type) else: - # _type 11 is MESSAGETYPE + # expecting TYPE_MESSAGE which in this context is associated with + # *Int32Value in legacy APIs such as BigQuery. # See: https://github.com/googleapis/gapic-generator-python/blob/c8b7229ba2865d6a2f5966aa151be121de81f92d/gapic/schema/wrappers.py#L378C1-L411C10 - # and in this context is associated with *Int32Value in legacy APIs - # such as BigQuery. page_size = make_field( name="max_results", - type=_type, + type=pb_type, message=make_message(name=field_type.DESCRIPTOR.name), ) - parent = make_field(name="parent", type=9) # str - page_token = make_field(name="page_token", type=9) # str - next_page_token = make_field(name="next_page_token", type=9) # str + parent = make_field(name="parent", type="TYPE_STRING") + page_token = make_field(name="page_token", type="TYPE_STRING") + next_page_token = make_field(name="next_page_token", type="TYPE_STRING") input_msg = make_message( name="ListFoosRequest", From ddbe96ac3fe1e6e0e3731e9f2ec76dac3399eef5 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 28 Mar 2025 11:37:02 +0000 Subject: [PATCH 15/30] updates return statement to resolve mypy error --- gapic/schema/wrappers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index ef72913bf4..ab02a011ca 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1846,6 +1846,7 @@ def _validate_paged_field_size_type(self, page_field_size) -> bool: and pb_type.message_pb.name in {"UInt32Value", "Int32Value"} ): return True + return False @utils.cached_property def paged_result_field(self) -> Optional[Field]: From 921e62bb2df08091c60829ad87297d5a23e33bc9 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 28 Mar 2025 12:15:19 +0000 Subject: [PATCH 16/30] updates expected value in test parameters --- tests/unit/schema/wrappers/test_method.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/schema/wrappers/test_method.py b/tests/unit/schema/wrappers/test_method.py index 619640524c..088958e06b 100644 --- a/tests/unit/schema/wrappers/test_method.py +++ b/tests/unit/schema/wrappers/test_method.py @@ -1067,9 +1067,9 @@ def test_mixin_rule(): (wrappers_pb2.UInt32Value, "TYPE_MESSAGE", True), (wrappers_pb2.Int32Value, "TYPE_MESSAGE", True), # invalid paged_result_field candidates - (float, "TYPE_DOUBLE", None), - (wrappers_pb2.UInt32Value, "TYPE_DOUBLE", None), - (wrappers_pb2.Int32Value, "TYPE_DOUBLE", None), + (float, "TYPE_DOUBLE", False), + (wrappers_pb2.UInt32Value, "TYPE_DOUBLE", False), + (wrappers_pb2.Int32Value, "TYPE_DOUBLE", False), ], ) def test__validate_paged_field_size_type(field_type, pb_type, expected): From 7e70e8dad9776914df147e7ee2ed10c9b9b13d14 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 28 Mar 2025 17:28:25 +0000 Subject: [PATCH 17/30] adds proof-of-concept fragment test --- ...t_pagination_max_results_and_wrapper.proto | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/fragments/test_pagination_max_results_and_wrapper.proto diff --git a/tests/fragments/test_pagination_max_results_and_wrapper.proto b/tests/fragments/test_pagination_max_results_and_wrapper.proto new file mode 100644 index 0000000000..b1a69087fe --- /dev/null +++ b/tests/fragments/test_pagination_max_results_and_wrapper.proto @@ -0,0 +1,86 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/protobuf/wrappers.proto"; + +service MyDatasetService { + option (google.api.default_host) = "my.example.com"; + rpc ListMyDataset(ListDatasetRequest) returns (ListDatasetResponse) { + } +} + +message ListDatasetRequest { + google.protobuf.UInt32Value max_results = 2; + string page_token = 3; +} + +message ListDatasetResponse { + string next_page_token = 3; + repeated string datasets = 4; +} + + + + + + + + + + + + + + + + +// service MyDatasetService { +// // option (google.api.default_host) = "my.example.com"; +// rpc MyListDatasets(MyListDatasetsRequest) returns (MyListDatasetsResponse) {} +// } + +// message MyListDatasetsRequest { +// string project_id = 1; +// google.protobuf.UInt32Value max_results = 2; +// string page_token = 3; +// bool all = 4; +// string filter = 5; +// bool show_deleted = 6; +// repeated string debug = 200; +// } + +// // message ListFormatDataset { +// // string kind = 1; +// // string id = 2; +// // // DatasetReference dataset_reference = 3; +// // map labels = 4; +// // google.protobuf.StringValue friendly_name = 5; +// // string location = 6; +// // string type = 7; +// // } + +// message MyListDatasetsResponse { +// string kind = 1; +// string etag = 2; +// string next_page_token = 3; +// repeated string datasets = 4; +// // repeated ListFormatDataset datasets = 4; +// repeated string unreachable = 5; + +// } \ No newline at end of file From 77366f845e618dd2cca4a60b4199eb9cd6ac1df6 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Mon, 31 Mar 2025 16:36:01 +0000 Subject: [PATCH 18/30] as experiment support remove files --- tests/fragments/test_api_version.proto | 37 ---- tests/fragments/test_compute_operation.proto | 108 ----------- tests/fragments/test_dynamic_routing.proto | 167 ------------------ tests/fragments/test_enum_indexed_types.proto | 86 --------- .../test_enum_indexed_types_nonlocal.proto | 54 ------ ...extended_operation_forwardcompat_lro.proto | 108 ----------- tests/fragments/test_flattened_value.proto | 37 ---- .../fragments/test_google_protobuf_type.proto | 62 ------- tests/fragments/test_keyword_import.proto | 33 ---- .../test_multiple_required_fields.proto | 42 ----- tests/fragments/test_nested_messages.proto | 41 ----- tests/fragments/test_non_primitive_body.proto | 101 ----------- .../test_oneof_imported_response.proto | 41 ----- tests/fragments/test_optional_signature.proto | 35 ---- tests/fragments/test_recursive_messages.proto | 34 ---- tests/fragments/test_repeated_double.proto | 38 ---- .../fragments/test_required_non_string.proto | 41 ----- .../fragments/test_reserved_field_name.proto | 45 ----- .../test_reserved_method_names.proto | 97 ---------- tests/fragments/test_rest_streaming.proto | 56 ------ 20 files changed, 1263 deletions(-) delete mode 100644 tests/fragments/test_api_version.proto delete mode 100644 tests/fragments/test_compute_operation.proto delete mode 100644 tests/fragments/test_dynamic_routing.proto delete mode 100644 tests/fragments/test_enum_indexed_types.proto delete mode 100644 tests/fragments/test_enum_indexed_types_nonlocal.proto delete mode 100644 tests/fragments/test_extended_operation_forwardcompat_lro.proto delete mode 100644 tests/fragments/test_flattened_value.proto delete mode 100644 tests/fragments/test_google_protobuf_type.proto delete mode 100644 tests/fragments/test_keyword_import.proto delete mode 100644 tests/fragments/test_multiple_required_fields.proto delete mode 100644 tests/fragments/test_nested_messages.proto delete mode 100644 tests/fragments/test_non_primitive_body.proto delete mode 100644 tests/fragments/test_oneof_imported_response.proto delete mode 100644 tests/fragments/test_optional_signature.proto delete mode 100644 tests/fragments/test_recursive_messages.proto delete mode 100644 tests/fragments/test_repeated_double.proto delete mode 100644 tests/fragments/test_required_non_string.proto delete mode 100644 tests/fragments/test_reserved_field_name.proto delete mode 100644 tests/fragments/test_reserved_method_names.proto delete mode 100644 tests/fragments/test_rest_streaming.proto diff --git a/tests/fragments/test_api_version.proto b/tests/fragments/test_api_version.proto deleted file mode 100644 index d75134d845..0000000000 --- a/tests/fragments/test_api_version.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/protobuf/struct.proto"; -import "google/api/client.proto"; - -service MyServiceWithVersion { - option (google.api.api_version) = "v1_20230601"; - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.method_signature) = "parameter"; - } -} - -message MethodRequest { - google.protobuf.Value parameter = 1; -} - -message MethodResponse { - google.protobuf.Value result = 1; -} diff --git a/tests/fragments/test_compute_operation.proto b/tests/fragments/test_compute_operation.proto deleted file mode 100644 index d471a5ebd8..0000000000 --- a/tests/fragments/test_compute_operation.proto +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/annotations.proto"; -import "google/cloud/extended_operations.proto"; -import "google/protobuf/struct.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; - - -message GetRegionOperationRequest { - // Name of the Operations resource to return. - string operation = 52090215 [ - (google.api.field_behavior) = REQUIRED, - (google.cloud.operation_response_field) = "name" - ]; - - // Project ID for this request. - string project = 227560217 [(google.api.field_behavior) = REQUIRED]; - - // Name of the region for this request. - string region = 138946292 [(google.api.field_behavior) = REQUIRED]; -} - -// A request message for Addresses.Insert. See the method description for details. -message InsertAddressRequest { - // The body resource for this request - Address address_resource = 483888121; - - // Project ID for this request. - string project = 227560217; - - // Name of the region for this request. - string region = 138946292; - -} - -message Address { - // The static IP address represented by this resource. - optional string address = 462920692; -} - -message Operation { - - // [Output Only] The status of the operation, which can be one of the following: `PENDING`, `RUNNING`, or `DONE`. - enum Status { - DONE = 0; - } - - // [Output Only] Name of the operation. - optional string name = 3373707 [(google.cloud.operation_field) = NAME]; - - // [Output Only] If the operation fails, this field contains the HTTP error message that was returned, such as `NOT FOUND`. - optional string http_error_message = 202521945 [(google.cloud.operation_field) = ERROR_MESSAGE]; - - // [Output Only] If the operation fails, this field contains the HTTP error status code that was returned. For example, a `404` means the resource was not found. - optional int32 http_error_status_code = 312345196 [(google.cloud.operation_field) = ERROR_CODE]; - - // [Output Only] The status of the operation, which can be one of the following: `PENDING`, `RUNNING`, or `DONE`. - optional Status status = 181260274 [(google.cloud.operation_field) = STATUS]; -} - -// The RegionOperations API. -service RegionOperations { - option (google.api.default_host) = - "compute.googleapis.com"; - - // Retrieves the specified region-specific Operations resource. - rpc Get(GetRegionOperationRequest) returns (Operation) { - option (google.api.http) = { - get: "/compute/v1/projects/{project}/regions/{region}/operations/{operation}" - }; - option (google.api.method_signature) = "project,region,operation"; - option (google.cloud.operation_polling_method) = true; - } -} - -// The Addresses API. -service Addresses { - option (google.api.default_host) = - "compute.googleapis.com"; - - // Creates an address resource in the specified project by using the data included in the request. - rpc Insert(InsertAddressRequest) returns (Operation) { - option (google.api.http) = { - body: "address_resource" - post: "/compute/v1/projects/{project}/regions/{region}/addresses" - }; - option (google.api.method_signature) = "project,region,address_resource"; - option (google.cloud.operation_service) = "RegionOperations"; - } -} - diff --git a/tests/fragments/test_dynamic_routing.proto b/tests/fragments/test_dynamic_routing.proto deleted file mode 100644 index a8be352dc3..0000000000 --- a/tests/fragments/test_dynamic_routing.proto +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/api/annotations.proto"; -import "google/api/routing.proto"; - -service ServiceNoHeaders { - option (google.api.default_host) = "routingheaders.example.com"; - - rpc Plain(Request) returns(Response); -} - -service ServiceImplicitHeaders { - option (google.api.default_host) = "routingheaders.example.com"; - - rpc Plain(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{table_name=projects/*/instances/*/tables/*}:plain" - }; - } - - rpc WithSubMessage(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{resource.resource_name=projects/*/instances/*/tables/*}:withSubMessage" - }; - } - - rpc WithMultipleLevels(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{resource.inner.inner_name=projects/*/instances/*/tables/*}:withMultipleLevels" - }; - } -} - -service ServiceExplicitHeaders { - option (google.api.default_host) = "routingheaders.example.com"; - - rpc PlainNoTemplate(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" - }; - option (google.api.routing) = { - routing_parameters { - field: "table_name" - } - }; - } - - rpc PlainFullField(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" - }; - option (google.api.routing) = { - routing_parameters { - field: "table_name" - path_template: "{table_name=projects/*/instances/*/tables/*}" - } - }; - } - - rpc PlainExtract(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" - }; - option (google.api.routing) = { - routing_parameters { - field: "table_name" - path_template: "projects/*/instances/*/{table_name=tables/*}" - } - }; - } - - rpc Complex(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" - }; - option (google.api.routing) = { - routing_parameters { - field: "table_name" - path_template: "{project_id=projects/*}/instances/*/tables/*" - } - routing_parameters { - field: "table_name" - path_template: "projects/*/{instance_id=instances/*}/tables/*" - } - routing_parameters { - field: "table_name" - path_template: "projects/*/instances/*/{table_id=tables/*}" - } - routing_parameters { - field: "table_name" - path_template: "{table_name=projects/*/instances/*/tables/*}" - } - routing_parameters { - field: "table_name" - path_template: "{table_name=projects/*/instances/*/tables/*/aliases/**}" - } - routing_parameters { - field: "app_profile_id" - } - routing_parameters { - field: "app_profile_id" - path_template: "{app_profile_id_renamed=**}" - } - }; - } - - rpc WithSubMessage(Request) returns(Response) { - option (google.api.http) = { - get: "/v2/{resource.resource_name=projects/*/instances/*/tables/*}:withSubMessage" - }; - option (google.api.routing) = { - routing_parameters { - field: "resource.resource_name" - path_template: "{table_name=projects/*/instances/*/tables/*}" - } - routing_parameters { - field: "app_profile_id" - } - }; - } -} - -message Request { - // The name of the Table - // Values can be of the following formats: - // - `projects//tables/` - // - `projects//instances//tables/
` - // - `region//zones//tables/
` - string table_name = 1; - - // This value specifies routing for replication. - // It can be in the following formats: - // - profiles/ - // - a legacy profile_id that can be any string - string app_profile_id = 2; - - RequestResource resource = 3; -} - -message RequestResource { - string resource_name = 1; - InnerResource inner = 2; -} - -message InnerResource { - string inner_name = 1; -} - -message Response { -} \ No newline at end of file diff --git a/tests/fragments/test_enum_indexed_types.proto b/tests/fragments/test_enum_indexed_types.proto deleted file mode 100644 index 3fb60b5e13..0000000000 --- a/tests/fragments/test_enum_indexed_types.proto +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/type/dayofweek.proto"; - -service EnumIndexedTypes { - option (google.api.default_host) = "my.example.com"; - - rpc MethodWithRepeatedEnums(MethodRequestWithRepeatedEnums) returns (MethodResponseWithRepeatedEnums) { - } -} - -// Represents a day of the week. Copied from "google/type/dayofweek.proto" -enum Weekday { - // The day of the week is unspecified. - DAY_OF_WEEK_UNSPECIFIED = 0; - - // Monday - MONDAY = 1; - - // Tuesday - TUESDAY = 2; - - // Wednesday - WEDNESDAY = 3; - - // Thursday - THURSDAY = 4; - - // Friday - FRIDAY = 5; - - // Saturday - SATURDAY = 6; - - // Sunday - SUNDAY = 7; -} - - -message MethodRequestWithRepeatedEnums { - // Without proper handling, the two fields below referencing - // google.type.DayOfWeek trigger errors like: - // - // TypeError: Parameters to generic types must be types. - // Got - // - // Interestingly, the fields referencing the Weekday type defined in this file - // do not trigger that error. - // - // The generated code needs to either quote the type, or `from __future__ - // import annotations`. This may be solved by PEP 563, currently scheduled for - // Python 3.11 - // (cf. https://mail.python.org/archives/list/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/) - - repeated Weekday which_days = 1; - repeated google.type.DayOfWeek holidays = 2; - map string_days = 3; - map string_holidays = 4; -} - -message MethodResponseWithRepeatedEnums { - // The commentary in MethodRequestWithRepeatedEnums describes what is tested - // below. - - repeated Weekday which_days = 1; - repeated google.type.DayOfWeek holidays = 2; - map string_days = 3; - map string_holidays = 4; -} diff --git a/tests/fragments/test_enum_indexed_types_nonlocal.proto b/tests/fragments/test_enum_indexed_types_nonlocal.proto deleted file mode 100644 index 09af4b4abf..0000000000 --- a/tests/fragments/test_enum_indexed_types_nonlocal.proto +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/type/dayofweek.proto"; - -// This test differs from the one implemented by service EnumIndexedTypes in -// that this file does not define any enum types, which may lead to a -// slightly distinct template generation path. -service EnumIndexedTypesNonLocal { - option (google.api.default_host) = "my.example.com"; - - rpc MethodWithRepeatedEnums(MethodRequestWithRepeatedEnums) returns (MethodResponseWithRepeatedEnums) { - } -} - -message MethodRequestWithRepeatedEnums { - // Without proper handling, the two fields below referencing - // google.type.DayOfWeek trigger errors like: - // - // TypeError: Parameters to generic types must be types. - // Got - // - // The generated code needs to either quote the type, or `from __future__ - // import annotations`. This may be solved by PEP 563, currently scheduled for - // Python 3.11 - // (cf. https://mail.python.org/archives/list/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/) - - repeated google.type.DayOfWeek holidays = 2; - map string_holidays = 4; -} - -message MethodResponseWithRepeatedEnums { - // The commentary in MethodRequestWithRepeatedEnums describes what is tested - // below. - - repeated google.type.DayOfWeek holidays = 2; - map string_holidays = 4; -} diff --git a/tests/fragments/test_extended_operation_forwardcompat_lro.proto b/tests/fragments/test_extended_operation_forwardcompat_lro.proto deleted file mode 100644 index 4d0da51106..0000000000 --- a/tests/fragments/test_extended_operation_forwardcompat_lro.proto +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -syntax = "proto3"; - -package google.fragment; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/cloud/extended_operations.proto"; - -message Operation { - enum Status { - // A value indicating that the enum field is not set. - UNDEFINED_STATUS = 0; - DONE = 2104194; - PENDING = 35394935; - RUNNING = 121282975; - } - - optional string name = 1 [ - (google.cloud.operation_field) = NAME, - (google.cloud.operation_response_field) = "name" - ]; - optional string http_error_message = 202521945 [(google.cloud.operation_field) = ERROR_MESSAGE]; - optional int32 http_error_status_code = 312345196 [(google.cloud.operation_field) = ERROR_CODE]; - optional Status status = 181260274 [(google.cloud.operation_field) = STATUS]; -} - -message GetExpensiveComputationRequest { - string name = 1; - string computation = 2; - string fragment = 3; -} - -message DeleteExpensiveComputationRequest { - string computation = 1; - string fragment = 2; -} - -message DeleteOperationResponse { - bool success = 1; -} - -message StartExpensiveComputationRequest { - string computation = 1 [ - (google.cloud.operation_request_field) = "computation" - ]; - string fragment = 2 [ - (google.cloud.operation_request_field) = "fragment" - ]; -} - -message StartCheapComputationRequest { - string computation = 1; - string fragment = 2; -} - -message StartCheapComputationResponse {} - -// Note: the name is a hint, but this is the de facto Operations client. -// It should _not_ generate methods with disambiguated names. -service DefactoOperationsClient { - option (google.api.default_host) = "my.example.com"; - - rpc Get(GetExpensiveComputationRequest) returns (Operation) { - option (google.cloud.operation_polling_method) = true; - option (google.api.http) = { - get: "/expensive/v1/computations/{computation}/fragments/{fragment}" - }; - } - - - rpc Delete(DeleteExpensiveComputationRequest) returns (DeleteOperationResponse) { - option (google.api.http) = { - delete: "/expensive/v1/computations/{computation}/fragments/{fragment}" - }; - - } -} - - -service DoStuff { - option (google.api.default_host) = "my.example.com"; - - rpc StartExpensiveComputation(StartExpensiveComputationRequest) returns (Operation) { - option (google.cloud.operation_service) = "DefactoOperationsClient"; - option (google.api.http) = { - post: "/expensive/v1/computations/{computation}/fragments/{fragment}" - }; - } - - rpc StartCheapComputation(StartCheapComputationRequest) returns (StartCheapComputationResponse) { - option (google.api.http) = { - post: "/expensive/v1/computations/{computation}/fragments/{fragment}"; - }; - } -} diff --git a/tests/fragments/test_flattened_value.proto b/tests/fragments/test_flattened_value.proto deleted file mode 100644 index 8965b97d40..0000000000 --- a/tests/fragments/test_flattened_value.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/protobuf/struct.proto"; -import "google/api/client.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.method_signature) = "parameter,items"; - } -} - -message MethodRequest { - google.protobuf.Value parameter = 1; - repeated google.protobuf.Value items = 2; -} - -message MethodResponse { - string result = 1; -} diff --git a/tests/fragments/test_google_protobuf_type.proto b/tests/fragments/test_google_protobuf_type.proto deleted file mode 100644 index e9a47a1293..0000000000 --- a/tests/fragments/test_google_protobuf_type.proto +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -// The purpose of this fragment test is to test for an issue found in the generated -// client for `google/api/servicemanagement/v1` where the version of a generated -// dependency (google.protobuf.type) at runtime differs from the version used during -// generation. See https://github.com/googleapis/gapic-generator-python/issues/1748. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/protobuf/struct.proto"; -import "google/protobuf/type.proto"; - -service MyServiceWithProtobufType { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequestWithProtobufType) - returns (MethodResponseWithProtobufType) { - option (google.api.http) = { - post: "/v1/services/{service_name}/configs/{test_message.another_message.another_field}" - body: "test_message" - }; - option (google.api.method_signature) = "service_name,test_message,another_string"; - } -} - -message MethodRequestWithProtobufType { - string service_name = 1 [(google.api.field_behavior) = REQUIRED]; - TestMessage test_message = 2 [(google.api.field_behavior) = REQUIRED]; - string another_string = 3 [(google.api.field_behavior) = REQUIRED]; -} - -message TestMessage { - string name = 1 [(google.api.field_behavior) = REQUIRED]; - repeated google.protobuf.Type types = 2 [(google.api.field_behavior) = REQUIRED]; - AnotherTestMessage another_message = 3 [(google.api.field_behavior) = REQUIRED]; -} - -message AnotherTestMessage { - string another_field = 1; -} - -message MethodResponseWithProtobufType { - google.protobuf.Value result = 1; -} diff --git a/tests/fragments/test_keyword_import.proto b/tests/fragments/test_keyword_import.proto deleted file mode 100644 index 81ce44eda1..0000000000 --- a/tests/fragments/test_keyword_import.proto +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "import.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - rpc MyMethod(MethodRequest) returns (MethodResponse) {} -} - -message MethodRequest { - Import import = 1; -} - -message MethodResponse { - string result = 1; -} diff --git a/tests/fragments/test_multiple_required_fields.proto b/tests/fragments/test_multiple_required_fields.proto deleted file mode 100644 index 55a207b40a..0000000000 --- a/tests/fragments/test_multiple_required_fields.proto +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/annotations.proto"; - -service MultipleRequiredFields { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.http) = { - get: "/nomenclature/v1/kingdom/{kingdom}/phylum/{phylum}" - }; - } -} - -message MethodRequest { - string kingdom = 1 [(google.api.field_behavior) = REQUIRED]; - string phylum = 2 [(google.api.field_behavior) = REQUIRED]; - string name = 3 [(google.api.field_behavior) = REQUIRED]; - int32 armor_class = 4 [(google.api.field_behavior) = REQUIRED]; -} - -message MethodResponse{ - string text = 1; -} \ No newline at end of file diff --git a/tests/fragments/test_nested_messages.proto b/tests/fragments/test_nested_messages.proto deleted file mode 100644 index 6c98cb15d2..0000000000 --- a/tests/fragments/test_nested_messages.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -syntax = "proto3"; - -package google.fragment; - -import "google/protobuf/struct.proto"; -import "google/api/client.proto"; - -service MyServiceWithNestedMessages { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.method_signature) = "some_message"; - } -} - -message AnotherMessage {}; - -message SomeMessage{ - AnotherMessage another_message = 1; -} - -message MethodRequest { - SomeMessage some_message = 1; -} - -message MethodResponse { - google.protobuf.Value result = 1; -} diff --git a/tests/fragments/test_non_primitive_body.proto b/tests/fragments/test_non_primitive_body.proto deleted file mode 100644 index 06a16da6ff..0000000000 --- a/tests/fragments/test_non_primitive_body.proto +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/api/annotations.proto"; -import "google/api/field_behavior.proto"; - -service SmallCompute { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.http) = { - body: "method_body" - post: "/computation/v1/first_name/{first_name}/last_name/{last_name}" - }; - }; - - rpc EnumBody(EnumBodyRequest) returns (EnumBodyResponse) { - option (google.api.http) = { - body: "resource" - post: "/enum_body/v1/names/{name}" - }; - } - - rpc RecursiveBody(RecursiveBodyRequest) returns (RecursiveBodyResponse) { - option (google.api.http) = { - body: "resource" - post: "/recursive_body/v1/names/{name}" - }; - } -} - -message SerialNumber { - int32 number = 1; -} - -message MethodRequest { - message MethodBody { - int32 mass_kg = 1; - int32 length_cm = 2; - repeated SerialNumber serial_numbers = 3; - map word_associations = 4; - } - - string first_name = 1 [(google.api.field_behavior) = REQUIRED]; - string last_name = 2 [(google.api.field_behavior) = REQUIRED]; - MethodBody method_body = 3 [(google.api.field_behavior) = REQUIRED]; -} - -message MethodResponse { - string name = 1; -} - -message EnumBodyRequest { - message Resource{ - enum Ordering { - UNKNOWN = 0; - CHRONOLOGICAL = 1; - ALPHABETICAL = 2; - DIFFICULTY = 3; - } - - Ordering ordering = 1; - } - - string name = 1; - Resource resource = 2; -} - -message EnumBodyResponse { - string data = 1; -} - -message RecursiveBodyRequest { - message Resource { - int32 depth = 1; - Resource child_resource = 2; - } - - string name = 1; - Resource resource = 2; -} - -message RecursiveBodyResponse { - string data = 1; -} \ No newline at end of file diff --git a/tests/fragments/test_oneof_imported_response.proto b/tests/fragments/test_oneof_imported_response.proto deleted file mode 100644 index 53f2a2cbd2..0000000000 --- a/tests/fragments/test_oneof_imported_response.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "import.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - rpc MyMethod(MethodRequest) returns (MethodResponse) {} -} - -message MethodRequest { - string input = 1; -} - -message Container { - Import import = 1; -} - -message MethodResponse { - string parent = 1; - oneof format { - Container container = 2; - string name = 3; - } -} diff --git a/tests/fragments/test_optional_signature.proto b/tests/fragments/test_optional_signature.proto deleted file mode 100644 index 4789abd596..0000000000 --- a/tests/fragments/test_optional_signature.proto +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.method_signature) = "parameter"; - } - -} - -message MethodRequest { - optional string parameter = 1; -} - -message MethodResponse { - string result = 1; -} diff --git a/tests/fragments/test_recursive_messages.proto b/tests/fragments/test_recursive_messages.proto deleted file mode 100644 index efe2685877..0000000000 --- a/tests/fragments/test_recursive_messages.proto +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) {} -} - -message MethodRequest { - int32 depth = 1; - MethodRequest child = 2; -} - -message MethodResponse { - string result = 1; -} diff --git a/tests/fragments/test_repeated_double.proto b/tests/fragments/test_repeated_double.proto deleted file mode 100644 index 63db0371b6..0000000000 --- a/tests/fragments/test_repeated_double.proto +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/protobuf/struct.proto"; -import "google/api/client.proto"; - -service MyServiceRepeatedDouble { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequestWithRepeatedDouble) returns (MethodResponseWithRepeatedDouble) { - option (google.api.method_signature) = "parameter,items"; - } -} - -message MethodRequestWithRepeatedDouble { - google.protobuf.Value parameter = 1; - repeated google.protobuf.Value items = 2; - repeated double repeated_items = 3; -} - -message MethodResponseWithRepeatedDouble { - repeated double result = 1; -} diff --git a/tests/fragments/test_required_non_string.proto b/tests/fragments/test_required_non_string.proto deleted file mode 100644 index 7186a83c87..0000000000 --- a/tests/fragments/test_required_non_string.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/api/annotations.proto"; - -service RestService { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.http) = { - get: "/restservice/v1/mass_kg/{mass_kg}/length_cm/{length_cm}" - }; - } -} - - -message MethodRequest { - int32 mass_kg = 1 [(google.api.field_behavior) = REQUIRED]; - int32 length_cm = 2 [(google.api.field_behavior) = REQUIRED]; -} - -message MethodResponse { - string name = 1; -} \ No newline at end of file diff --git a/tests/fragments/test_reserved_field_name.proto b/tests/fragments/test_reserved_field_name.proto deleted file mode 100644 index f11b3416ce..0000000000 --- a/tests/fragments/test_reserved_field_name.proto +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethod(MethodRequest) returns (MethodResponse) { - option (google.api.method_signature) = "from,class,import,any,license,type"; - } - -} - -message MethodRequest { - string from = 1; - string class = 2; - string import = 3; - string any = 4; - string license = 5; - string type = 6; - // Refer to PEP8 https://peps.python.org/pep-0008/#function-and-method-arguments - string self = 7; - // Refer to PEP8 https://peps.python.org/pep-0008/#function-and-method-arguments - string cls = 8; -} - -message MethodResponse { - string result = 1; -} diff --git a/tests/fragments/test_reserved_method_names.proto b/tests/fragments/test_reserved_method_names.proto deleted file mode 100644 index ba89ef0f25..0000000000 --- a/tests/fragments/test_reserved_method_names.proto +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/api/annotations.proto"; -import "google/longrunning/operations.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - - rpc CreateChannel(CreateChannelRequest) returns (CreateChannelResponse) { - option (google.api.http) = { - body: "*" - post: "/channels/v1/channel/{channel}" - }; - }; - - rpc Import(CreateImportRequest) returns (CreateImportResponse) { - option (google.api.http) = { - body: "*" - post: "/import/v1" - }; - }; - - rpc GrpcChannel(GrpcChannelRequest) returns (GrpcChannelResponse) { - option (google.api.http) = { - body: "*" - post: "/channels/v1/grpc_channel/{grpc_channel}" - }; - }; - - rpc OperationsClient(OperationsClientRequest) returns (google.longrunning.Operation) { - option (google.api.http) = { - body: "*" - post: "/clients/v1/operations_clients/{operations_client}" - }; - option (google.longrunning.operation_info) = { - response_type: "google.fragment.OperationsClientResponse" - metadata_type: "google.fragment.OperationsMetadata" - }; - }; - -} - -message CreateChannelRequest { - string channel = 1; - string info = 2; -} - -message CreateChannelResponse { - string info = 1; -} - -message CreateImportRequest { - string info = 1; -} - -message CreateImportResponse { - string info = 1; -} - -message GrpcChannelRequest { - string grpc_channel = 1; - string info = 2; -} - -message GrpcChannelResponse { - string info = 1; -} - -message OperationsClientRequest { - string operations_client = 1; - string info = 2; -} - -message OperationsClientResponse { - string info = 1; -} - -message OperationsMetadata { - string data = 1; -} \ No newline at end of file diff --git a/tests/fragments/test_rest_streaming.proto b/tests/fragments/test_rest_streaming.proto deleted file mode 100644 index 2055144005..0000000000 --- a/tests/fragments/test_rest_streaming.proto +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/httpbody.proto"; - -service MyService { - option (google.api.default_host) = "my.example.com"; - - rpc MyMethodApiSpecificResponse(MethodRequest) returns (stream MethodResponse) { - option (google.api.http) = { - post: "/v1/{from=projects/*}" - body: "*" - }; - option (google.api.method_signature) = "from,class,import,any,license,type"; - } - - rpc MyMethodCommonResponse(MethodRequest) returns (stream google.api.HttpBody) { - option (google.api.http) = { - post: "/v1/{from=projects/*}" - body: "*" - }; - option (google.api.method_signature) = "from,class,import,any,license,type"; - } -} - -message MethodRequest { - string from = 1; - string class = 2; - string import = 3; - string any = 4; - string license = 5; - string type = 6; - int32 page_size = 7; - string page_token = 8; -} - -message MethodResponse { - string result = 1; -} From a85188048630d5dc01b26c4596f8947d212c12fc Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Mon, 31 Mar 2025 16:36:36 +0000 Subject: [PATCH 19/30] add page_size focused test --- .../fragments/test_pagination_page_size.proto | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/fragments/test_pagination_page_size.proto diff --git a/tests/fragments/test_pagination_page_size.proto b/tests/fragments/test_pagination_page_size.proto new file mode 100644 index 0000000000..7452ef60da --- /dev/null +++ b/tests/fragments/test_pagination_page_size.proto @@ -0,0 +1,86 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/protobuf/wrappers.proto"; + +service MyDatasetService { + option (google.api.default_host) = "my.example.com"; + rpc ListMyDataset(ListDatasetRequest) returns (ListDatasetResponse) { + } +} + +message ListDatasetRequest { + int32 page_size = 2; + string page_token = 3; +} + +message ListDatasetResponse { + string next_page_token = 3; + repeated string datasets = 4; +} + + + + + + + + + + + + + + + + +// service MyDatasetService { +// // option (google.api.default_host) = "my.example.com"; +// rpc MyListDatasets(MyListDatasetsRequest) returns (MyListDatasetsResponse) {} +// } + +// message MyListDatasetsRequest { +// string project_id = 1; +// google.protobuf.UInt32Value max_results = 2; +// string page_token = 3; +// bool all = 4; +// string filter = 5; +// bool show_deleted = 6; +// repeated string debug = 200; +// } + +// // message ListFormatDataset { +// // string kind = 1; +// // string id = 2; +// // // DatasetReference dataset_reference = 3; +// // map labels = 4; +// // google.protobuf.StringValue friendly_name = 5; +// // string location = 6; +// // string type = 7; +// // } + +// message MyListDatasetsResponse { +// string kind = 1; +// string etag = 2; +// string next_page_token = 3; +// repeated string datasets = 4; +// // repeated ListFormatDataset datasets = 4; +// repeated string unreachable = 5; + +// } \ No newline at end of file From fbe3961d6cfe167d9cac9614246c1b51972ed64e Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 1 Apr 2025 15:03:51 +0000 Subject: [PATCH 20/30] updates proto files for max_result and page_size --- ...t_pagination_max_results_and_wrapper.proto | 58 +------------ .../fragments/test_pagination_page_size.proto | 86 ------------------- 2 files changed, 4 insertions(+), 140 deletions(-) delete mode 100644 tests/fragments/test_pagination_page_size.proto diff --git a/tests/fragments/test_pagination_max_results_and_wrapper.proto b/tests/fragments/test_pagination_max_results_and_wrapper.proto index b1a69087fe..ea2ab2d687 100644 --- a/tests/fragments/test_pagination_max_results_and_wrapper.proto +++ b/tests/fragments/test_pagination_max_results_and_wrapper.proto @@ -19,68 +19,18 @@ package google.fragment; import "google/api/client.proto"; import "google/protobuf/wrappers.proto"; -service MyDatasetService { +service MaxResultsDatasetService { option (google.api.default_host) = "my.example.com"; - rpc ListMyDataset(ListDatasetRequest) returns (ListDatasetResponse) { + rpc ListMaxResultsDataset(ListMaxResultsDatasetRequest) returns (ListMaxResultsDatasetResponse) { } } -message ListDatasetRequest { +message ListMaxResultsDatasetRequest { google.protobuf.UInt32Value max_results = 2; string page_token = 3; } -message ListDatasetResponse { +message ListMaxResultsDatasetResponse { string next_page_token = 3; repeated string datasets = 4; } - - - - - - - - - - - - - - - - -// service MyDatasetService { -// // option (google.api.default_host) = "my.example.com"; -// rpc MyListDatasets(MyListDatasetsRequest) returns (MyListDatasetsResponse) {} -// } - -// message MyListDatasetsRequest { -// string project_id = 1; -// google.protobuf.UInt32Value max_results = 2; -// string page_token = 3; -// bool all = 4; -// string filter = 5; -// bool show_deleted = 6; -// repeated string debug = 200; -// } - -// // message ListFormatDataset { -// // string kind = 1; -// // string id = 2; -// // // DatasetReference dataset_reference = 3; -// // map labels = 4; -// // google.protobuf.StringValue friendly_name = 5; -// // string location = 6; -// // string type = 7; -// // } - -// message MyListDatasetsResponse { -// string kind = 1; -// string etag = 2; -// string next_page_token = 3; -// repeated string datasets = 4; -// // repeated ListFormatDataset datasets = 4; -// repeated string unreachable = 5; - -// } \ No newline at end of file diff --git a/tests/fragments/test_pagination_page_size.proto b/tests/fragments/test_pagination_page_size.proto deleted file mode 100644 index 7452ef60da..0000000000 --- a/tests/fragments/test_pagination_page_size.proto +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/protobuf/wrappers.proto"; - -service MyDatasetService { - option (google.api.default_host) = "my.example.com"; - rpc ListMyDataset(ListDatasetRequest) returns (ListDatasetResponse) { - } -} - -message ListDatasetRequest { - int32 page_size = 2; - string page_token = 3; -} - -message ListDatasetResponse { - string next_page_token = 3; - repeated string datasets = 4; -} - - - - - - - - - - - - - - - - -// service MyDatasetService { -// // option (google.api.default_host) = "my.example.com"; -// rpc MyListDatasets(MyListDatasetsRequest) returns (MyListDatasetsResponse) {} -// } - -// message MyListDatasetsRequest { -// string project_id = 1; -// google.protobuf.UInt32Value max_results = 2; -// string page_token = 3; -// bool all = 4; -// string filter = 5; -// bool show_deleted = 6; -// repeated string debug = 200; -// } - -// // message ListFormatDataset { -// // string kind = 1; -// // string id = 2; -// // // DatasetReference dataset_reference = 3; -// // map labels = 4; -// // google.protobuf.StringValue friendly_name = 5; -// // string location = 6; -// // string type = 7; -// // } - -// message MyListDatasetsResponse { -// string kind = 1; -// string etag = 2; -// string next_page_token = 3; -// repeated string datasets = 4; -// // repeated ListFormatDataset datasets = 4; -// repeated string unreachable = 5; - -// } \ No newline at end of file From 01efee0b62a5074500d3cfca3a6116f7812acfce Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 1 Apr 2025 15:06:30 +0000 Subject: [PATCH 21/30] adds back the temporarily removed fragments tests --- tests/fragments/test_api_version.proto | 37 ++++ tests/fragments/test_compute_operation.proto | 108 +++++++++++ tests/fragments/test_dynamic_routing.proto | 167 ++++++++++++++++++ tests/fragments/test_enum_indexed_types.proto | 86 +++++++++ .../test_enum_indexed_types_nonlocal.proto | 54 ++++++ ...extended_operation_forwardcompat_lro.proto | 108 +++++++++++ tests/fragments/test_flattened_value.proto | 37 ++++ .../fragments/test_google_protobuf_type.proto | 62 +++++++ tests/fragments/test_keyword_import.proto | 33 ++++ .../test_multiple_required_fields.proto | 42 +++++ tests/fragments/test_nested_messages.proto | 41 +++++ tests/fragments/test_non_primitive_body.proto | 101 +++++++++++ .../test_oneof_imported_response.proto | 41 +++++ tests/fragments/test_optional_signature.proto | 35 ++++ tests/fragments/test_recursive_messages.proto | 34 ++++ tests/fragments/test_repeated_double.proto | 38 ++++ .../fragments/test_required_non_string.proto | 41 +++++ .../fragments/test_reserved_field_name.proto | 45 +++++ .../test_reserved_method_names.proto | 97 ++++++++++ tests/fragments/test_rest_streaming.proto | 56 ++++++ 20 files changed, 1263 insertions(+) create mode 100644 tests/fragments/test_api_version.proto create mode 100644 tests/fragments/test_compute_operation.proto create mode 100644 tests/fragments/test_dynamic_routing.proto create mode 100644 tests/fragments/test_enum_indexed_types.proto create mode 100644 tests/fragments/test_enum_indexed_types_nonlocal.proto create mode 100644 tests/fragments/test_extended_operation_forwardcompat_lro.proto create mode 100644 tests/fragments/test_flattened_value.proto create mode 100644 tests/fragments/test_google_protobuf_type.proto create mode 100644 tests/fragments/test_keyword_import.proto create mode 100644 tests/fragments/test_multiple_required_fields.proto create mode 100644 tests/fragments/test_nested_messages.proto create mode 100644 tests/fragments/test_non_primitive_body.proto create mode 100644 tests/fragments/test_oneof_imported_response.proto create mode 100644 tests/fragments/test_optional_signature.proto create mode 100644 tests/fragments/test_recursive_messages.proto create mode 100644 tests/fragments/test_repeated_double.proto create mode 100644 tests/fragments/test_required_non_string.proto create mode 100644 tests/fragments/test_reserved_field_name.proto create mode 100644 tests/fragments/test_reserved_method_names.proto create mode 100644 tests/fragments/test_rest_streaming.proto diff --git a/tests/fragments/test_api_version.proto b/tests/fragments/test_api_version.proto new file mode 100644 index 0000000000..d75134d845 --- /dev/null +++ b/tests/fragments/test_api_version.proto @@ -0,0 +1,37 @@ +// Copyright (C) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/protobuf/struct.proto"; +import "google/api/client.proto"; + +service MyServiceWithVersion { + option (google.api.api_version) = "v1_20230601"; + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.method_signature) = "parameter"; + } +} + +message MethodRequest { + google.protobuf.Value parameter = 1; +} + +message MethodResponse { + google.protobuf.Value result = 1; +} diff --git a/tests/fragments/test_compute_operation.proto b/tests/fragments/test_compute_operation.proto new file mode 100644 index 0000000000..d471a5ebd8 --- /dev/null +++ b/tests/fragments/test_compute_operation.proto @@ -0,0 +1,108 @@ +// Copyright (C) 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/annotations.proto"; +import "google/cloud/extended_operations.proto"; +import "google/protobuf/struct.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; + + +message GetRegionOperationRequest { + // Name of the Operations resource to return. + string operation = 52090215 [ + (google.api.field_behavior) = REQUIRED, + (google.cloud.operation_response_field) = "name" + ]; + + // Project ID for this request. + string project = 227560217 [(google.api.field_behavior) = REQUIRED]; + + // Name of the region for this request. + string region = 138946292 [(google.api.field_behavior) = REQUIRED]; +} + +// A request message for Addresses.Insert. See the method description for details. +message InsertAddressRequest { + // The body resource for this request + Address address_resource = 483888121; + + // Project ID for this request. + string project = 227560217; + + // Name of the region for this request. + string region = 138946292; + +} + +message Address { + // The static IP address represented by this resource. + optional string address = 462920692; +} + +message Operation { + + // [Output Only] The status of the operation, which can be one of the following: `PENDING`, `RUNNING`, or `DONE`. + enum Status { + DONE = 0; + } + + // [Output Only] Name of the operation. + optional string name = 3373707 [(google.cloud.operation_field) = NAME]; + + // [Output Only] If the operation fails, this field contains the HTTP error message that was returned, such as `NOT FOUND`. + optional string http_error_message = 202521945 [(google.cloud.operation_field) = ERROR_MESSAGE]; + + // [Output Only] If the operation fails, this field contains the HTTP error status code that was returned. For example, a `404` means the resource was not found. + optional int32 http_error_status_code = 312345196 [(google.cloud.operation_field) = ERROR_CODE]; + + // [Output Only] The status of the operation, which can be one of the following: `PENDING`, `RUNNING`, or `DONE`. + optional Status status = 181260274 [(google.cloud.operation_field) = STATUS]; +} + +// The RegionOperations API. +service RegionOperations { + option (google.api.default_host) = + "compute.googleapis.com"; + + // Retrieves the specified region-specific Operations resource. + rpc Get(GetRegionOperationRequest) returns (Operation) { + option (google.api.http) = { + get: "/compute/v1/projects/{project}/regions/{region}/operations/{operation}" + }; + option (google.api.method_signature) = "project,region,operation"; + option (google.cloud.operation_polling_method) = true; + } +} + +// The Addresses API. +service Addresses { + option (google.api.default_host) = + "compute.googleapis.com"; + + // Creates an address resource in the specified project by using the data included in the request. + rpc Insert(InsertAddressRequest) returns (Operation) { + option (google.api.http) = { + body: "address_resource" + post: "/compute/v1/projects/{project}/regions/{region}/addresses" + }; + option (google.api.method_signature) = "project,region,address_resource"; + option (google.cloud.operation_service) = "RegionOperations"; + } +} + diff --git a/tests/fragments/test_dynamic_routing.proto b/tests/fragments/test_dynamic_routing.proto new file mode 100644 index 0000000000..a8be352dc3 --- /dev/null +++ b/tests/fragments/test_dynamic_routing.proto @@ -0,0 +1,167 @@ +// Copyright (C) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/api/annotations.proto"; +import "google/api/routing.proto"; + +service ServiceNoHeaders { + option (google.api.default_host) = "routingheaders.example.com"; + + rpc Plain(Request) returns(Response); +} + +service ServiceImplicitHeaders { + option (google.api.default_host) = "routingheaders.example.com"; + + rpc Plain(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{table_name=projects/*/instances/*/tables/*}:plain" + }; + } + + rpc WithSubMessage(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{resource.resource_name=projects/*/instances/*/tables/*}:withSubMessage" + }; + } + + rpc WithMultipleLevels(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{resource.inner.inner_name=projects/*/instances/*/tables/*}:withMultipleLevels" + }; + } +} + +service ServiceExplicitHeaders { + option (google.api.default_host) = "routingheaders.example.com"; + + rpc PlainNoTemplate(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" + }; + option (google.api.routing) = { + routing_parameters { + field: "table_name" + } + }; + } + + rpc PlainFullField(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" + }; + option (google.api.routing) = { + routing_parameters { + field: "table_name" + path_template: "{table_name=projects/*/instances/*/tables/*}" + } + }; + } + + rpc PlainExtract(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" + }; + option (google.api.routing) = { + routing_parameters { + field: "table_name" + path_template: "projects/*/instances/*/{table_name=tables/*}" + } + }; + } + + rpc Complex(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys" + }; + option (google.api.routing) = { + routing_parameters { + field: "table_name" + path_template: "{project_id=projects/*}/instances/*/tables/*" + } + routing_parameters { + field: "table_name" + path_template: "projects/*/{instance_id=instances/*}/tables/*" + } + routing_parameters { + field: "table_name" + path_template: "projects/*/instances/*/{table_id=tables/*}" + } + routing_parameters { + field: "table_name" + path_template: "{table_name=projects/*/instances/*/tables/*}" + } + routing_parameters { + field: "table_name" + path_template: "{table_name=projects/*/instances/*/tables/*/aliases/**}" + } + routing_parameters { + field: "app_profile_id" + } + routing_parameters { + field: "app_profile_id" + path_template: "{app_profile_id_renamed=**}" + } + }; + } + + rpc WithSubMessage(Request) returns(Response) { + option (google.api.http) = { + get: "/v2/{resource.resource_name=projects/*/instances/*/tables/*}:withSubMessage" + }; + option (google.api.routing) = { + routing_parameters { + field: "resource.resource_name" + path_template: "{table_name=projects/*/instances/*/tables/*}" + } + routing_parameters { + field: "app_profile_id" + } + }; + } +} + +message Request { + // The name of the Table + // Values can be of the following formats: + // - `projects//tables/
` + // - `projects//instances//tables/
` + // - `region//zones//tables/
` + string table_name = 1; + + // This value specifies routing for replication. + // It can be in the following formats: + // - profiles/ + // - a legacy profile_id that can be any string + string app_profile_id = 2; + + RequestResource resource = 3; +} + +message RequestResource { + string resource_name = 1; + InnerResource inner = 2; +} + +message InnerResource { + string inner_name = 1; +} + +message Response { +} \ No newline at end of file diff --git a/tests/fragments/test_enum_indexed_types.proto b/tests/fragments/test_enum_indexed_types.proto new file mode 100644 index 0000000000..3fb60b5e13 --- /dev/null +++ b/tests/fragments/test_enum_indexed_types.proto @@ -0,0 +1,86 @@ +// Copyright (C) 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/type/dayofweek.proto"; + +service EnumIndexedTypes { + option (google.api.default_host) = "my.example.com"; + + rpc MethodWithRepeatedEnums(MethodRequestWithRepeatedEnums) returns (MethodResponseWithRepeatedEnums) { + } +} + +// Represents a day of the week. Copied from "google/type/dayofweek.proto" +enum Weekday { + // The day of the week is unspecified. + DAY_OF_WEEK_UNSPECIFIED = 0; + + // Monday + MONDAY = 1; + + // Tuesday + TUESDAY = 2; + + // Wednesday + WEDNESDAY = 3; + + // Thursday + THURSDAY = 4; + + // Friday + FRIDAY = 5; + + // Saturday + SATURDAY = 6; + + // Sunday + SUNDAY = 7; +} + + +message MethodRequestWithRepeatedEnums { + // Without proper handling, the two fields below referencing + // google.type.DayOfWeek trigger errors like: + // + // TypeError: Parameters to generic types must be types. + // Got + // + // Interestingly, the fields referencing the Weekday type defined in this file + // do not trigger that error. + // + // The generated code needs to either quote the type, or `from __future__ + // import annotations`. This may be solved by PEP 563, currently scheduled for + // Python 3.11 + // (cf. https://mail.python.org/archives/list/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/) + + repeated Weekday which_days = 1; + repeated google.type.DayOfWeek holidays = 2; + map string_days = 3; + map string_holidays = 4; +} + +message MethodResponseWithRepeatedEnums { + // The commentary in MethodRequestWithRepeatedEnums describes what is tested + // below. + + repeated Weekday which_days = 1; + repeated google.type.DayOfWeek holidays = 2; + map string_days = 3; + map string_holidays = 4; +} diff --git a/tests/fragments/test_enum_indexed_types_nonlocal.proto b/tests/fragments/test_enum_indexed_types_nonlocal.proto new file mode 100644 index 0000000000..09af4b4abf --- /dev/null +++ b/tests/fragments/test_enum_indexed_types_nonlocal.proto @@ -0,0 +1,54 @@ +// Copyright (C) 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/type/dayofweek.proto"; + +// This test differs from the one implemented by service EnumIndexedTypes in +// that this file does not define any enum types, which may lead to a +// slightly distinct template generation path. +service EnumIndexedTypesNonLocal { + option (google.api.default_host) = "my.example.com"; + + rpc MethodWithRepeatedEnums(MethodRequestWithRepeatedEnums) returns (MethodResponseWithRepeatedEnums) { + } +} + +message MethodRequestWithRepeatedEnums { + // Without proper handling, the two fields below referencing + // google.type.DayOfWeek trigger errors like: + // + // TypeError: Parameters to generic types must be types. + // Got + // + // The generated code needs to either quote the type, or `from __future__ + // import annotations`. This may be solved by PEP 563, currently scheduled for + // Python 3.11 + // (cf. https://mail.python.org/archives/list/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/) + + repeated google.type.DayOfWeek holidays = 2; + map string_holidays = 4; +} + +message MethodResponseWithRepeatedEnums { + // The commentary in MethodRequestWithRepeatedEnums describes what is tested + // below. + + repeated google.type.DayOfWeek holidays = 2; + map string_holidays = 4; +} diff --git a/tests/fragments/test_extended_operation_forwardcompat_lro.proto b/tests/fragments/test_extended_operation_forwardcompat_lro.proto new file mode 100644 index 0000000000..4d0da51106 --- /dev/null +++ b/tests/fragments/test_extended_operation_forwardcompat_lro.proto @@ -0,0 +1,108 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +syntax = "proto3"; + +package google.fragment; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/cloud/extended_operations.proto"; + +message Operation { + enum Status { + // A value indicating that the enum field is not set. + UNDEFINED_STATUS = 0; + DONE = 2104194; + PENDING = 35394935; + RUNNING = 121282975; + } + + optional string name = 1 [ + (google.cloud.operation_field) = NAME, + (google.cloud.operation_response_field) = "name" + ]; + optional string http_error_message = 202521945 [(google.cloud.operation_field) = ERROR_MESSAGE]; + optional int32 http_error_status_code = 312345196 [(google.cloud.operation_field) = ERROR_CODE]; + optional Status status = 181260274 [(google.cloud.operation_field) = STATUS]; +} + +message GetExpensiveComputationRequest { + string name = 1; + string computation = 2; + string fragment = 3; +} + +message DeleteExpensiveComputationRequest { + string computation = 1; + string fragment = 2; +} + +message DeleteOperationResponse { + bool success = 1; +} + +message StartExpensiveComputationRequest { + string computation = 1 [ + (google.cloud.operation_request_field) = "computation" + ]; + string fragment = 2 [ + (google.cloud.operation_request_field) = "fragment" + ]; +} + +message StartCheapComputationRequest { + string computation = 1; + string fragment = 2; +} + +message StartCheapComputationResponse {} + +// Note: the name is a hint, but this is the de facto Operations client. +// It should _not_ generate methods with disambiguated names. +service DefactoOperationsClient { + option (google.api.default_host) = "my.example.com"; + + rpc Get(GetExpensiveComputationRequest) returns (Operation) { + option (google.cloud.operation_polling_method) = true; + option (google.api.http) = { + get: "/expensive/v1/computations/{computation}/fragments/{fragment}" + }; + } + + + rpc Delete(DeleteExpensiveComputationRequest) returns (DeleteOperationResponse) { + option (google.api.http) = { + delete: "/expensive/v1/computations/{computation}/fragments/{fragment}" + }; + + } +} + + +service DoStuff { + option (google.api.default_host) = "my.example.com"; + + rpc StartExpensiveComputation(StartExpensiveComputationRequest) returns (Operation) { + option (google.cloud.operation_service) = "DefactoOperationsClient"; + option (google.api.http) = { + post: "/expensive/v1/computations/{computation}/fragments/{fragment}" + }; + } + + rpc StartCheapComputation(StartCheapComputationRequest) returns (StartCheapComputationResponse) { + option (google.api.http) = { + post: "/expensive/v1/computations/{computation}/fragments/{fragment}"; + }; + } +} diff --git a/tests/fragments/test_flattened_value.proto b/tests/fragments/test_flattened_value.proto new file mode 100644 index 0000000000..8965b97d40 --- /dev/null +++ b/tests/fragments/test_flattened_value.proto @@ -0,0 +1,37 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/protobuf/struct.proto"; +import "google/api/client.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.method_signature) = "parameter,items"; + } +} + +message MethodRequest { + google.protobuf.Value parameter = 1; + repeated google.protobuf.Value items = 2; +} + +message MethodResponse { + string result = 1; +} diff --git a/tests/fragments/test_google_protobuf_type.proto b/tests/fragments/test_google_protobuf_type.proto new file mode 100644 index 0000000000..e9a47a1293 --- /dev/null +++ b/tests/fragments/test_google_protobuf_type.proto @@ -0,0 +1,62 @@ +// Copyright (C) 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// The purpose of this fragment test is to test for an issue found in the generated +// client for `google/api/servicemanagement/v1` where the version of a generated +// dependency (google.protobuf.type) at runtime differs from the version used during +// generation. See https://github.com/googleapis/gapic-generator-python/issues/1748. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/type.proto"; + +service MyServiceWithProtobufType { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequestWithProtobufType) + returns (MethodResponseWithProtobufType) { + option (google.api.http) = { + post: "/v1/services/{service_name}/configs/{test_message.another_message.another_field}" + body: "test_message" + }; + option (google.api.method_signature) = "service_name,test_message,another_string"; + } +} + +message MethodRequestWithProtobufType { + string service_name = 1 [(google.api.field_behavior) = REQUIRED]; + TestMessage test_message = 2 [(google.api.field_behavior) = REQUIRED]; + string another_string = 3 [(google.api.field_behavior) = REQUIRED]; +} + +message TestMessage { + string name = 1 [(google.api.field_behavior) = REQUIRED]; + repeated google.protobuf.Type types = 2 [(google.api.field_behavior) = REQUIRED]; + AnotherTestMessage another_message = 3 [(google.api.field_behavior) = REQUIRED]; +} + +message AnotherTestMessage { + string another_field = 1; +} + +message MethodResponseWithProtobufType { + google.protobuf.Value result = 1; +} diff --git a/tests/fragments/test_keyword_import.proto b/tests/fragments/test_keyword_import.proto new file mode 100644 index 0000000000..81ce44eda1 --- /dev/null +++ b/tests/fragments/test_keyword_import.proto @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "import.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + rpc MyMethod(MethodRequest) returns (MethodResponse) {} +} + +message MethodRequest { + Import import = 1; +} + +message MethodResponse { + string result = 1; +} diff --git a/tests/fragments/test_multiple_required_fields.proto b/tests/fragments/test_multiple_required_fields.proto new file mode 100644 index 0000000000..55a207b40a --- /dev/null +++ b/tests/fragments/test_multiple_required_fields.proto @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; + +service MultipleRequiredFields { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.http) = { + get: "/nomenclature/v1/kingdom/{kingdom}/phylum/{phylum}" + }; + } +} + +message MethodRequest { + string kingdom = 1 [(google.api.field_behavior) = REQUIRED]; + string phylum = 2 [(google.api.field_behavior) = REQUIRED]; + string name = 3 [(google.api.field_behavior) = REQUIRED]; + int32 armor_class = 4 [(google.api.field_behavior) = REQUIRED]; +} + +message MethodResponse{ + string text = 1; +} \ No newline at end of file diff --git a/tests/fragments/test_nested_messages.proto b/tests/fragments/test_nested_messages.proto new file mode 100644 index 0000000000..6c98cb15d2 --- /dev/null +++ b/tests/fragments/test_nested_messages.proto @@ -0,0 +1,41 @@ +// Copyright (C) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +syntax = "proto3"; + +package google.fragment; + +import "google/protobuf/struct.proto"; +import "google/api/client.proto"; + +service MyServiceWithNestedMessages { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.method_signature) = "some_message"; + } +} + +message AnotherMessage {}; + +message SomeMessage{ + AnotherMessage another_message = 1; +} + +message MethodRequest { + SomeMessage some_message = 1; +} + +message MethodResponse { + google.protobuf.Value result = 1; +} diff --git a/tests/fragments/test_non_primitive_body.proto b/tests/fragments/test_non_primitive_body.proto new file mode 100644 index 0000000000..06a16da6ff --- /dev/null +++ b/tests/fragments/test_non_primitive_body.proto @@ -0,0 +1,101 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/api/annotations.proto"; +import "google/api/field_behavior.proto"; + +service SmallCompute { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.http) = { + body: "method_body" + post: "/computation/v1/first_name/{first_name}/last_name/{last_name}" + }; + }; + + rpc EnumBody(EnumBodyRequest) returns (EnumBodyResponse) { + option (google.api.http) = { + body: "resource" + post: "/enum_body/v1/names/{name}" + }; + } + + rpc RecursiveBody(RecursiveBodyRequest) returns (RecursiveBodyResponse) { + option (google.api.http) = { + body: "resource" + post: "/recursive_body/v1/names/{name}" + }; + } +} + +message SerialNumber { + int32 number = 1; +} + +message MethodRequest { + message MethodBody { + int32 mass_kg = 1; + int32 length_cm = 2; + repeated SerialNumber serial_numbers = 3; + map word_associations = 4; + } + + string first_name = 1 [(google.api.field_behavior) = REQUIRED]; + string last_name = 2 [(google.api.field_behavior) = REQUIRED]; + MethodBody method_body = 3 [(google.api.field_behavior) = REQUIRED]; +} + +message MethodResponse { + string name = 1; +} + +message EnumBodyRequest { + message Resource{ + enum Ordering { + UNKNOWN = 0; + CHRONOLOGICAL = 1; + ALPHABETICAL = 2; + DIFFICULTY = 3; + } + + Ordering ordering = 1; + } + + string name = 1; + Resource resource = 2; +} + +message EnumBodyResponse { + string data = 1; +} + +message RecursiveBodyRequest { + message Resource { + int32 depth = 1; + Resource child_resource = 2; + } + + string name = 1; + Resource resource = 2; +} + +message RecursiveBodyResponse { + string data = 1; +} \ No newline at end of file diff --git a/tests/fragments/test_oneof_imported_response.proto b/tests/fragments/test_oneof_imported_response.proto new file mode 100644 index 0000000000..53f2a2cbd2 --- /dev/null +++ b/tests/fragments/test_oneof_imported_response.proto @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "import.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + rpc MyMethod(MethodRequest) returns (MethodResponse) {} +} + +message MethodRequest { + string input = 1; +} + +message Container { + Import import = 1; +} + +message MethodResponse { + string parent = 1; + oneof format { + Container container = 2; + string name = 3; + } +} diff --git a/tests/fragments/test_optional_signature.proto b/tests/fragments/test_optional_signature.proto new file mode 100644 index 0000000000..4789abd596 --- /dev/null +++ b/tests/fragments/test_optional_signature.proto @@ -0,0 +1,35 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.method_signature) = "parameter"; + } + +} + +message MethodRequest { + optional string parameter = 1; +} + +message MethodResponse { + string result = 1; +} diff --git a/tests/fragments/test_recursive_messages.proto b/tests/fragments/test_recursive_messages.proto new file mode 100644 index 0000000000..efe2685877 --- /dev/null +++ b/tests/fragments/test_recursive_messages.proto @@ -0,0 +1,34 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) {} +} + +message MethodRequest { + int32 depth = 1; + MethodRequest child = 2; +} + +message MethodResponse { + string result = 1; +} diff --git a/tests/fragments/test_repeated_double.proto b/tests/fragments/test_repeated_double.proto new file mode 100644 index 0000000000..63db0371b6 --- /dev/null +++ b/tests/fragments/test_repeated_double.proto @@ -0,0 +1,38 @@ +// Copyright (C) 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/protobuf/struct.proto"; +import "google/api/client.proto"; + +service MyServiceRepeatedDouble { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequestWithRepeatedDouble) returns (MethodResponseWithRepeatedDouble) { + option (google.api.method_signature) = "parameter,items"; + } +} + +message MethodRequestWithRepeatedDouble { + google.protobuf.Value parameter = 1; + repeated google.protobuf.Value items = 2; + repeated double repeated_items = 3; +} + +message MethodResponseWithRepeatedDouble { + repeated double result = 1; +} diff --git a/tests/fragments/test_required_non_string.proto b/tests/fragments/test_required_non_string.proto new file mode 100644 index 0000000000..7186a83c87 --- /dev/null +++ b/tests/fragments/test_required_non_string.proto @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/annotations.proto"; + +service RestService { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.http) = { + get: "/restservice/v1/mass_kg/{mass_kg}/length_cm/{length_cm}" + }; + } +} + + +message MethodRequest { + int32 mass_kg = 1 [(google.api.field_behavior) = REQUIRED]; + int32 length_cm = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message MethodResponse { + string name = 1; +} \ No newline at end of file diff --git a/tests/fragments/test_reserved_field_name.proto b/tests/fragments/test_reserved_field_name.proto new file mode 100644 index 0000000000..f11b3416ce --- /dev/null +++ b/tests/fragments/test_reserved_field_name.proto @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethod(MethodRequest) returns (MethodResponse) { + option (google.api.method_signature) = "from,class,import,any,license,type"; + } + +} + +message MethodRequest { + string from = 1; + string class = 2; + string import = 3; + string any = 4; + string license = 5; + string type = 6; + // Refer to PEP8 https://peps.python.org/pep-0008/#function-and-method-arguments + string self = 7; + // Refer to PEP8 https://peps.python.org/pep-0008/#function-and-method-arguments + string cls = 8; +} + +message MethodResponse { + string result = 1; +} diff --git a/tests/fragments/test_reserved_method_names.proto b/tests/fragments/test_reserved_method_names.proto new file mode 100644 index 0000000000..ba89ef0f25 --- /dev/null +++ b/tests/fragments/test_reserved_method_names.proto @@ -0,0 +1,97 @@ +// Copyright (C) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/api/annotations.proto"; +import "google/longrunning/operations.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + + rpc CreateChannel(CreateChannelRequest) returns (CreateChannelResponse) { + option (google.api.http) = { + body: "*" + post: "/channels/v1/channel/{channel}" + }; + }; + + rpc Import(CreateImportRequest) returns (CreateImportResponse) { + option (google.api.http) = { + body: "*" + post: "/import/v1" + }; + }; + + rpc GrpcChannel(GrpcChannelRequest) returns (GrpcChannelResponse) { + option (google.api.http) = { + body: "*" + post: "/channels/v1/grpc_channel/{grpc_channel}" + }; + }; + + rpc OperationsClient(OperationsClientRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + body: "*" + post: "/clients/v1/operations_clients/{operations_client}" + }; + option (google.longrunning.operation_info) = { + response_type: "google.fragment.OperationsClientResponse" + metadata_type: "google.fragment.OperationsMetadata" + }; + }; + +} + +message CreateChannelRequest { + string channel = 1; + string info = 2; +} + +message CreateChannelResponse { + string info = 1; +} + +message CreateImportRequest { + string info = 1; +} + +message CreateImportResponse { + string info = 1; +} + +message GrpcChannelRequest { + string grpc_channel = 1; + string info = 2; +} + +message GrpcChannelResponse { + string info = 1; +} + +message OperationsClientRequest { + string operations_client = 1; + string info = 2; +} + +message OperationsClientResponse { + string info = 1; +} + +message OperationsMetadata { + string data = 1; +} \ No newline at end of file diff --git a/tests/fragments/test_rest_streaming.proto b/tests/fragments/test_rest_streaming.proto new file mode 100644 index 0000000000..2055144005 --- /dev/null +++ b/tests/fragments/test_rest_streaming.proto @@ -0,0 +1,56 @@ +// Copyright (C) 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/httpbody.proto"; + +service MyService { + option (google.api.default_host) = "my.example.com"; + + rpc MyMethodApiSpecificResponse(MethodRequest) returns (stream MethodResponse) { + option (google.api.http) = { + post: "/v1/{from=projects/*}" + body: "*" + }; + option (google.api.method_signature) = "from,class,import,any,license,type"; + } + + rpc MyMethodCommonResponse(MethodRequest) returns (stream google.api.HttpBody) { + option (google.api.http) = { + post: "/v1/{from=projects/*}" + body: "*" + }; + option (google.api.method_signature) = "from,class,import,any,license,type"; + } +} + +message MethodRequest { + string from = 1; + string class = 2; + string import = 3; + string any = 4; + string license = 5; + string type = 6; + int32 page_size = 7; + string page_token = 8; +} + +message MethodResponse { + string result = 1; +} From 20e145cd71141b340e9646ffe44036ab41105386 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 1 Apr 2025 15:08:37 +0000 Subject: [PATCH 22/30] adds back the page_size proto --- .../fragments/test_pagination_page_size.proto | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/fragments/test_pagination_page_size.proto diff --git a/tests/fragments/test_pagination_page_size.proto b/tests/fragments/test_pagination_page_size.proto new file mode 100644 index 0000000000..6e15097798 --- /dev/null +++ b/tests/fragments/test_pagination_page_size.proto @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.fragment; + +import "google/api/client.proto"; +import "google/protobuf/wrappers.proto"; + +service PageSizeDatasetService { + option (google.api.default_host) = "my.example.com"; + rpc ListPageSizeDataset(ListPageSizeDatasetRequest) returns (ListPageSizeDatasetResponse) { + } +} + +message ListPageSizeDatasetRequest { + int32 page_size = 2; + string page_token = 3; +} + +message ListPageSizeDatasetResponse { + string next_page_token = 3; + repeated string datasets = 4; +} From a8c11b2c16e955be55e2d8099044a0383e085fa7 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 1 Apr 2025 16:10:27 +0000 Subject: [PATCH 23/30] adds two experimental fragments --- .../test_max_results_dataset_service.py | 1986 ++++++++++++++++ .../test_page_size_dataset_service.py | 1987 +++++++++++++++++ 2 files changed, 3973 insertions(+) create mode 100644 gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py create mode 100644 gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py diff --git a/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py b/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py new file mode 100644 index 0000000000..e3a401bcbf --- /dev/null +++ b/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py @@ -0,0 +1,1986 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceAsyncClient +from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceClient +from google.fragment.services.max_results_dataset_service import pagers +from google.fragment.services.max_results_dataset_service import transports +from google.fragment.types import test_pagination_max_results_and_wrapper +from google.oauth2 import service_account +from google.protobuf import wrappers_pb2 # type: ignore +import google.auth + + + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(None) is None + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + MaxResultsDatasetServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + MaxResultsDatasetServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert MaxResultsDatasetServiceClient._get_client_cert_source(None, False) is None + assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_default_cert_source): + assert MaxResultsDatasetServiceClient._get_client_cert_source(None, True) is mock_default_cert_source + assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) +@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE + default_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert MaxResultsDatasetServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "always") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert MaxResultsDatasetServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert MaxResultsDatasetServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert MaxResultsDatasetServiceClient._get_universe_domain(None, None) == MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + MaxResultsDatasetServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False) +]) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MaxResultsDatasetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + +@pytest.mark.parametrize("error_code", [401,403,404,500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MaxResultsDatasetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + +@pytest.mark.parametrize("client_class,transport_name", [ + (MaxResultsDatasetServiceClient, "grpc"), + (MaxResultsDatasetServiceAsyncClient, "grpc_asyncio"), + (MaxResultsDatasetServiceClient, "rest"), +]) +def test_max_results_dataset_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://my.example.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), + (transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.MaxResultsDatasetServiceRestTransport, "rest"), +]) +def test_max_results_dataset_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (MaxResultsDatasetServiceClient, "grpc"), + (MaxResultsDatasetServiceAsyncClient, "grpc_asyncio"), + (MaxResultsDatasetServiceClient, "rest"), +]) +def test_max_results_dataset_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://my.example.com' + ) + + +def test_max_results_dataset_service_client_get_transport_class(): + transport = MaxResultsDatasetServiceClient.get_transport_class() + available_transports = [ + transports.MaxResultsDatasetServiceGrpcTransport, + transports.MaxResultsDatasetServiceRestTransport, + ] + assert transport in available_transports + + transport = MaxResultsDatasetServiceClient.get_transport_class("grpc") + assert transport == transports.MaxResultsDatasetServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest"), +]) +@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) +@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) +def test_max_results_dataset_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(MaxResultsDatasetServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(MaxResultsDatasetServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", "true"), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", "false"), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", "true"), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) +@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_max_results_dataset_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + MaxResultsDatasetServiceClient, MaxResultsDatasetServiceAsyncClient +]) +@mock.patch.object(MaxResultsDatasetServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MaxResultsDatasetServiceClient)) +@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MaxResultsDatasetServiceAsyncClient)) +def test_max_results_dataset_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + MaxResultsDatasetServiceClient, MaxResultsDatasetServiceAsyncClient +]) +@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) +@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) +def test_max_results_dataset_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE + default_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest"), +]) +def test_max_results_dataset_service_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", grpc_helpers), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", None), +]) +def test_max_results_dataset_service_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_max_results_dataset_service_client_client_options_from_dict(): + with mock.patch('google.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = MaxResultsDatasetServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", grpc_helpers), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_max_results_dataset_service_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "my.example.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( +), + scopes=None, + default_host="my.example.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest, + dict, +]) +def test_list_max_results_dataset(request_type, transport: str = 'grpc'): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + ) + response = client.list_max_results_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMaxResultsDatasetPager) + assert response.next_page_token == 'next_page_token_value' + assert response.datasets == ['datasets_value'] + +# ========================================= +def test_list_my_dataset_w_max_results_set(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + max_results=4, + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + "a", + "b", + "c", + "d", + "e", + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + "f", + ], + ), + ) + + + pager = client.list_max_results_dataset(request=request) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) + + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + max_results=4, + page_token='page_token_value', + ) +# ========================================= + + +def test_list_max_results_dataset_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_max_results_dataset(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + page_token='page_token_value', + ) + +def test_list_max_results_dataset_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_max_results_dataset in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_max_results_dataset] = mock_rpc + request = {} + client.list_max_results_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_max_results_dataset(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_max_results_dataset_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_max_results_dataset in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_max_results_dataset] = mock_rpc + + request = {} + await client.list_max_results_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_max_results_dataset(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_max_results_dataset_async(transport: str = 'grpc_asyncio', request_type=test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + )) + response = await client.list_max_results_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMaxResultsDatasetAsyncPager) + assert response.next_page_token == 'next_page_token_value' + assert response.datasets == ['datasets_value'] + + +@pytest.mark.asyncio +async def test_list_max_results_dataset_async_from_dict(): + await test_list_max_results_dataset_async(request_type=dict) + + +def test_list_max_results_dataset_pager(transport_name: str = "grpc"): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + pager = client.list_max_results_dataset(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) +def test_list_max_results_dataset_pages(transport_name: str = "grpc"): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + pages = list(client.list_max_results_dataset(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_max_results_dataset_async_pager(): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_max_results_dataset(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, str) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_max_results_dataset_async_pages(): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_max_results_dataset(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_list_max_results_dataset_rest_no_http_options(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + with pytest.raises(RuntimeError): + client.list_max_results_dataset(request) + + +def test_list_max_results_dataset_rest_error(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.list_max_results_dataset({}) + assert ( + "Method ListMaxResultsDataset is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MaxResultsDatasetServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MaxResultsDatasetServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MaxResultsDatasetServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MaxResultsDatasetServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MaxResultsDatasetServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.MaxResultsDatasetServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.MaxResultsDatasetServiceGrpcTransport, + transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, + transports.MaxResultsDatasetServiceRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +def test_transport_kind_grpc(): + transport = MaxResultsDatasetServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_max_results_dataset_empty_call_grpc(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + call.return_value = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse() + client.list_max_results_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = MaxResultsDatasetServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_max_results_dataset_empty_call_grpc_asyncio(): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + )) + await client.list_max_results_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = MaxResultsDatasetServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_max_results_dataset_rest_error(): + + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + with pytest.raises(NotImplementedError) as not_implemented_error: + client.list_max_results_dataset({}) + assert ( + "Method ListMaxResultsDataset is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_initialize_client_w_rest(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_max_results_dataset_empty_call_rest(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + client.list_max_results_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.MaxResultsDatasetServiceGrpcTransport, + ) + +def test_max_results_dataset_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MaxResultsDatasetServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_max_results_dataset_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.MaxResultsDatasetServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_max_results_dataset', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_max_results_dataset_service_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.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MaxResultsDatasetServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( +), + quota_project_id="octopus", + ) + + +def test_max_results_dataset_service_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.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MaxResultsDatasetServiceTransport() + adc.assert_called_once() + + +def test_max_results_dataset_service_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) + MaxResultsDatasetServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MaxResultsDatasetServiceGrpcTransport, + transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, + ], +) +def test_max_results_dataset_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=(), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MaxResultsDatasetServiceGrpcTransport, + transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, + transports.MaxResultsDatasetServiceRestTransport, + ], +) +def test_max_results_dataset_service_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.MaxResultsDatasetServiceGrpcTransport, grpc_helpers), + (transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_max_results_dataset_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "my.example.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( +), + scopes=["1", "2"], + default_host="my.example.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) +def test_max_results_dataset_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_max_results_dataset_service_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.MaxResultsDatasetServiceRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_max_results_dataset_service_host_no_port(transport_name): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='my.example.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://my.example.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_max_results_dataset_service_host_with_port(transport_name): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='my.example.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'my.example.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://my.example.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_max_results_dataset_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MaxResultsDatasetServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MaxResultsDatasetServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_max_results_dataset._session + session2 = client2.transport.list_max_results_dataset._session + assert session1 != session2 +def test_max_results_dataset_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MaxResultsDatasetServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_max_results_dataset_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MaxResultsDatasetServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) +def test_max_results_dataset_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) +def test_max_results_dataset_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = MaxResultsDatasetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = MaxResultsDatasetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = MaxResultsDatasetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = MaxResultsDatasetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = MaxResultsDatasetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MaxResultsDatasetServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = MaxResultsDatasetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = MaxResultsDatasetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MaxResultsDatasetServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = MaxResultsDatasetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = MaxResultsDatasetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MaxResultsDatasetServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = MaxResultsDatasetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = MaxResultsDatasetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MaxResultsDatasetServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.MaxResultsDatasetServiceTransport, '_prep_wrapped_messages') as prep: + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.MaxResultsDatasetServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = MaxResultsDatasetServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = MaxResultsDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport), + (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py b/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py new file mode 100644 index 0000000000..b96bebc773 --- /dev/null +++ b/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py @@ -0,0 +1,1987 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +import grpc +from grpc.experimental import aio +from collections.abc import Iterable, AsyncIterable +from google.protobuf import json_format +import json +import math +import pytest +from google.api_core import api_core_version +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 + +try: + from google.auth.aio import credentials as ga_credentials_async + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.api_core import path_template +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceAsyncClient +from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceClient +from google.fragment.services.page_size_dataset_service import pagers +from google.fragment.services.page_size_dataset_service import transports +from google.fragment.types import test_pagination_page_size +from google.oauth2 import service_account +import google.auth + + + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(None) is None + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + +def test__read_environment_variables(): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + PageSizeDatasetServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + PageSizeDatasetServiceClient._read_environment_variables() + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", "foo.com") + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert PageSizeDatasetServiceClient._get_client_cert_source(None, False) is None + assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source + + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_default_cert_source): + assert PageSizeDatasetServiceClient._get_client_cert_source(None, True) is mock_default_cert_source + assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source + +@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) +@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = PageSizeDatasetServiceClient._DEFAULT_UNIVERSE + default_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + assert PageSizeDatasetServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override + assert PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint + assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "always") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT + assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint + assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint + + with pytest.raises(MutualTLSChannelError) as excinfo: + PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") + assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert PageSizeDatasetServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain + assert PageSizeDatasetServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env + assert PageSizeDatasetServiceClient._get_universe_domain(None, None) == PageSizeDatasetServiceClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + PageSizeDatasetServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + +@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False) +]) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PageSizeDatasetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + +@pytest.mark.parametrize("error_code", [401,403,404,500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PageSizeDatasetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + +@pytest.mark.parametrize("client_class,transport_name", [ + (PageSizeDatasetServiceClient, "grpc"), + (PageSizeDatasetServiceAsyncClient, "grpc_asyncio"), + (PageSizeDatasetServiceClient, "rest"), +]) +def test_page_size_dataset_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://my.example.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PageSizeDatasetServiceGrpcTransport, "grpc"), + (transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.PageSizeDatasetServiceRestTransport, "rest"), +]) +def test_page_size_dataset_service_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize("client_class,transport_name", [ + (PageSizeDatasetServiceClient, "grpc"), + (PageSizeDatasetServiceAsyncClient, "grpc_asyncio"), + (PageSizeDatasetServiceClient, "rest"), +]) +def test_page_size_dataset_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://my.example.com' + ) + + +def test_page_size_dataset_service_client_get_transport_class(): + transport = PageSizeDatasetServiceClient.get_transport_class() + available_transports = [ + transports.PageSizeDatasetServiceGrpcTransport, + transports.PageSizeDatasetServiceRestTransport, + ] + assert transport in available_transports + + transport = PageSizeDatasetServiceClient.get_transport_class("grpc") + assert transport == transports.PageSizeDatasetServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc"), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest"), +]) +@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) +@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) +def test_page_size_dataset_service_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(PageSizeDatasetServiceClient, 'get_transport_class') as gtc: + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(PageSizeDatasetServiceClient, 'get_transport_class') as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions(api_audience="https://language.googleapis.com") + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com" + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", "true"), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", "false"), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", "true"), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) +@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_page_size_dataset_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): + with mock.patch.object(transport_class, '__init__') as patched: + with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ + PageSizeDatasetServiceClient, PageSizeDatasetServiceAsyncClient +]) +@mock.patch.object(PageSizeDatasetServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PageSizeDatasetServiceClient)) +@mock.patch.object(PageSizeDatasetServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PageSizeDatasetServiceAsyncClient)) +def test_page_size_dataset_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): + with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + +@pytest.mark.parametrize("client_class", [ + PageSizeDatasetServiceClient, PageSizeDatasetServiceAsyncClient +]) +@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) +@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) +def test_page_size_dataset_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = PageSizeDatasetServiceClient._DEFAULT_UNIVERSE + default_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) + mock_universe = "bar.com" + mock_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): + options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + else: + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) + assert client.universe_domain == (mock_universe if universe_exists else default_universe) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc"), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest"), +]) +def test_page_size_dataset_service_client_client_options_scopes(client_class, transport_class, transport_name): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", grpc_helpers), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", None), +]) +def test_page_size_dataset_service_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + +def test_page_size_dataset_service_client_client_options_from_dict(): + with mock.patch('google.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PageSizeDatasetServiceClient( + client_options={'api_endpoint': 'squid.clam.whelk'} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", grpc_helpers), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_page_size_dataset_service_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): + # Check the case credentials file is provided. + options = client_options.ClientOptions( + credentials_file="credentials.json" + ) + + with mock.patch.object(transport_class, '__init__') as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "my.example.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( +), + scopes=None, + default_host="my.example.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + test_pagination_page_size.ListPageSizeDatasetRequest, + dict, +]) +def test_list_page_size_dataset(request_type, transport: str = 'grpc'): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = test_pagination_page_size.ListPageSizeDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + ) + response = client.list_page_size_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = test_pagination_page_size.ListPageSizeDatasetRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPageSizeDatasetPager) + assert response.next_page_token == 'next_page_token_value' + assert response.datasets == ['datasets_value'] + + +# ========================================= +def test_list_my_dataset_w_page_size_set(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_page_size.ListPageSizeDatasetRequest( + page_size=4, + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + "a", + "b", + "c", + "d", + "e", + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + "f", + ], + ), + ) + + + pager = client.list_page_size_dataset(request=request) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) + + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( + page_size=4, + page_token='page_token_value', + ) +# ========================================= + + + +def test_list_page_size_dataset_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_page_size.ListPageSizeDatasetRequest( + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client.list_page_size_dataset(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( + page_token='page_token_value', + ) + +def test_list_page_size_dataset_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_page_size_dataset in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. + client._transport._wrapped_methods[client._transport.list_page_size_dataset] = mock_rpc + request = {} + client.list_page_size_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_page_size_dataset(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_page_size_dataset_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._client._transport.list_page_size_dataset in client._client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[client._client._transport.list_page_size_dataset] = mock_rpc + + request = {} + await client.list_page_size_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_page_size_dataset(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + +@pytest.mark.asyncio +async def test_list_page_size_dataset_async(transport: str = 'grpc_asyncio', request_type=test_pagination_page_size.ListPageSizeDatasetRequest): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_page_size.ListPageSizeDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + )) + response = await client.list_page_size_dataset(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = test_pagination_page_size.ListPageSizeDatasetRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPageSizeDatasetAsyncPager) + assert response.next_page_token == 'next_page_token_value' + assert response.datasets == ['datasets_value'] + + +@pytest.mark.asyncio +async def test_list_page_size_dataset_async_from_dict(): + await test_list_page_size_dataset_async(request_type=dict) + + +def test_list_page_size_dataset_pager(transport_name: str = "grpc"): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + pager = client.list_page_size_dataset(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) +def test_list_page_size_dataset_pages(transport_name: str = "grpc"): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + pages = list(client.list_page_size_dataset(request={}).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + +@pytest.mark.asyncio +async def test_list_page_size_dataset_async_pager(): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_page_size_dataset(request={},) + assert async_pager.next_page_token == 'abc' + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, str) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_page_size_dataset_async_pages(): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + str(), + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[], + next_page_token='def', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + ], + next_page_token='ghi', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + str(), + str(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_page_size_dataset(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_list_page_size_dataset_rest_no_http_options(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = test_pagination_page_size.ListPageSizeDatasetRequest() + with pytest.raises(RuntimeError): + client.list_page_size_dataset(request) + + +def test_list_page_size_dataset_rest_error(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.list_page_size_dataset({}) + assert ( + "Method ListPageSizeDataset is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PageSizeDatasetServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PageSizeDatasetServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PageSizeDatasetServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PageSizeDatasetServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PageSizeDatasetServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PageSizeDatasetServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PageSizeDatasetServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PageSizeDatasetServiceGrpcTransport, + transports.PageSizeDatasetServiceGrpcAsyncIOTransport, + transports.PageSizeDatasetServiceRestTransport, +]) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + +def test_transport_kind_grpc(): + transport = PageSizeDatasetServiceClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_page_size_dataset_empty_call_grpc(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + call.return_value = test_pagination_page_size.ListPageSizeDatasetResponse() + client.list_page_size_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = PageSizeDatasetServiceAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_page_size_dataset_empty_call_grpc_asyncio(): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_page_size.ListPageSizeDatasetResponse( + next_page_token='next_page_token_value', + datasets=['datasets_value'], + )) + await client.list_page_size_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = PageSizeDatasetServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_list_page_size_dataset_rest_error(): + + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + + with pytest.raises(NotImplementedError) as not_implemented_error: + client.list_page_size_dataset({}) + assert ( + "Method ListPageSizeDataset is not available over REST transport" + in str(not_implemented_error.value) + ) + + +def test_initialize_client_w_rest(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_page_size_dataset_empty_call_rest(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + client.list_page_size_dataset(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PageSizeDatasetServiceGrpcTransport, + ) + +def test_page_size_dataset_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PageSizeDatasetServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_page_size_dataset_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PageSizeDatasetServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_page_size_dataset', + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + 'kind', + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_page_size_dataset_service_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.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PageSizeDatasetServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with("credentials.json", + scopes=None, + default_scopes=( +), + quota_project_id="octopus", + ) + + +def test_page_size_dataset_service_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.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PageSizeDatasetServiceTransport() + adc.assert_called_once() + + +def test_page_size_dataset_service_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) + PageSizeDatasetServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PageSizeDatasetServiceGrpcTransport, + transports.PageSizeDatasetServiceGrpcAsyncIOTransport, + ], +) +def test_page_size_dataset_service_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=(), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PageSizeDatasetServiceGrpcTransport, + transports.PageSizeDatasetServiceGrpcAsyncIOTransport, + transports.PageSizeDatasetServiceRestTransport, + ], +) +def test_page_size_dataset_service_transport_auth_gdch_credentials(transport_class): + host = 'https://language.com' + api_audience_tests = [None, 'https://language2.com'] + api_audience_expect = [host, 'https://language2.com'] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, 'default', autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with( + e + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.PageSizeDatasetServiceGrpcTransport, grpc_helpers), + (transports.PageSizeDatasetServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_page_size_dataset_service_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class( + quota_project_id="octopus", + scopes=["1", "2"] + ) + + create_channel.assert_called_with( + "my.example.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( +), + scopes=["1", "2"], + default_host="my.example.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) +def test_page_size_dataset_service_grpc_transport_client_cert_source_for_mtls( + transport_class +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, + private_key=expected_key + ) + +def test_page_size_dataset_service_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.PageSizeDatasetServiceRestTransport ( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_page_size_dataset_service_host_no_port(transport_name): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='my.example.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'my.example.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://my.example.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_page_size_dataset_service_host_with_port(transport_name): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='my.example.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'my.example.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://my.example.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_page_size_dataset_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = PageSizeDatasetServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = PageSizeDatasetServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_page_size_dataset._session + session2 = client2.transport.list_page_size_dataset._session + assert session1 != session2 +def test_page_size_dataset_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PageSizeDatasetServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_page_size_dataset_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PageSizeDatasetServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) +def test_page_size_dataset_service_transport_channel_mtls_with_client_cert_source( + transport_class +): + with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, 'default') as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) +def test_page_size_dataset_service_transport_channel_mtls_with_adc( + transport_class +): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_common_billing_account_path(): + billing_account = "squid" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PageSizeDatasetServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "clam", + } + path = PageSizeDatasetServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PageSizeDatasetServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "whelk" + expected = "folders/{folder}".format(folder=folder, ) + actual = PageSizeDatasetServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "octopus", + } + path = PageSizeDatasetServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PageSizeDatasetServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "oyster" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PageSizeDatasetServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nudibranch", + } + path = PageSizeDatasetServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PageSizeDatasetServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "cuttlefish" + expected = "projects/{project}".format(project=project, ) + actual = PageSizeDatasetServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "mussel", + } + path = PageSizeDatasetServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PageSizeDatasetServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "winkle" + location = "nautilus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = PageSizeDatasetServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "scallop", + "location": "abalone", + } + path = PageSizeDatasetServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PageSizeDatasetServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.PageSizeDatasetServiceTransport, '_prep_wrapped_messages') as prep: + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PageSizeDatasetServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PageSizeDatasetServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_grpc(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = PageSizeDatasetServiceAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio" + ) + with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest" + ) + with mock.patch.object(type(getattr(client.transport, "_session")), "close") as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + 'rest', + 'grpc', + ] + for transport in transports: + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + +@pytest.mark.parametrize("client_class,transport_class", [ + (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport), + (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport), +]) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) From 654c7af22ed3fc5dab40e1b1ad7312f9ac5a3e01 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 1 Apr 2025 18:30:54 +0000 Subject: [PATCH 24/30] updates experimental fragments --- .../unit/gapic/fragment/test_max_results.py | 64 + .../test_max_results_dataset_service.py | 1986 ---------------- .../unit/gapic/fragment/test_page_size.py | 64 + .../test_page_size_dataset_service.py | 1987 ----------------- 4 files changed, 128 insertions(+), 3973 deletions(-) create mode 100644 gf/tests/unit/gapic/fragment/test_max_results.py delete mode 100644 gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py create mode 100644 gf/tests/unit/gapic/fragment/test_page_size.py delete mode 100644 gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py diff --git a/gf/tests/unit/gapic/fragment/test_max_results.py b/gf/tests/unit/gapic/fragment/test_max_results.py new file mode 100644 index 0000000000..54dc680f07 --- /dev/null +++ b/gf/tests/unit/gapic/fragment/test_max_results.py @@ -0,0 +1,64 @@ +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from google.auth import credentials as ga_credentials + +from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceClient + +from google.fragment.types import test_pagination_max_results_and_wrapper + +# ========================================= +def test_list_my_dataset_w_max_results_set(): + client = MaxResultsDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + max_results=4, + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_max_results_dataset), + '__call__') as call: + + call.side_effect = ( + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + "a", + "b", + "c", + "d", + "e", + ], + next_page_token='abc', + ), + test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( + datasets=[ + "f", + ], + ), + ) + + + pager = client.list_max_results_dataset(request=request) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) + + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( + max_results=4, + page_token='page_token_value', + ) +# ========================================= \ No newline at end of file diff --git a/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py b/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py deleted file mode 100644 index e3a401bcbf..0000000000 --- a/gf/tests/unit/gapic/fragment/test_max_results_dataset_service.py +++ /dev/null @@ -1,1986 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -import grpc -from grpc.experimental import aio -from collections.abc import Iterable, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceAsyncClient -from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceClient -from google.fragment.services.max_results_dataset_service import pagers -from google.fragment.services.max_results_dataset_service import transports -from google.fragment.types import test_pagination_max_results_and_wrapper -from google.oauth2 import service_account -from google.protobuf import wrappers_pb2 # type: ignore -import google.auth - - - -CRED_INFO_JSON = { - "credential_source": "/path/to/file", - "credential_type": "service account credentials", - "principal": "service-account@example.com", -} -CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(None) is None - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert MaxResultsDatasetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - MaxResultsDatasetServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - MaxResultsDatasetServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert MaxResultsDatasetServiceClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert MaxResultsDatasetServiceClient._get_client_cert_source(None, False) is None - assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_default_cert_source): - assert MaxResultsDatasetServiceClient._get_client_cert_source(None, True) is mock_default_cert_source - assert MaxResultsDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) -@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE - default_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert MaxResultsDatasetServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "always") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == MaxResultsDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert MaxResultsDatasetServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - MaxResultsDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert MaxResultsDatasetServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert MaxResultsDatasetServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert MaxResultsDatasetServiceClient._get_universe_domain(None, None) == MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - MaxResultsDatasetServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [ - (401, CRED_INFO_JSON, True), - (403, CRED_INFO_JSON, True), - (404, CRED_INFO_JSON, True), - (500, CRED_INFO_JSON, False), - (401, None, False), - (403, None, False), - (404, None, False), - (500, None, False) -]) -def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): - cred = mock.Mock(["get_cred_info"]) - cred.get_cred_info = mock.Mock(return_value=cred_info_json) - client = MaxResultsDatasetServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=["foo"]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - if show_cred_info: - assert error.details == ["foo", CRED_INFO_STRING] - else: - assert error.details == ["foo"] - -@pytest.mark.parametrize("error_code", [401,403,404,500]) -def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): - cred = mock.Mock([]) - assert not hasattr(cred, "get_cred_info") - client = MaxResultsDatasetServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=[]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - assert error.details == [] - -@pytest.mark.parametrize("client_class,transport_name", [ - (MaxResultsDatasetServiceClient, "grpc"), - (MaxResultsDatasetServiceAsyncClient, "grpc_asyncio"), - (MaxResultsDatasetServiceClient, "rest"), -]) -def test_max_results_dataset_service_client_from_service_account_info(client_class, transport_name): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://my.example.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), - (transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.MaxResultsDatasetServiceRestTransport, "rest"), -]) -def test_max_results_dataset_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class,transport_name", [ - (MaxResultsDatasetServiceClient, "grpc"), - (MaxResultsDatasetServiceAsyncClient, "grpc_asyncio"), - (MaxResultsDatasetServiceClient, "rest"), -]) -def test_max_results_dataset_service_client_from_service_account_file(client_class, transport_name): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://my.example.com' - ) - - -def test_max_results_dataset_service_client_get_transport_class(): - transport = MaxResultsDatasetServiceClient.get_transport_class() - available_transports = [ - transports.MaxResultsDatasetServiceGrpcTransport, - transports.MaxResultsDatasetServiceRestTransport, - ] - assert transport in available_transports - - transport = MaxResultsDatasetServiceClient.get_transport_class("grpc") - assert transport == transports.MaxResultsDatasetServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest"), -]) -@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) -@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) -def test_max_results_dataset_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(MaxResultsDatasetServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(MaxResultsDatasetServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions(api_audience="https://language.googleapis.com") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com" - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", "true"), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", "false"), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", "true"), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", "false"), -]) -@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) -@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_max_results_dataset_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize("client_class", [ - MaxResultsDatasetServiceClient, MaxResultsDatasetServiceAsyncClient -]) -@mock.patch.object(MaxResultsDatasetServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MaxResultsDatasetServiceClient)) -@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MaxResultsDatasetServiceAsyncClient)) -def test_max_results_dataset_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - MaxResultsDatasetServiceClient, MaxResultsDatasetServiceAsyncClient -]) -@mock.patch.object(MaxResultsDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceClient)) -@mock.patch.object(MaxResultsDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(MaxResultsDatasetServiceAsyncClient)) -def test_max_results_dataset_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = MaxResultsDatasetServiceClient._DEFAULT_UNIVERSE - default_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = MaxResultsDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc"), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest"), -]) -def test_max_results_dataset_service_client_client_options_scopes(client_class, transport_class, transport_name): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", grpc_helpers), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceRestTransport, "rest", None), -]) -def test_max_results_dataset_service_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - -def test_max_results_dataset_service_client_client_options_from_dict(): - with mock.patch('google.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = MaxResultsDatasetServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport, "grpc", grpc_helpers), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_max_results_dataset_service_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "my.example.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( -), - scopes=None, - default_host="my.example.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest, - dict, -]) -def test_list_max_results_dataset(request_type, transport: str = 'grpc'): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - ) - response = client.list_max_results_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListMaxResultsDatasetPager) - assert response.next_page_token == 'next_page_token_value' - assert response.datasets == ['datasets_value'] - -# ========================================= -def test_list_my_dataset_w_max_results_set(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - max_results=4, - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - "a", - "b", - "c", - "d", - "e", - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - "f", - ], - ), - ) - - - pager = client.list_max_results_dataset(request=request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) - - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - max_results=4, - page_token='page_token_value', - ) -# ========================================= - - -def test_list_max_results_dataset_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_max_results_dataset(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - page_token='page_token_value', - ) - -def test_list_max_results_dataset_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_max_results_dataset in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_max_results_dataset] = mock_rpc - request = {} - client.list_max_results_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_max_results_dataset(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_max_results_dataset_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_max_results_dataset in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_max_results_dataset] = mock_rpc - - request = {} - await client.list_max_results_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_max_results_dataset(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_max_results_dataset_async(transport: str = 'grpc_asyncio', request_type=test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - )) - response = await client.list_max_results_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListMaxResultsDatasetAsyncPager) - assert response.next_page_token == 'next_page_token_value' - assert response.datasets == ['datasets_value'] - - -@pytest.mark.asyncio -async def test_list_max_results_dataset_async_from_dict(): - await test_list_max_results_dataset_async(request_type=dict) - - -def test_list_max_results_dataset_pager(transport_name: str = "grpc"): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - pager = client.list_max_results_dataset(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) -def test_list_max_results_dataset_pages(transport_name: str = "grpc"): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - pages = list(client.list_max_results_dataset(request={}).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.asyncio -async def test_list_max_results_dataset_async_pager(): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_max_results_dataset(request={},) - assert async_pager.next_page_token == 'abc' - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, str) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_max_results_dataset_async_pages(): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_max_results_dataset(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_list_max_results_dataset_rest_no_http_options(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - with pytest.raises(RuntimeError): - client.list_max_results_dataset(request) - - -def test_list_max_results_dataset_rest_error(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest' - ) - # Since a `google.api.http` annotation is required for using a rest transport - # method, this should error. - with pytest.raises(NotImplementedError) as not_implemented_error: - client.list_max_results_dataset({}) - assert ( - "Method ListMaxResultsDataset is not available over REST transport" - in str(not_implemented_error.value) - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = MaxResultsDatasetServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = MaxResultsDatasetServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = MaxResultsDatasetServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = MaxResultsDatasetServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = MaxResultsDatasetServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.MaxResultsDatasetServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.MaxResultsDatasetServiceGrpcTransport, - transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, - transports.MaxResultsDatasetServiceRestTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -def test_transport_kind_grpc(): - transport = MaxResultsDatasetServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_max_results_dataset_empty_call_grpc(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - call.return_value = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse() - client.list_max_results_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = MaxResultsDatasetServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_max_results_dataset_empty_call_grpc_asyncio(): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - )) - await client.list_max_results_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = MaxResultsDatasetServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_list_max_results_dataset_rest_error(): - - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - with pytest.raises(NotImplementedError) as not_implemented_error: - client.list_max_results_dataset({}) - assert ( - "Method ListMaxResultsDataset is not available over REST transport" - in str(not_implemented_error.value) - ) - - -def test_initialize_client_w_rest(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_max_results_dataset_empty_call_rest(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - client.list_max_results_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.MaxResultsDatasetServiceGrpcTransport, - ) - -def test_max_results_dataset_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.MaxResultsDatasetServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_max_results_dataset_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.MaxResultsDatasetServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'list_max_results_dataset', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Catch all for all remaining methods and properties - remainder = [ - 'kind', - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_max_results_dataset_service_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.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.MaxResultsDatasetServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( -), - quota_project_id="octopus", - ) - - -def test_max_results_dataset_service_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.fragment.services.max_results_dataset_service.transports.MaxResultsDatasetServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.MaxResultsDatasetServiceTransport() - adc.assert_called_once() - - -def test_max_results_dataset_service_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) - MaxResultsDatasetServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.MaxResultsDatasetServiceGrpcTransport, - transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, - ], -) -def test_max_results_dataset_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=(), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.MaxResultsDatasetServiceGrpcTransport, - transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, - transports.MaxResultsDatasetServiceRestTransport, - ], -) -def test_max_results_dataset_service_transport_auth_gdch_credentials(transport_class): - host = 'https://language.com' - api_audience_tests = [None, 'https://language2.com'] - api_audience_expect = [host, 'https://language2.com'] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with( - e - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.MaxResultsDatasetServiceGrpcTransport, grpc_helpers), - (transports.MaxResultsDatasetServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_max_results_dataset_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "my.example.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( -), - scopes=["1", "2"], - default_host="my.example.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) -def test_max_results_dataset_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - -def test_max_results_dataset_service_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.MaxResultsDatasetServiceRestTransport ( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_max_results_dataset_service_host_no_port(transport_name): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='my.example.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://my.example.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_max_results_dataset_service_host_with_port(transport_name): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='my.example.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'my.example.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://my.example.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_max_results_dataset_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = MaxResultsDatasetServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = MaxResultsDatasetServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.list_max_results_dataset._session - session2 = client2.transport.list_max_results_dataset._session - assert session1 != session2 -def test_max_results_dataset_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.MaxResultsDatasetServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_max_results_dataset_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.MaxResultsDatasetServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) -def test_max_results_dataset_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.MaxResultsDatasetServiceGrpcTransport, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport]) -def test_max_results_dataset_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_common_billing_account_path(): - billing_account = "squid" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = MaxResultsDatasetServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "clam", - } - path = MaxResultsDatasetServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = MaxResultsDatasetServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "whelk" - expected = "folders/{folder}".format(folder=folder, ) - actual = MaxResultsDatasetServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "octopus", - } - path = MaxResultsDatasetServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = MaxResultsDatasetServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "oyster" - expected = "organizations/{organization}".format(organization=organization, ) - actual = MaxResultsDatasetServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nudibranch", - } - path = MaxResultsDatasetServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = MaxResultsDatasetServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "cuttlefish" - expected = "projects/{project}".format(project=project, ) - actual = MaxResultsDatasetServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "mussel", - } - path = MaxResultsDatasetServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = MaxResultsDatasetServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "winkle" - location = "nautilus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = MaxResultsDatasetServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "scallop", - "location": "abalone", - } - path = MaxResultsDatasetServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = MaxResultsDatasetServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.MaxResultsDatasetServiceTransport, '_prep_wrapped_messages') as prep: - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.MaxResultsDatasetServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = MaxResultsDatasetServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = MaxResultsDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - 'rest', - 'grpc', - ] - for transport in transports: - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (MaxResultsDatasetServiceClient, transports.MaxResultsDatasetServiceGrpcTransport), - (MaxResultsDatasetServiceAsyncClient, transports.MaxResultsDatasetServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) diff --git a/gf/tests/unit/gapic/fragment/test_page_size.py b/gf/tests/unit/gapic/fragment/test_page_size.py new file mode 100644 index 0000000000..964ef9b082 --- /dev/null +++ b/gf/tests/unit/gapic/fragment/test_page_size.py @@ -0,0 +1,64 @@ +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from google.auth import credentials as ga_credentials + +from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceClient + +from google.fragment.types import test_pagination_page_size + +# ========================================= +def test_list_my_dataset_w_page_size_set(): + client = PageSizeDatasetServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='grpc', + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = test_pagination_page_size.ListPageSizeDatasetRequest( + page_size=4, + page_token='page_token_value', + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_page_size_dataset), + '__call__') as call: + + call.side_effect = ( + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + "a", + "b", + "c", + "d", + "e", + ], + next_page_token='abc', + ), + test_pagination_page_size.ListPageSizeDatasetResponse( + datasets=[ + "f", + ], + ), + ) + + + pager = client.list_page_size_dataset(request=request) + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, str) + for i in results) + + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( + page_size=4, + page_token='page_token_value', + ) +# ========================================= \ No newline at end of file diff --git a/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py b/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py deleted file mode 100644 index b96bebc773..0000000000 --- a/gf/tests/unit/gapic/fragment/test_page_size_dataset_service.py +++ /dev/null @@ -1,1987 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -import grpc -from grpc.experimental import aio -from collections.abc import Iterable, AsyncIterable -from google.protobuf import json_format -import json -import math -import pytest -from google.api_core import api_core_version -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 - -try: - from google.auth.aio import credentials as ga_credentials_async - HAS_GOOGLE_AUTH_AIO = True -except ImportError: # pragma: NO COVER - HAS_GOOGLE_AUTH_AIO = False - -from google.api_core import client_options -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers -from google.api_core import grpc_helpers_async -from google.api_core import path_template -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials -from google.auth.exceptions import MutualTLSChannelError -from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceAsyncClient -from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceClient -from google.fragment.services.page_size_dataset_service import pagers -from google.fragment.services.page_size_dataset_service import transports -from google.fragment.types import test_pagination_page_size -from google.oauth2 import service_account -import google.auth - - - -CRED_INFO_JSON = { - "credential_source": "/path/to/file", - "credential_type": "service account credentials", - "principal": "service-account@example.com", -} -CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) - - -async def mock_async_gen(data, chunk_size=1): - for i in range(0, len(data)): # pragma: NO COVER - chunk = data[i : i + chunk_size] - yield chunk.encode("utf-8") - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - -# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. -# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. -def async_anonymous_credentials(): - if HAS_GOOGLE_AUTH_AIO: - return ga_credentials_async.AnonymousCredentials() - return ga_credentials.AnonymousCredentials() - -# If default endpoint is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint(client): - return "foo.googleapis.com" if ("localhost" in client.DEFAULT_ENDPOINT) else client.DEFAULT_ENDPOINT - -# If default endpoint template is localhost, then default mtls endpoint will be the same. -# This method modifies the default endpoint template so the client can produce a different -# mtls endpoint for endpoint testing purposes. -def modify_default_endpoint_template(client): - return "test.{UNIVERSE_DOMAIN}" if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) else client._DEFAULT_ENDPOINT_TEMPLATE - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(None) is None - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint - assert PageSizeDatasetServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - -def test__read_environment_variables(): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (True, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - PageSizeDatasetServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "never", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "always", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", None) - - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - PageSizeDatasetServiceClient._read_environment_variables() - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): - assert PageSizeDatasetServiceClient._read_environment_variables() == (False, "auto", "foo.com") - -def test__get_client_cert_source(): - mock_provided_cert_source = mock.Mock() - mock_default_cert_source = mock.Mock() - - assert PageSizeDatasetServiceClient._get_client_cert_source(None, False) is None - assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, False) is None - assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, True) == mock_provided_cert_source - - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_default_cert_source): - assert PageSizeDatasetServiceClient._get_client_cert_source(None, True) is mock_default_cert_source - assert PageSizeDatasetServiceClient._get_client_cert_source(mock_provided_cert_source, "true") is mock_provided_cert_source - -@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) -@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) -def test__get_api_endpoint(): - api_override = "foo.com" - mock_client_cert_source = mock.Mock() - default_universe = PageSizeDatasetServiceClient._DEFAULT_UNIVERSE - default_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - assert PageSizeDatasetServiceClient._get_api_endpoint(api_override, mock_client_cert_source, default_universe, "always") == api_override - assert PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "auto") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "auto") == default_endpoint - assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "always") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, default_universe, "always") == PageSizeDatasetServiceClient.DEFAULT_MTLS_ENDPOINT - assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, mock_universe, "never") == mock_endpoint - assert PageSizeDatasetServiceClient._get_api_endpoint(None, None, default_universe, "never") == default_endpoint - - with pytest.raises(MutualTLSChannelError) as excinfo: - PageSizeDatasetServiceClient._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto") - assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com." - - -def test__get_universe_domain(): - client_universe_domain = "foo.com" - universe_domain_env = "bar.com" - - assert PageSizeDatasetServiceClient._get_universe_domain(client_universe_domain, universe_domain_env) == client_universe_domain - assert PageSizeDatasetServiceClient._get_universe_domain(None, universe_domain_env) == universe_domain_env - assert PageSizeDatasetServiceClient._get_universe_domain(None, None) == PageSizeDatasetServiceClient._DEFAULT_UNIVERSE - - with pytest.raises(ValueError) as excinfo: - PageSizeDatasetServiceClient._get_universe_domain("", None) - assert str(excinfo.value) == "Universe Domain cannot be an empty string." - -@pytest.mark.parametrize("error_code,cred_info_json,show_cred_info", [ - (401, CRED_INFO_JSON, True), - (403, CRED_INFO_JSON, True), - (404, CRED_INFO_JSON, True), - (500, CRED_INFO_JSON, False), - (401, None, False), - (403, None, False), - (404, None, False), - (500, None, False) -]) -def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): - cred = mock.Mock(["get_cred_info"]) - cred.get_cred_info = mock.Mock(return_value=cred_info_json) - client = PageSizeDatasetServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=["foo"]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - if show_cred_info: - assert error.details == ["foo", CRED_INFO_STRING] - else: - assert error.details == ["foo"] - -@pytest.mark.parametrize("error_code", [401,403,404,500]) -def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): - cred = mock.Mock([]) - assert not hasattr(cred, "get_cred_info") - client = PageSizeDatasetServiceClient(credentials=cred) - client._transport._credentials = cred - - error = core_exceptions.GoogleAPICallError("message", details=[]) - error.code = error_code - - client._add_cred_info_for_auth_errors(error) - assert error.details == [] - -@pytest.mark.parametrize("client_class,transport_name", [ - (PageSizeDatasetServiceClient, "grpc"), - (PageSizeDatasetServiceAsyncClient, "grpc_asyncio"), - (PageSizeDatasetServiceClient, "rest"), -]) -def test_page_size_dataset_service_client_from_service_account_info(client_class, transport_name): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_info') as factory: - factory.return_value = creds - info = {"valid": True} - client = client_class.from_service_account_info(info, transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://my.example.com' - ) - - -@pytest.mark.parametrize("transport_class,transport_name", [ - (transports.PageSizeDatasetServiceGrpcTransport, "grpc"), - (transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (transports.PageSizeDatasetServiceRestTransport, "rest"), -]) -def test_page_size_dataset_service_client_service_account_always_use_jwt(transport_class, transport_name): - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=True) - use_jwt.assert_called_once_with(True) - - with mock.patch.object(service_account.Credentials, 'with_always_use_jwt_access', create=True) as use_jwt: - creds = service_account.Credentials(None, None, None) - transport = transport_class(credentials=creds, always_use_jwt_access=False) - use_jwt.assert_not_called() - - -@pytest.mark.parametrize("client_class,transport_name", [ - (PageSizeDatasetServiceClient, "grpc"), - (PageSizeDatasetServiceAsyncClient, "grpc_asyncio"), - (PageSizeDatasetServiceClient, "rest"), -]) -def test_page_size_dataset_service_client_from_service_account_file(client_class, transport_name): - creds = ga_credentials.AnonymousCredentials() - with mock.patch.object(service_account.Credentials, 'from_service_account_file') as factory: - factory.return_value = creds - client = client_class.from_service_account_file("dummy/file/path.json", transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - client = client_class.from_service_account_json("dummy/file/path.json", transport=transport_name) - assert client.transport._credentials == creds - assert isinstance(client, client_class) - - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else - 'https://my.example.com' - ) - - -def test_page_size_dataset_service_client_get_transport_class(): - transport = PageSizeDatasetServiceClient.get_transport_class() - available_transports = [ - transports.PageSizeDatasetServiceGrpcTransport, - transports.PageSizeDatasetServiceRestTransport, - ] - assert transport in available_transports - - transport = PageSizeDatasetServiceClient.get_transport_class("grpc") - assert transport == transports.PageSizeDatasetServiceGrpcTransport - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc"), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest"), -]) -@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) -@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) -def test_page_size_dataset_service_client_client_options(client_class, transport_class, transport_name): - # Check that if channel is provided we won't create a new one. - with mock.patch.object(PageSizeDatasetServiceClient, 'get_transport_class') as gtc: - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials() - ) - client = client_class(transport=transport) - gtc.assert_not_called() - - # Check that if channel is provided via str we will create a new one. - with mock.patch.object(PageSizeDatasetServiceClient, 'get_transport_class') as gtc: - client = client_class(transport=transport_name) - gtc.assert_called() - - # Check the case api_endpoint is provided. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name, client_options=options) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is - # "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client.DEFAULT_MTLS_ENDPOINT, - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - client = client_class(transport=transport_name) - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - - # Check the case quota_project_id is provided - options = client_options.ClientOptions(quota_project_id="octopus") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id="octopus", - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - # Check the case api_endpoint is provided - options = client_options.ClientOptions(api_audience="https://language.googleapis.com") - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience="https://language.googleapis.com" - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,use_client_cert_env", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", "true"), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", "false"), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", "true"), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", "false"), -]) -@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) -@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) -@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) -def test_page_size_dataset_service_client_mtls_env_auto(client_class, transport_class, transport_name, use_client_cert_env): - # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default - # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. - - # Check the case client_cert_source is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - options = client_options.ClientOptions(client_cert_source=client_cert_source_callback) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - - if use_client_cert_env == "false": - expected_client_cert_source = None - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - else: - expected_client_cert_source = client_cert_source_callback - expected_host = client.DEFAULT_MTLS_ENDPOINT - - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case ADC client cert is provided. Whether client cert is used depends on - # GOOGLE_API_USE_CLIENT_CERTIFICATE value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=client_cert_source_callback): - if use_client_cert_env == "false": - expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE) - expected_client_cert_source = None - else: - expected_host = client.DEFAULT_MTLS_ENDPOINT - expected_client_cert_source = client_cert_source_callback - - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=expected_host, - scopes=None, - client_cert_source_for_mtls=expected_client_cert_source, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # Check the case client_cert_source and ADC client cert are not provided. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}): - with mock.patch.object(transport_class, '__init__') as patched: - with mock.patch("google.auth.transport.mtls.has_default_client_cert_source", return_value=False): - patched.return_value = None - client = client_class(transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize("client_class", [ - PageSizeDatasetServiceClient, PageSizeDatasetServiceAsyncClient -]) -@mock.patch.object(PageSizeDatasetServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PageSizeDatasetServiceClient)) -@mock.patch.object(PageSizeDatasetServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PageSizeDatasetServiceAsyncClient)) -def test_page_size_dataset_service_client_get_mtls_endpoint_and_cert_source(client_class): - mock_client_cert_source = mock.Mock() - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source == mock_client_cert_source - - # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): - mock_client_cert_source = mock.Mock() - mock_api_endpoint = "foo" - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint) - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(options) - assert api_endpoint == mock_api_endpoint - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=False): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_ENDPOINT - assert cert_source is None - - # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch('google.auth.transport.mtls.has_default_client_cert_source', return_value=True): - with mock.patch('google.auth.transport.mtls.default_client_cert_source', return_value=mock_client_cert_source): - api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() - assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - assert cert_source == mock_client_cert_source - - # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has - # unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): - with pytest.raises(MutualTLSChannelError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - - # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}): - with pytest.raises(ValueError) as excinfo: - client_class.get_mtls_endpoint_and_cert_source() - - assert str(excinfo.value) == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - -@pytest.mark.parametrize("client_class", [ - PageSizeDatasetServiceClient, PageSizeDatasetServiceAsyncClient -]) -@mock.patch.object(PageSizeDatasetServiceClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceClient)) -@mock.patch.object(PageSizeDatasetServiceAsyncClient, "_DEFAULT_ENDPOINT_TEMPLATE", modify_default_endpoint_template(PageSizeDatasetServiceAsyncClient)) -def test_page_size_dataset_service_client_client_api_endpoint(client_class): - mock_client_cert_source = client_cert_source_callback - api_override = "foo.com" - default_universe = PageSizeDatasetServiceClient._DEFAULT_UNIVERSE - default_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=default_universe) - mock_universe = "bar.com" - mock_endpoint = PageSizeDatasetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=mock_universe) - - # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", - # use ClientOptions.api_endpoint as the api endpoint regardless. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): - with mock.patch("google.auth.transport.requests.AuthorizedSession.configure_mtls_channel"): - options = client_options.ClientOptions(client_cert_source=mock_client_cert_source, api_endpoint=api_override) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == api_override - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", - # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): - client = client_class(credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT - - # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), - # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, - # and ClientOptions.universe_domain="bar.com", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. - options = client_options.ClientOptions() - universe_exists = hasattr(options, "universe_domain") - if universe_exists: - options = client_options.ClientOptions(universe_domain=mock_universe) - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - else: - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == (mock_endpoint if universe_exists else default_endpoint) - assert client.universe_domain == (mock_universe if universe_exists else default_universe) - - # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", - # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. - options = client_options.ClientOptions() - if hasattr(options, "universe_domain"): - delattr(options, "universe_domain") - with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): - client = client_class(client_options=options, credentials=ga_credentials.AnonymousCredentials()) - assert client.api_endpoint == default_endpoint - - -@pytest.mark.parametrize("client_class,transport_class,transport_name", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc"), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio"), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest"), -]) -def test_page_size_dataset_service_client_client_options_scopes(client_class, transport_class, transport_name): - # Check the case scopes are provided. - options = client_options.ClientOptions( - scopes=["1", "2"], - ) - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=["1", "2"], - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - -@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", grpc_helpers), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceRestTransport, "rest", None), -]) -def test_page_size_dataset_service_client_client_options_credentials_file(client_class, transport_class, transport_name, grpc_helpers): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - -def test_page_size_dataset_service_client_client_options_from_dict(): - with mock.patch('google.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceGrpcTransport.__init__') as grpc_transport: - grpc_transport.return_value = None - client = PageSizeDatasetServiceClient( - client_options={'api_endpoint': 'squid.clam.whelk'} - ) - grpc_transport.assert_called_once_with( - credentials=None, - credentials_file=None, - host="squid.clam.whelk", - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - -@pytest.mark.parametrize("client_class,transport_class,transport_name,grpc_helpers", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport, "grpc", grpc_helpers), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), -]) -def test_page_size_dataset_service_client_create_channel_credentials_file(client_class, transport_class, transport_name, grpc_helpers): - # Check the case credentials file is provided. - options = client_options.ClientOptions( - credentials_file="credentials.json" - ) - - with mock.patch.object(transport_class, '__init__') as patched: - patched.return_value = None - client = client_class(client_options=options, transport=transport_name) - patched.assert_called_once_with( - credentials=None, - credentials_file="credentials.json", - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) - - # test that the credentials from file are saved and used as the credentials. - with mock.patch.object( - google.auth, "load_credentials_from_file", autospec=True - ) as load_creds, mock.patch.object( - google.auth, "default", autospec=True - ) as adc, mock.patch.object( - grpc_helpers, "create_channel" - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - file_creds = ga_credentials.AnonymousCredentials() - load_creds.return_value = (file_creds, None) - adc.return_value = (creds, None) - client = client_class(client_options=options, transport=transport_name) - create_channel.assert_called_with( - "my.example.com:443", - credentials=file_creds, - credentials_file=None, - quota_project_id=None, - default_scopes=( -), - scopes=None, - default_host="my.example.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("request_type", [ - test_pagination_page_size.ListPageSizeDatasetRequest, - dict, -]) -def test_list_page_size_dataset(request_type, transport: str = 'grpc'): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = test_pagination_page_size.ListPageSizeDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - ) - response = client.list_page_size_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - request = test_pagination_page_size.ListPageSizeDatasetRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPageSizeDatasetPager) - assert response.next_page_token == 'next_page_token_value' - assert response.datasets == ['datasets_value'] - - -# ========================================= -def test_list_my_dataset_w_page_size_set(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_page_size.ListPageSizeDatasetRequest( - page_size=4, - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - "a", - "b", - "c", - "d", - "e", - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - "f", - ], - ), - ) - - - pager = client.list_page_size_dataset(request=request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) - - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( - page_size=4, - page_token='page_token_value', - ) -# ========================================= - - - -def test_list_page_size_dataset_non_empty_request_with_auto_populated_field(): - # This test is a coverage failsafe to make sure that UUID4 fields are - # automatically populated, according to AIP-4235, with non-empty requests. - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_page_size.ListPageSizeDatasetRequest( - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - call.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client.list_page_size_dataset(request=request) - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( - page_token='page_token_value', - ) - -def test_list_page_size_dataset_use_cached_wrapped_rpc(): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._transport.list_page_size_dataset in client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.Mock() - mock_rpc.return_value.name = "foo" # operation_request.operation in compute client(s) expect a string. - client._transport._wrapped_methods[client._transport.list_page_size_dataset] = mock_rpc - request = {} - client.list_page_size_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - client.list_page_size_dataset(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_page_size_dataset_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): - # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, - # instead of constructing them on each call - with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Should wrap all calls on client creation - assert wrapper_fn.call_count > 0 - wrapper_fn.reset_mock() - - # Ensure method has been cached - assert client._client._transport.list_page_size_dataset in client._client._transport._wrapped_methods - - # Replace cached wrapped function with mock - mock_rpc = mock.AsyncMock() - mock_rpc.return_value = mock.Mock() - client._client._transport._wrapped_methods[client._client._transport.list_page_size_dataset] = mock_rpc - - request = {} - await client.list_page_size_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert mock_rpc.call_count == 1 - - await client.list_page_size_dataset(request) - - # Establish that a new wrapper was not created for this call - assert wrapper_fn.call_count == 0 - assert mock_rpc.call_count == 2 - -@pytest.mark.asyncio -async def test_list_page_size_dataset_async(transport: str = 'grpc_asyncio', request_type=test_pagination_page_size.ListPageSizeDatasetRequest): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport=transport, - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = request_type() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_page_size.ListPageSizeDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - )) - response = await client.list_page_size_dataset(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) - _, args, _ = call.mock_calls[0] - request = test_pagination_page_size.ListPageSizeDatasetRequest() - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPageSizeDatasetAsyncPager) - assert response.next_page_token == 'next_page_token_value' - assert response.datasets == ['datasets_value'] - - -@pytest.mark.asyncio -async def test_list_page_size_dataset_async_from_dict(): - await test_list_page_size_dataset_async(request_type=dict) - - -def test_list_page_size_dataset_pager(transport_name: str = "grpc"): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - - expected_metadata = () - retry = retries.Retry() - timeout = 5 - pager = client.list_page_size_dataset(request={}, retry=retry, timeout=timeout) - - assert pager._metadata == expected_metadata - assert pager._retry == retry - assert pager._timeout == timeout - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) -def test_list_page_size_dataset_pages(transport_name: str = "grpc"): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport_name, - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - pages = list(client.list_page_size_dataset(request={}).pages) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - -@pytest.mark.asyncio -async def test_list_page_size_dataset_async_pager(): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - async_pager = await client.list_page_size_dataset(request={},) - assert async_pager.next_page_token == 'abc' - responses = [] - async for response in async_pager: # pragma: no branch - responses.append(response) - - assert len(responses) == 6 - assert all(isinstance(i, str) - for i in responses) - - -@pytest.mark.asyncio -async def test_list_page_size_dataset_async_pages(): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__', new_callable=mock.AsyncMock) as call: - # Set the response to a series of pages. - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - str(), - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[], - next_page_token='def', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - ], - next_page_token='ghi', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - str(), - str(), - ], - ), - RuntimeError, - ) - pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_page_size_dataset(request={}) - ).pages: - pages.append(page_) - for page_, token in zip(pages, ['abc','def','ghi', '']): - assert page_.raw_page.next_page_token == token - - -def test_list_page_size_dataset_rest_no_http_options(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - request = test_pagination_page_size.ListPageSizeDatasetRequest() - with pytest.raises(RuntimeError): - client.list_page_size_dataset(request) - - -def test_list_page_size_dataset_rest_error(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='rest' - ) - # Since a `google.api.http` annotation is required for using a rest transport - # method, this should error. - with pytest.raises(NotImplementedError) as not_implemented_error: - client.list_page_size_dataset({}) - assert ( - "Method ListPageSizeDataset is not available over REST transport" - in str(not_implemented_error.value) - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PageSizeDatasetServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - - # It is an error to provide an api_key and a transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PageSizeDatasetServiceClient( - client_options=options, - transport=transport, - ) - - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PageSizeDatasetServiceClient( - client_options=options, - credentials=ga_credentials.AnonymousCredentials() - ) - - # It is an error to provide scopes and a transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = PageSizeDatasetServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = PageSizeDatasetServiceClient(transport=transport) - assert client.transport is transport - -def test_transport_get_channel(): - # A client may be instantiated with a custom transport instance. - transport = transports.PageSizeDatasetServiceGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - - transport = transports.PageSizeDatasetServiceGrpcAsyncIOTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - channel = transport.grpc_channel - assert channel - -@pytest.mark.parametrize("transport_class", [ - transports.PageSizeDatasetServiceGrpcTransport, - transports.PageSizeDatasetServiceGrpcAsyncIOTransport, - transports.PageSizeDatasetServiceRestTransport, -]) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - -def test_transport_kind_grpc(): - transport = PageSizeDatasetServiceClient.get_transport_class("grpc")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "grpc" - - -def test_initialize_client_w_grpc(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_page_size_dataset_empty_call_grpc(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - call.return_value = test_pagination_page_size.ListPageSizeDatasetResponse() - client.list_page_size_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_kind_grpc_asyncio(): - transport = PageSizeDatasetServiceAsyncClient.get_transport_class("grpc_asyncio")( - credentials=async_anonymous_credentials() - ) - assert transport.kind == "grpc_asyncio" - - -def test_initialize_client_w_grpc_asyncio(): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -@pytest.mark.asyncio -async def test_list_page_size_dataset_empty_call_grpc_asyncio(): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - # Designate an appropriate return value for the call. - call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(test_pagination_page_size.ListPageSizeDatasetResponse( - next_page_token='next_page_token_value', - datasets=['datasets_value'], - )) - await client.list_page_size_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_kind_rest(): - transport = PageSizeDatasetServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" - - -def test_list_page_size_dataset_rest_error(): - - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - - with pytest.raises(NotImplementedError) as not_implemented_error: - client.list_page_size_dataset({}) - assert ( - "Method ListPageSizeDataset is not available over REST transport" - in str(not_implemented_error.value) - ) - - -def test_initialize_client_w_rest(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - assert client is not None - - -# This test is a coverage failsafe to make sure that totally empty calls, -# i.e. request == None and no flattened fields passed, work. -def test_list_page_size_dataset_empty_call_rest(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the actual call, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - client.list_page_size_dataset(request=None) - - # Establish that the underlying stub method was called. - call.assert_called() - _, args, _ = call.mock_calls[0] - request_msg = test_pagination_page_size.ListPageSizeDatasetRequest() - - assert args[0] == request_msg - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - ) - assert isinstance( - client.transport, - transports.PageSizeDatasetServiceGrpcTransport, - ) - -def test_page_size_dataset_service_base_transport_error(): - # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transport = transports.PageSizeDatasetServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json" - ) - - -def test_page_size_dataset_service_base_transport(): - # Instantiate the base transport. - with mock.patch('google.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport.__init__') as Transport: - Transport.return_value = None - transport = transports.PageSizeDatasetServiceTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - 'list_page_size_dataset', - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - with pytest.raises(NotImplementedError): - transport.close() - - # Catch all for all remaining methods and properties - remainder = [ - 'kind', - ] - for r in remainder: - with pytest.raises(NotImplementedError): - getattr(transport, r)() - - -def test_page_size_dataset_service_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.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PageSizeDatasetServiceTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) - load_creds.assert_called_once_with("credentials.json", - scopes=None, - default_scopes=( -), - quota_project_id="octopus", - ) - - -def test_page_size_dataset_service_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.fragment.services.page_size_dataset_service.transports.PageSizeDatasetServiceTransport._prep_wrapped_messages') as Transport: - Transport.return_value = None - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport = transports.PageSizeDatasetServiceTransport() - adc.assert_called_once() - - -def test_page_size_dataset_service_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) - PageSizeDatasetServiceClient() - adc.assert_called_once_with( - scopes=None, - default_scopes=( -), - quota_project_id=None, - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PageSizeDatasetServiceGrpcTransport, - transports.PageSizeDatasetServiceGrpcAsyncIOTransport, - ], -) -def test_page_size_dataset_service_transport_auth_adc(transport_class): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class(quota_project_id="octopus", scopes=["1", "2"]) - adc.assert_called_once_with( - scopes=["1", "2"], - default_scopes=(), - quota_project_id="octopus", - ) - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.PageSizeDatasetServiceGrpcTransport, - transports.PageSizeDatasetServiceGrpcAsyncIOTransport, - transports.PageSizeDatasetServiceRestTransport, - ], -) -def test_page_size_dataset_service_transport_auth_gdch_credentials(transport_class): - host = 'https://language.com' - api_audience_tests = [None, 'https://language2.com'] - api_audience_expect = [host, 'https://language2.com'] - for t, e in zip(api_audience_tests, api_audience_expect): - with mock.patch.object(google.auth, 'default', autospec=True) as adc: - gdch_mock = mock.MagicMock() - type(gdch_mock).with_gdch_audience = mock.PropertyMock(return_value=gdch_mock) - adc.return_value = (gdch_mock, None) - transport_class(host=host, api_audience=t) - gdch_mock.with_gdch_audience.assert_called_once_with( - e - ) - - -@pytest.mark.parametrize( - "transport_class,grpc_helpers", - [ - (transports.PageSizeDatasetServiceGrpcTransport, grpc_helpers), - (transports.PageSizeDatasetServiceGrpcAsyncIOTransport, grpc_helpers_async) - ], -) -def test_page_size_dataset_service_transport_create_channel(transport_class, grpc_helpers): - # If credentials and host are not provided, the transport class should use - # ADC credentials. - with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch.object( - grpc_helpers, "create_channel", autospec=True - ) as create_channel: - creds = ga_credentials.AnonymousCredentials() - adc.return_value = (creds, None) - transport_class( - quota_project_id="octopus", - scopes=["1", "2"] - ) - - create_channel.assert_called_with( - "my.example.com:443", - credentials=creds, - credentials_file=None, - quota_project_id="octopus", - default_scopes=( -), - scopes=["1", "2"], - default_host="my.example.com", - ssl_credentials=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - -@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) -def test_page_size_dataset_service_grpc_transport_client_cert_source_for_mtls( - transport_class -): - cred = ga_credentials.AnonymousCredentials() - - # Check ssl_channel_credentials is used if provided. - with mock.patch.object(transport_class, "create_channel") as mock_create_channel: - mock_ssl_channel_creds = mock.Mock() - transport_class( - host="squid.clam.whelk", - credentials=cred, - ssl_channel_credentials=mock_ssl_channel_creds - ) - mock_create_channel.assert_called_once_with( - "squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_channel_creds, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls - # is used. - with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): - with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: - transport_class( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - expected_cert, expected_key = client_cert_source_callback() - mock_ssl_cred.assert_called_once_with( - certificate_chain=expected_cert, - private_key=expected_key - ) - -def test_page_size_dataset_service_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.PageSizeDatasetServiceRestTransport ( - credentials=cred, - client_cert_source_for_mtls=client_cert_source_callback - ) - mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) - - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_page_size_dataset_service_host_no_port(transport_name): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='my.example.com'), - transport=transport_name, - ) - assert client.transport._host == ( - 'my.example.com:443' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://my.example.com' - ) - -@pytest.mark.parametrize("transport_name", [ - "grpc", - "grpc_asyncio", - "rest", -]) -def test_page_size_dataset_service_host_with_port(transport_name): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions(api_endpoint='my.example.com:8000'), - transport=transport_name, - ) - assert client.transport._host == ( - 'my.example.com:8000' - if transport_name in ['grpc', 'grpc_asyncio'] - else 'https://my.example.com:8000' - ) - -@pytest.mark.parametrize("transport_name", [ - "rest", -]) -def test_page_size_dataset_service_client_transport_session_collision(transport_name): - creds1 = ga_credentials.AnonymousCredentials() - creds2 = ga_credentials.AnonymousCredentials() - client1 = PageSizeDatasetServiceClient( - credentials=creds1, - transport=transport_name, - ) - client2 = PageSizeDatasetServiceClient( - credentials=creds2, - transport=transport_name, - ) - session1 = client1.transport.list_page_size_dataset._session - session2 = client2.transport.list_page_size_dataset._session - assert session1 != session2 -def test_page_size_dataset_service_grpc_transport_channel(): - channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PageSizeDatasetServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -def test_page_size_dataset_service_grpc_asyncio_transport_channel(): - channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) - - # Check that channel is used if provided. - transport = transports.PageSizeDatasetServiceGrpcAsyncIOTransport( - host="squid.clam.whelk", - channel=channel, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert transport._ssl_channel_credentials == None - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) -def test_page_size_dataset_service_transport_channel_mtls_with_client_cert_source( - transport_class -): - with mock.patch("grpc.ssl_channel_credentials", autospec=True) as grpc_ssl_channel_cred: - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - cred = ga_credentials.AnonymousCredentials() - with pytest.warns(DeprecationWarning): - with mock.patch.object(google.auth, 'default') as adc: - adc.return_value = (cred, None) - transport = transport_class( - host="squid.clam.whelk", - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - adc.assert_called_once() - - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - assert transport._ssl_channel_credentials == mock_ssl_cred - - -# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are -# removed from grpc/grpc_asyncio transport constructor. -@pytest.mark.parametrize("transport_class", [transports.PageSizeDatasetServiceGrpcTransport, transports.PageSizeDatasetServiceGrpcAsyncIOTransport]) -def test_page_size_dataset_service_transport_channel_mtls_with_adc( - transport_class -): - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - with mock.patch.object(transport_class, "create_channel") as grpc_create_channel: - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - mock_cred = mock.Mock() - - with pytest.warns(DeprecationWarning): - transport = transport_class( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=None, - ) - - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - credentials_file=None, - scopes=None, - ssl_credentials=mock_ssl_cred, - quota_project_id=None, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_common_billing_account_path(): - billing_account = "squid" - expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) - actual = PageSizeDatasetServiceClient.common_billing_account_path(billing_account) - assert expected == actual - - -def test_parse_common_billing_account_path(): - expected = { - "billing_account": "clam", - } - path = PageSizeDatasetServiceClient.common_billing_account_path(**expected) - - # Check that the path construction is reversible. - actual = PageSizeDatasetServiceClient.parse_common_billing_account_path(path) - assert expected == actual - -def test_common_folder_path(): - folder = "whelk" - expected = "folders/{folder}".format(folder=folder, ) - actual = PageSizeDatasetServiceClient.common_folder_path(folder) - assert expected == actual - - -def test_parse_common_folder_path(): - expected = { - "folder": "octopus", - } - path = PageSizeDatasetServiceClient.common_folder_path(**expected) - - # Check that the path construction is reversible. - actual = PageSizeDatasetServiceClient.parse_common_folder_path(path) - assert expected == actual - -def test_common_organization_path(): - organization = "oyster" - expected = "organizations/{organization}".format(organization=organization, ) - actual = PageSizeDatasetServiceClient.common_organization_path(organization) - assert expected == actual - - -def test_parse_common_organization_path(): - expected = { - "organization": "nudibranch", - } - path = PageSizeDatasetServiceClient.common_organization_path(**expected) - - # Check that the path construction is reversible. - actual = PageSizeDatasetServiceClient.parse_common_organization_path(path) - assert expected == actual - -def test_common_project_path(): - project = "cuttlefish" - expected = "projects/{project}".format(project=project, ) - actual = PageSizeDatasetServiceClient.common_project_path(project) - assert expected == actual - - -def test_parse_common_project_path(): - expected = { - "project": "mussel", - } - path = PageSizeDatasetServiceClient.common_project_path(**expected) - - # Check that the path construction is reversible. - actual = PageSizeDatasetServiceClient.parse_common_project_path(path) - assert expected == actual - -def test_common_location_path(): - project = "winkle" - location = "nautilus" - expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) - actual = PageSizeDatasetServiceClient.common_location_path(project, location) - assert expected == actual - - -def test_parse_common_location_path(): - expected = { - "project": "scallop", - "location": "abalone", - } - path = PageSizeDatasetServiceClient.common_location_path(**expected) - - # Check that the path construction is reversible. - actual = PageSizeDatasetServiceClient.parse_common_location_path(path) - assert expected == actual - - -def test_client_with_default_client_info(): - client_info = gapic_v1.client_info.ClientInfo() - - with mock.patch.object(transports.PageSizeDatasetServiceTransport, '_prep_wrapped_messages') as prep: - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - with mock.patch.object(transports.PageSizeDatasetServiceTransport, '_prep_wrapped_messages') as prep: - transport_class = PageSizeDatasetServiceClient.get_transport_class() - transport = transport_class( - credentials=ga_credentials.AnonymousCredentials(), - client_info=client_info, - ) - prep.assert_called_once_with(client_info) - - -def test_transport_close_grpc(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="grpc" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -@pytest.mark.asyncio -async def test_transport_close_grpc_asyncio(): - client = PageSizeDatasetServiceAsyncClient( - credentials=async_anonymous_credentials(), - transport="grpc_asyncio" - ) - with mock.patch.object(type(getattr(client.transport, "_grpc_channel")), "close") as close: - async with client: - close.assert_not_called() - close.assert_called_once() - - -def test_transport_close_rest(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest" - ) - with mock.patch.object(type(getattr(client.transport, "_session")), "close") as close: - with client: - close.assert_not_called() - close.assert_called_once() - - -def test_client_ctx(): - transports = [ - 'rest', - 'grpc', - ] - for transport in transports: - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport - ) - # Test client calls underlying transport. - with mock.patch.object(type(client.transport), "close") as close: - close.assert_not_called() - with client: - pass - close.assert_called() - -@pytest.mark.parametrize("client_class,transport_class", [ - (PageSizeDatasetServiceClient, transports.PageSizeDatasetServiceGrpcTransport), - (PageSizeDatasetServiceAsyncClient, transports.PageSizeDatasetServiceGrpcAsyncIOTransport), -]) -def test_api_key_credentials(client_class, transport_class): - with mock.patch.object( - google.auth._default, "get_api_key_credentials", create=True - ) as get_api_key_credentials: - mock_cred = mock.Mock() - get_api_key_credentials.return_value = mock_cred - options = client_options.ClientOptions() - options.api_key = "api_key" - with mock.patch.object(transport_class, "__init__") as patched: - patched.return_value = None - client = client_class(client_options=options) - patched.assert_called_once_with( - credentials=mock_cred, - credentials_file=None, - host=client._DEFAULT_ENDPOINT_TEMPLATE.format(UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE), - scopes=None, - client_cert_source_for_mtls=None, - quota_project_id=None, - client_info=transports.base.DEFAULT_CLIENT_INFO, - always_use_jwt_access=True, - api_audience=None, - ) From def14232d895129c35b39c4ff275e294cac6be42 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Wed, 2 Apr 2025 05:38:42 -0400 Subject: [PATCH 25/30] Update tests/fragments/test_pagination_max_results_and_wrapper.proto Co-authored-by: Anthonios Partheniou --- tests/fragments/test_pagination_max_results_and_wrapper.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fragments/test_pagination_max_results_and_wrapper.proto b/tests/fragments/test_pagination_max_results_and_wrapper.proto index ea2ab2d687..f305fc0e30 100644 --- a/tests/fragments/test_pagination_max_results_and_wrapper.proto +++ b/tests/fragments/test_pagination_max_results_and_wrapper.proto @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Google LLC +// Copyright (C) 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From caea510848966f05edb1fada23fe254d108bc936 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 9 Apr 2025 10:26:32 +0000 Subject: [PATCH 26/30] removes fragment proto focused solely on page_size --- .../fragments/test_pagination_page_size.proto | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 tests/fragments/test_pagination_page_size.proto diff --git a/tests/fragments/test_pagination_page_size.proto b/tests/fragments/test_pagination_page_size.proto deleted file mode 100644 index 6e15097798..0000000000 --- a/tests/fragments/test_pagination_page_size.proto +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.fragment; - -import "google/api/client.proto"; -import "google/protobuf/wrappers.proto"; - -service PageSizeDatasetService { - option (google.api.default_host) = "my.example.com"; - rpc ListPageSizeDataset(ListPageSizeDatasetRequest) returns (ListPageSizeDatasetResponse) { - } -} - -message ListPageSizeDatasetRequest { - int32 page_size = 2; - string page_token = 3; -} - -message ListPageSizeDatasetResponse { - string next_page_token = 3; - repeated string datasets = 4; -} From 42587ef3a8d907785164d4a2b5c699dcb2289326 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 9 Apr 2025 10:33:12 +0000 Subject: [PATCH 27/30] removes example fragments --- .../unit/gapic/fragment/test_max_results.py | 64 ------------------- .../unit/gapic/fragment/test_page_size.py | 64 ------------------- 2 files changed, 128 deletions(-) delete mode 100644 gf/tests/unit/gapic/fragment/test_max_results.py delete mode 100644 gf/tests/unit/gapic/fragment/test_page_size.py diff --git a/gf/tests/unit/gapic/fragment/test_max_results.py b/gf/tests/unit/gapic/fragment/test_max_results.py deleted file mode 100644 index 54dc680f07..0000000000 --- a/gf/tests/unit/gapic/fragment/test_max_results.py +++ /dev/null @@ -1,64 +0,0 @@ -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -from google.auth import credentials as ga_credentials - -from google.fragment.services.max_results_dataset_service import MaxResultsDatasetServiceClient - -from google.fragment.types import test_pagination_max_results_and_wrapper - -# ========================================= -def test_list_my_dataset_w_max_results_set(): - client = MaxResultsDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - max_results=4, - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_max_results_dataset), - '__call__') as call: - - call.side_effect = ( - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - "a", - "b", - "c", - "d", - "e", - ], - next_page_token='abc', - ), - test_pagination_max_results_and_wrapper.ListMaxResultsDatasetResponse( - datasets=[ - "f", - ], - ), - ) - - - pager = client.list_max_results_dataset(request=request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) - - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_max_results_and_wrapper.ListMaxResultsDatasetRequest( - max_results=4, - page_token='page_token_value', - ) -# ========================================= \ No newline at end of file diff --git a/gf/tests/unit/gapic/fragment/test_page_size.py b/gf/tests/unit/gapic/fragment/test_page_size.py deleted file mode 100644 index 964ef9b082..0000000000 --- a/gf/tests/unit/gapic/fragment/test_page_size.py +++ /dev/null @@ -1,64 +0,0 @@ -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - -from google.auth import credentials as ga_credentials - -from google.fragment.services.page_size_dataset_service import PageSizeDatasetServiceClient - -from google.fragment.types import test_pagination_page_size - -# ========================================= -def test_list_my_dataset_w_page_size_set(): - client = PageSizeDatasetServiceClient( - credentials=ga_credentials.AnonymousCredentials(), - transport='grpc', - ) - - # Populate all string fields in the request which are not UUID4 - # since we want to check that UUID4 are populated automatically - # if they meet the requirements of AIP 4235. - request = test_pagination_page_size.ListPageSizeDatasetRequest( - page_size=4, - page_token='page_token_value', - ) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client.transport.list_page_size_dataset), - '__call__') as call: - - call.side_effect = ( - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - "a", - "b", - "c", - "d", - "e", - ], - next_page_token='abc', - ), - test_pagination_page_size.ListPageSizeDatasetResponse( - datasets=[ - "f", - ], - ), - ) - - - pager = client.list_page_size_dataset(request=request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, str) - for i in results) - - call.assert_called() - _, args, _ = call.mock_calls[0] - assert args[0] == test_pagination_page_size.ListPageSizeDatasetRequest( - page_size=4, - page_token='page_token_value', - ) -# ========================================= \ No newline at end of file From 4459d9f8e27cff9b01d7a45e1c75e673502e9c4f Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 9 Apr 2025 10:50:38 +0000 Subject: [PATCH 28/30] git pull is filling me --- gf/tests/unit/gapic/fragment/test_max_results.py | 0 gf/tests/unit/gapic/fragment/test_page_size.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 gf/tests/unit/gapic/fragment/test_max_results.py create mode 100644 gf/tests/unit/gapic/fragment/test_page_size.py diff --git a/gf/tests/unit/gapic/fragment/test_max_results.py b/gf/tests/unit/gapic/fragment/test_max_results.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gf/tests/unit/gapic/fragment/test_page_size.py b/gf/tests/unit/gapic/fragment/test_page_size.py new file mode 100644 index 0000000000..e69de29bb2 From eb59fcd820ef711d6b86306ddf01cf677b89948e Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 9 Apr 2025 11:02:53 +0000 Subject: [PATCH 29/30] removes unneeded files --- gf/tests/unit/gapic/fragment/test_max_results.py | 0 gf/tests/unit/gapic/fragment/test_page_size.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 gf/tests/unit/gapic/fragment/test_max_results.py delete mode 100644 gf/tests/unit/gapic/fragment/test_page_size.py diff --git a/gf/tests/unit/gapic/fragment/test_max_results.py b/gf/tests/unit/gapic/fragment/test_max_results.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/gf/tests/unit/gapic/fragment/test_page_size.py b/gf/tests/unit/gapic/fragment/test_page_size.py deleted file mode 100644 index e69de29bb2..0000000000 From bace0d6734fd0ca67a5edd60fb4f48089f5f7774 Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Wed, 9 Apr 2025 13:57:36 -0400 Subject: [PATCH 30/30] Update gapic/schema/wrappers.py Co-authored-by: Anthonios Partheniou --- gapic/schema/wrappers.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gapic/schema/wrappers.py b/gapic/schema/wrappers.py index ab02a011ca..17a7832756 100644 --- a/gapic/schema/wrappers.py +++ b/gapic/schema/wrappers.py @@ -1841,12 +1841,10 @@ def _validate_paged_field_size_type(self, page_field_size) -> bool: pb_type = page_field_size.type - if pb_type == int or ( + return pb_type == int or ( isinstance(pb_type, MessageType) and pb_type.message_pb.name in {"UInt32Value", "Int32Value"} - ): - return True - return False + ) @utils.cached_property def paged_result_field(self) -> Optional[Field]: