Skip to content

Commit aa43c83

Browse files
authored
chore: sort resource messages for deterministic generation (#16756)
sort resource messages for deterministic generation. Towards b/505425328
1 parent 6614d4c commit aa43c83

4 files changed

Lines changed: 33 additions & 18 deletions

File tree

packages/gapic-generator/gapic/schema/api.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,16 @@ def resource_messages(self) -> Mapping[str, wrappers.MessageType]:
169169
for msg in self.messages.values()
170170
if msg.options.Extensions[resource_pb2.resource].type
171171
)
172+
173+
# Convert the set to a sorted tuple using the resource path or message name.
174+
# This is needed to prevent non-deterministic code generation.
172175
return collections.OrderedDict(
173-
itertools.chain(
174-
file_resource_messages,
175-
resource_messages,
176+
sorted(
177+
itertools.chain(
178+
file_resource_messages,
179+
resource_messages,
180+
),
181+
key=lambda item: item[0]
176182
)
177183
)
178184

packages/gapic-generator/gapic/schema/wrappers.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,7 +2278,7 @@ def names(self) -> FrozenSet[str]:
22782278
return frozenset(answer)
22792279

22802280
@utils.cached_property
2281-
def resource_messages(self) -> FrozenSet[MessageType]:
2281+
def resource_messages(self) -> Sequence['MessageType']:
22822282
"""Returns all the resource message types used in all
22832283
request and response fields in the service."""
22842284

@@ -2301,7 +2301,7 @@ def gen_indirect_resources_used(message):
23012301
if resource:
23022302
yield resource
23032303

2304-
return frozenset(
2304+
unique_messages = frozenset(
23052305
msg
23062306
for method in self.methods.values()
23072307
for msg in chain(
@@ -2316,6 +2316,15 @@ def gen_indirect_resources_used(message):
23162316
)
23172317
)
23182318

2319+
# Convert the set to a sorted tuple using the resource path or message name.
2320+
# This is needed to prevent non-deterministic code generation.
2321+
sorted_messages = sorted(
2322+
unique_messages,
2323+
key=lambda m: m.resource_type_full_path or m.name
2324+
)
2325+
2326+
return tuple(sorted_messages)
2327+
23192328
@utils.cached_property
23202329
def resource_messages_dict(self) -> Dict[str, MessageType]:
23212330
"""Returns a dict from resource reference to

packages/gapic-generator/tests/unit/schema/test_api.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,17 +1740,17 @@ def test_file_level_resources():
17401740
expected = collections.OrderedDict(
17411741
(
17421742
(
1743-
"nomenclature.linnaen.com/Species",
1743+
"nomenclature.linnaen.com/Phylum",
17441744
wrappers.CommonResource(
1745-
type_name="nomenclature.linnaen.com/Species",
1746-
pattern="families/{family}/genera/{genus}/species/{species}",
1745+
type_name="nomenclature.linnaen.com/Phylum",
1746+
pattern="kingdoms/{kingdom}/phyla/{phylum}",
17471747
).message_type,
17481748
),
17491749
(
1750-
"nomenclature.linnaen.com/Phylum",
1750+
"nomenclature.linnaen.com/Species",
17511751
wrappers.CommonResource(
1752-
type_name="nomenclature.linnaen.com/Phylum",
1753-
pattern="kingdoms/{kingdom}/phyla/{phylum}",
1752+
type_name="nomenclature.linnaen.com/Species",
1753+
pattern="families/{family}/genera/{genus}/species/{species}",
17541754
).message_type,
17551755
),
17561756
)
@@ -1767,7 +1767,7 @@ def test_file_level_resources():
17671767
# The service doesn't own any method that owns a message that references
17681768
# Phylum, so the service doesn't count it among its resource messages.
17691769
expected.pop("nomenclature.linnaen.com/Phylum")
1770-
expected = frozenset(expected.values())
1770+
expected = tuple(expected.values())
17711771
actual = service.resource_messages
17721772

17731773
assert actual == expected
@@ -1822,7 +1822,7 @@ def test_resources_referenced_but_not_typed(reference_attr="type"):
18221822
name_resource_opts.child_type = species_resource_opts.type
18231823

18241824
api_schema = api.API.build([fdp], package="nomenclature.linneaen.v1")
1825-
expected = {api_schema.messages["nomenclature.linneaen.v1.Species"]}
1825+
expected = (api_schema.messages["nomenclature.linneaen.v1.Species"],)
18261826
actual = api_schema.services[
18271827
"nomenclature.linneaen.v1.SpeciesService"
18281828
].resource_messages

packages/gapic-generator/tests/unit/schema/wrappers/test_service.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,12 @@ def test_resource_messages():
267267
),
268268
)
269269

270-
expected = {
271-
squid_resource,
270+
expected = (
272271
clam_resource,
273-
whelk_resource,
274272
squamosa_message,
275-
}
273+
squid_resource,
274+
whelk_resource,
275+
)
276276
actual = service.resource_messages
277277
assert expected == actual
278278

@@ -557,7 +557,7 @@ def test_resource_response():
557557
),
558558
)
559559

560-
expected = {squid_resource, clam_resource}
560+
expected = (clam_resource, squid_resource)
561561
actual = mollusc_service.resource_messages
562562
assert expected == actual
563563

0 commit comments

Comments
 (0)