Skip to content

Commit

Permalink
fix: enable self-referencing schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
eliax1996 committed Sep 18, 2023
1 parent a33b4e1 commit 462a93e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
14 changes: 10 additions & 4 deletions karapace/protobuf/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def add_used_type(self, parent: str, element_type: str) -> None:
end = element_type.find(">")
virgule = element_type.find(",")
key = element_type[4:virgule]
value = element_type[virgule + 1 : end]
value = element_type[virgule + 1: end]
value = value.strip()
self.used_types.append(parent + ";" + key)
self.used_types.append(parent + ";" + value)
Expand All @@ -39,10 +39,14 @@ def verify(self) -> DependencyVerifierResult:
declared_index = set(self.declared_types)
for used_type in self.used_types:
delimiter = used_type.rfind(";")
father_child_type = None
used_type_with_scope = ""
if delimiter != -1:
used_type_with_scope = used_type[:delimiter] + "." + used_type[delimiter + 1 :]
used_type = used_type[delimiter + 1 :]
used_type_with_scope = used_type[:delimiter] + "." + used_type[delimiter + 1:]
father_delimiter = used_type[:delimiter].find(".")
if father_delimiter != -1:
father_child_type = used_type[:father_delimiter] + "." + used_type[delimiter + 1:]
used_type = used_type[delimiter + 1:]

if used_type in DependenciesHardcoded.index:
continue
Expand All @@ -54,6 +58,7 @@ def verify(self) -> DependencyVerifierResult:
if (
used_type in declared_index
or (delimiter != -1 and used_type_with_scope in declared_index)
or (father_child_type is not None and father_child_type in declared_index)
or "." + used_type in declared_index
):
continue
Expand All @@ -63,7 +68,8 @@ def verify(self) -> DependencyVerifierResult:
return DependencyVerifierResult(True)


def process_one_of(verifier: ProtobufDependencyVerifier, package_name: str, parent_name: str, one_of: OneOfElement) -> None:
def process_one_of(verifier: ProtobufDependencyVerifier, package_name: str, parent_name: str,
one_of: OneOfElement) -> None:
parent = package_name + "." + parent_name
for field in one_of.fields:
verifier.add_used_type(parent, field.element_type)
2 changes: 1 addition & 1 deletion karapace/protobuf/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def _process_nested_type(
one_of_parent_name = parent_name + "." + element_type.name
process_one_of(verifier, package_name, one_of_parent_name, one_of)
for field in element_type.fields:
verifier.add_used_type(parent_name, field.element_type)
verifier.add_used_type(parent_name, field.element_type)
for nested_type in element_type.nested_types:
self._process_nested_type(verifier, package_name, parent_name + "." + element_type.name, nested_type)

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_schema_protobuf.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ class ReferenceTestCase(BaseTestCase):
"""



@pytest.mark.parametrize(
"testcase",
[
Expand Down Expand Up @@ -999,7 +1000,6 @@ async def test_references(testcase: ReferenceTestCase, registry_async_client: Cl
fetch_schema_res = await registry_async_client.get(f"/schemas/ids/{testdata.schema_id}")
assert fetch_schema_res.status_code == 200


async def test_protobuf_error(registry_async_client: Client) -> None:
testdata = TestCaseSchema(
schema_type=SchemaType.PROTOBUF,
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/protobuf/test_protobuf_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,44 @@ def test_protobuf_field_compatible_alter_to_oneof():
protobuf_schema1.compare(protobuf_schema2, result)

assert result.is_compatible()

def test_protobuf_self_referencing_schema():
proto1 = """\
syntax = "proto3";
package fancy.company.in.party.v1;
message MyFirstMessage {
string my_fancy_string = 1;
}
message AnotherMessage {
message WowANestedMessage {
enum BamFancyEnum {
// Hei! This is a comment!
MY_AWESOME_FIELD = 0;
}
BamFancyEnum im_tricky_im_referring_to_the_previous_enum = 1;
}
}
"""

assert type(ValidatedTypedSchema.parse(SchemaType.PROTOBUF, proto1).schema) == ProtobufSchema


proto2 ="""\
syntax = "proto3";
package fancy.company.in.party.v1;
message AnotherMessage {
enum BamFancyEnum {
// Hei! This is a comment!
MY_AWESOME_FIELD = 0;
}
message WowANestedMessage {
message DeeplyNestedMsg {
BamFancyEnum im_tricky_im_referring_to_the_previous_enum = 1;
}
}
}
"""

assert type(ValidatedTypedSchema.parse(SchemaType.PROTOBUF, proto2).schema) == ProtobufSchema

0 comments on commit 462a93e

Please sign in to comment.