diff --git a/packages/gapic-generator/gapic/schema/api.py b/packages/gapic-generator/gapic/schema/api.py index 4ee478a64398..bdb8031d147b 100644 --- a/packages/gapic-generator/gapic/schema/api.py +++ b/packages/gapic-generator/gapic/schema/api.py @@ -169,10 +169,16 @@ def resource_messages(self) -> Mapping[str, wrappers.MessageType]: for msg in self.messages.values() if msg.options.Extensions[resource_pb2.resource].type ) + + # Convert the set to a sorted tuple using the resource path or message name. + # This is needed to prevent non-deterministic code generation. return collections.OrderedDict( - itertools.chain( - file_resource_messages, - resource_messages, + sorted( + itertools.chain( + file_resource_messages, + resource_messages, + ), + key=lambda item: item[0] ) ) diff --git a/packages/gapic-generator/gapic/schema/wrappers.py b/packages/gapic-generator/gapic/schema/wrappers.py index f654d0a82d18..ce74043798e2 100644 --- a/packages/gapic-generator/gapic/schema/wrappers.py +++ b/packages/gapic-generator/gapic/schema/wrappers.py @@ -2278,7 +2278,7 @@ def names(self) -> FrozenSet[str]: return frozenset(answer) @utils.cached_property - def resource_messages(self) -> FrozenSet[MessageType]: + def resource_messages(self) -> Sequence['MessageType']: """Returns all the resource message types used in all request and response fields in the service.""" @@ -2301,7 +2301,7 @@ def gen_indirect_resources_used(message): if resource: yield resource - return frozenset( + unique_messages = frozenset( msg for method in self.methods.values() for msg in chain( @@ -2316,6 +2316,15 @@ def gen_indirect_resources_used(message): ) ) + # Convert the set to a sorted tuple using the resource path or message name. + # This is needed to prevent non-deterministic code generation. + sorted_messages = sorted( + unique_messages, + key=lambda m: m.resource_type_full_path or m.name + ) + + return tuple(sorted_messages) + @utils.cached_property def resource_messages_dict(self) -> Dict[str, MessageType]: """Returns a dict from resource reference to diff --git a/packages/gapic-generator/tests/unit/schema/test_api.py b/packages/gapic-generator/tests/unit/schema/test_api.py index 9d2dab2ec6a1..9d94e8251523 100644 --- a/packages/gapic-generator/tests/unit/schema/test_api.py +++ b/packages/gapic-generator/tests/unit/schema/test_api.py @@ -1740,17 +1740,17 @@ def test_file_level_resources(): expected = collections.OrderedDict( ( ( - "nomenclature.linnaen.com/Species", + "nomenclature.linnaen.com/Phylum", wrappers.CommonResource( - type_name="nomenclature.linnaen.com/Species", - pattern="families/{family}/genera/{genus}/species/{species}", + type_name="nomenclature.linnaen.com/Phylum", + pattern="kingdoms/{kingdom}/phyla/{phylum}", ).message_type, ), ( - "nomenclature.linnaen.com/Phylum", + "nomenclature.linnaen.com/Species", wrappers.CommonResource( - type_name="nomenclature.linnaen.com/Phylum", - pattern="kingdoms/{kingdom}/phyla/{phylum}", + type_name="nomenclature.linnaen.com/Species", + pattern="families/{family}/genera/{genus}/species/{species}", ).message_type, ), ) @@ -1767,7 +1767,7 @@ def test_file_level_resources(): # The service doesn't own any method that owns a message that references # Phylum, so the service doesn't count it among its resource messages. expected.pop("nomenclature.linnaen.com/Phylum") - expected = frozenset(expected.values()) + expected = tuple(expected.values()) actual = service.resource_messages assert actual == expected @@ -1822,7 +1822,7 @@ def test_resources_referenced_but_not_typed(reference_attr="type"): name_resource_opts.child_type = species_resource_opts.type api_schema = api.API.build([fdp], package="nomenclature.linneaen.v1") - expected = {api_schema.messages["nomenclature.linneaen.v1.Species"]} + expected = (api_schema.messages["nomenclature.linneaen.v1.Species"],) actual = api_schema.services[ "nomenclature.linneaen.v1.SpeciesService" ].resource_messages diff --git a/packages/gapic-generator/tests/unit/schema/wrappers/test_service.py b/packages/gapic-generator/tests/unit/schema/wrappers/test_service.py index eb54577b2e51..04f7ac7308ea 100644 --- a/packages/gapic-generator/tests/unit/schema/wrappers/test_service.py +++ b/packages/gapic-generator/tests/unit/schema/wrappers/test_service.py @@ -267,12 +267,12 @@ def test_resource_messages(): ), ) - expected = { - squid_resource, + expected = ( clam_resource, - whelk_resource, squamosa_message, - } + squid_resource, + whelk_resource, + ) actual = service.resource_messages assert expected == actual @@ -557,7 +557,7 @@ def test_resource_response(): ), ) - expected = {squid_resource, clam_resource} + expected = (clam_resource, squid_resource) actual = mollusc_service.resource_messages assert expected == actual