diff --git a/gapic/schema/api.py b/gapic/schema/api.py index ce2fdc8022..b1b1276ed8 100644 --- a/gapic/schema/api.py +++ b/gapic/schema/api.py @@ -736,12 +736,27 @@ def enforce_valid_library_settings( all_errors: dict = {} versions_seen: set = set() for library_settings in client_library_settings: - # Check if this version is defind more than once + # Check if this version is defined more than once if library_settings.version in versions_seen: all_errors[library_settings.version] = ["Duplicate version"] continue versions_seen.add(library_settings.version) + # Check to see if selective gapic generation methods are valid. + selective_gapic_errors = {} + for method_name in library_settings.python_settings.common.selective_gapic_generation.methods: + if method_name not in self.all_methods: + selective_gapic_errors[method_name] = "Method does not exist." + elif not method_name.startswith(library_settings.version): + selective_gapic_errors[method_name] = "Mismatched version for method." + + if selective_gapic_errors: + all_errors[library_settings.version] = [ + { + "selective_gapic_generation": selective_gapic_errors, + } + ] + if all_errors: raise ClientLibrarySettingsError(yaml.dump(all_errors)) diff --git a/tests/unit/schema/test_api.py b/tests/unit/schema/test_api.py index c8bf9706d3..e3403a086e 100644 --- a/tests/unit/schema/test_api.py +++ b/tests/unit/schema/test_api.py @@ -2726,6 +2726,97 @@ def test_read_python_settings_from_service_yaml(): } +def test_read_selective_gapic_methods_from_service_yaml(): + service_yaml_config = { + "apis": [ + {"name": "google.example.v1beta1.ServiceOne.Example1"}, + ], + "publishing": { + "library_settings": [ + { + "version": "google.example.v1beta1", + "python_settings": { + "experimental_features": {"rest_async_io_enabled": True}, + "common": { + "selective_gapic_generation": { + "methods": ["google.example.v1beta1.ServiceOne.Example1"] + } + } + }, + } + ] + }, + } + cli_options = Options(service_yaml_config=service_yaml_config) + fd = get_file_descriptor_proto_for_tests(fields=[]) + api_schema = api.API.build(fd, "google.example.v1beta1", opts=cli_options) + assert api_schema.all_library_settings == { + "google.example.v1beta1": client_pb2.ClientLibrarySettings( + version="google.example.v1beta1", + python_settings=client_pb2.PythonSettings( + experimental_features=client_pb2.PythonSettings.ExperimentalFeatures( + rest_async_io_enabled=True + ), + common=client_pb2.CommonLanguageSettings( + selective_gapic_generation=client_pb2.SelectiveGapicGeneration( + methods=["google.example.v1beta1.ServiceOne.Example1"] + ) + ) + ), + ) + } + + +def test_python_settings_selective_gapic_nonexistent_method_raises_error(): + """ + Test that `ClientLibrarySettingsError` is raised when there are nonexistent methods in + `client_pb2.ClientLibrarySettings.PythonSettings.CommonSettings.SelectiveGapicGeneration`. + """ + client_library_settings = [ + client_pb2.ClientLibrarySettings( + version="google.example.v1beta1", + python_settings=client_pb2.PythonSettings( + common=client_pb2.CommonLanguageSettings( + selective_gapic_generation=client_pb2.SelectiveGapicGeneration( + methods=["google.example.v1beta1.ServiceOne.DoesNotExist"] + ) + ) + ) + ) + ] + fd = get_file_descriptor_proto_for_tests(fields=[]) + api_schema = api.API.build(fd, "google.example.v1beta1") + with pytest.raises( + api.ClientLibrarySettingsError, match="(?i)google.example.v1beta1.ServiceOne.DoesNotExist: Method does not exist" + ): + api_schema.enforce_valid_library_settings(client_library_settings) + + +def test_python_settings_selective_gapic_version_mismatch_method_raises_error(): + """ + Test that `ClientLibrarySettingsError` is raised when there are nonexistent methods in + `client_pb2.ClientLibrarySettings.PythonSettings.CommonSettings.SelectiveGapicGeneration`. + """ + client_library_settings = [ + client_pb2.ClientLibrarySettings( + version="google.example.v2beta2", + python_settings=client_pb2.PythonSettings( + common=client_pb2.CommonLanguageSettings( + selective_gapic_generation=client_pb2.SelectiveGapicGeneration( + methods=["google.example.v1beta1.ServiceOne.Example1"] + ) + ) + ) + ) + ] + fd = get_file_descriptor_proto_for_tests(fields=[]) + api_schema = api.API.build(fd, "google.example.v1beta1") + with pytest.raises( + api.ClientLibrarySettingsError, match="(?i)google.example.v1beta1.ServiceOne.Example1: Mismatched version for method." + ): + api_schema.enforce_valid_library_settings(client_library_settings) + + def test_read_empty_python_settings_from_service_yaml(): service_yaml_config = { "apis": [