diff --git a/karapace/protobuf/schema.py b/karapace/protobuf/schema.py index 8df162e75..a0d91b1cb 100644 --- a/karapace/protobuf/schema.py +++ b/karapace/protobuf/schema.py @@ -164,7 +164,10 @@ def _process_nested_type( if isinstance(element_type, MessageElement): for one_of in element_type.one_ofs: - process_one_of(verifier, package_name, parent_name, one_of) + # The parent name for nested one of fields is the parent and element type name. + # The field type name is handled in process_one_of function. + 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) for nested_type in element_type.nested_types: diff --git a/tests/unit/protobuf/test_dependency.py b/tests/unit/protobuf/test_dependency.py new file mode 100644 index 000000000..bc542b93c --- /dev/null +++ b/tests/unit/protobuf/test_dependency.py @@ -0,0 +1,114 @@ +""" +Copyright (c) 2023 Aiven Ltd +See LICENSE for details +""" +from karapace.protobuf.kotlin_wrapper import trim_margin +from karapace.protobuf.schema import ProtobufSchema + + +def test_nested_field_one_of_dependency(): + """The nested field may contain nested messages that are referred with one of restriction. + This test is for regression when used types are added and parent name did not include correctly + the nested `Foo`. + The full used type is `.test.FooVal.Foo.Bar`. + """ + proto = """ + |syntax = "proto3"; + |package test; + | + |option java_multiple_files = true; + |option java_string_check_utf8 = true; + |option java_outer_classname = "FooProto"; + |option java_package = "test"; + | + |// Comment + |message FooKey { + | // Comment + | string field_a = 1; + | + |} + | + |// Comment + |message FooVal { + | // Comment + | repeated Foo field_a = 1; + | + | // Comment + | string field_b = 2; + | + | // Comment + | message Foo { + | + | // Comment + | message Bar { + | // Comment + | string field_b = 1; + | } + | + | // Comment + | message Bee { + | } + | + | // Comment + | oneof packaging { + | // Comment + | Bar field_h = 2; + | + | // Comment + | Bee field_i = 3; + | } + | } + |} + """ + proto = trim_margin(proto) + pbschema = ProtobufSchema(schema=proto, references=(), dependencies=()) + deps = pbschema.verify_schema_dependencies() + assert deps.result, "Dependencies verification failed." + + +def test_one_of_dependency(): + proto = """ + |syntax = "proto3"; + |package test; + | + |option java_multiple_files = true; + |option java_string_check_utf8 = true; + |option java_outer_classname = "FooProto"; + |option java_package = "test"; + | + |// Comment + |message FooKey { + | // Comment + | string field_a = 1; + | + |} + | + |// Comment + |message FooVal { + | // Comment + | string field_b = 1; + | + | // Comment + | message Bar { + | // Comment + | string field_b = 1; + | } + | + | // Comment + | message Bee { + | } + | + | // Comment + | oneof packaging { + | // Comment + | Bar field_h = 2; + | + | // Comment + | Bee field_i = 3; + | } + |} + """ + proto = trim_margin(proto) + pbschema = ProtobufSchema(schema=proto, references=(), dependencies=()) + deps = pbschema.verify_schema_dependencies() + assert deps.result, "Dependencies verification failed."