mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Fixes #27472
Closes #27473
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27473 from iblancasa:27472 0ab662a73b
PiperOrigin-RevId: 929221750
124 lines
3.9 KiB
Python
124 lines
3.9 KiB
Python
# Protocol Buffers - Google's data interchange format
|
|
# Copyright 2008 Google Inc. All rights reserved.
|
|
#
|
|
# Use of this source code is governed by a BSD-style
|
|
# license that can be found in the LICENSE file or at
|
|
# https://developers.google.com/open-source/licenses/bsd
|
|
|
|
"""Tests for google.protobuf.proto_builder."""
|
|
|
|
import collections
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from google.protobuf import descriptor
|
|
from google.protobuf import descriptor_pb2
|
|
from google.protobuf import descriptor_pool
|
|
from google.protobuf import proto_builder
|
|
from google.protobuf import text_format
|
|
from google.protobuf.internal import api_implementation
|
|
|
|
|
|
class ProtoBuilderTest(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
self.ordered_fields = collections.OrderedDict([
|
|
('foo', descriptor_pb2.FieldDescriptorProto.TYPE_INT64),
|
|
('bar', descriptor_pb2.FieldDescriptorProto.TYPE_STRING),
|
|
])
|
|
self._fields = dict(self.ordered_fields)
|
|
|
|
def testMakeSimpleProtoClass(self):
|
|
"""Test that we can create a proto class."""
|
|
proto_cls = proto_builder.MakeSimpleProtoClass(
|
|
self._fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.Test',
|
|
)
|
|
proto = proto_cls()
|
|
proto.foo = 12345
|
|
proto.bar = 'asdf'
|
|
self.assertMultiLineEqual(
|
|
'bar: "asdf"\nfoo: 12345\n', text_format.MessageToString(proto)
|
|
)
|
|
|
|
def testOrderedFields(self):
|
|
"""Test that the field order is maintained when given an OrderedDict."""
|
|
proto_cls = proto_builder.MakeSimpleProtoClass(
|
|
self.ordered_fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.OrderedTest',
|
|
)
|
|
proto = proto_cls()
|
|
proto.foo = 12345
|
|
proto.bar = 'asdf'
|
|
self.assertMultiLineEqual(
|
|
'foo: 12345\nbar: "asdf"\n', text_format.MessageToString(proto)
|
|
)
|
|
|
|
def testMakeSameProtoClassTwice(self):
|
|
"""Test that the DescriptorPool is used."""
|
|
pool = descriptor_pool.DescriptorPool()
|
|
proto_cls1 = proto_builder.MakeSimpleProtoClass(
|
|
self._fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.Test',
|
|
pool=pool,
|
|
)
|
|
proto_cls2 = proto_builder.MakeSimpleProtoClass(
|
|
self._fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.Test',
|
|
pool=pool,
|
|
)
|
|
self.assertIs(proto_cls1.DESCRIPTOR, proto_cls2.DESCRIPTOR)
|
|
|
|
def testMakeSimpleProtoClassUsesNonSecuritySha1(self):
|
|
pool = descriptor_pool.DescriptorPool()
|
|
with mock.patch.object(
|
|
proto_builder.hashlib,
|
|
'sha1',
|
|
wraps=proto_builder.hashlib.sha1,
|
|
) as sha1:
|
|
proto_builder.MakeSimpleProtoClass(
|
|
self._fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.Sha1Test',
|
|
pool=pool,
|
|
)
|
|
|
|
sha1.assert_called_once_with(usedforsecurity=False)
|
|
|
|
def testMakeLargeProtoClass(self):
|
|
"""Test that large created protos don't use reserved field numbers."""
|
|
num_fields = 65000
|
|
fields = {
|
|
'foo%d' % i: descriptor_pb2.FieldDescriptorProto.TYPE_INT64
|
|
for i in range(num_fields)
|
|
}
|
|
if api_implementation.Type() == 'upb':
|
|
with self.assertRaisesRegex(
|
|
TypeError, "Couldn't build proto file into descriptor pool"
|
|
):
|
|
proto_cls = proto_builder.MakeSimpleProtoClass(
|
|
fields,
|
|
full_name=(
|
|
'net.proto2.python.public.proto_builder_test.LargeProtoTest'
|
|
),
|
|
)
|
|
return
|
|
|
|
proto_cls = proto_builder.MakeSimpleProtoClass(
|
|
fields,
|
|
full_name='net.proto2.python.public.proto_builder_test.LargeProtoTest',
|
|
)
|
|
|
|
reserved_field_numbers = set(
|
|
range(
|
|
descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER,
|
|
descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER + 1,
|
|
)
|
|
)
|
|
proto_field_numbers = set(proto_cls.DESCRIPTOR.fields_by_number)
|
|
self.assertFalse(reserved_field_numbers.intersection(proto_field_numbers))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|