diff options
Diffstat (limited to 'src/google/protobuf/extension_set_unittest.cc')
-rw-r--r-- | src/google/protobuf/extension_set_unittest.cc | 133 |
1 files changed, 114 insertions, 19 deletions
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index f40fcbc2..bc65d295 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -32,21 +32,23 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include <google/protobuf/extension_set.h> +#include <google/protobuf/stubs/casts.h> + +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/test_util.h> #include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest_mset.pb.h> -#include <google/protobuf/test_util.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/arena.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/dynamic_message.h> +#include <google/protobuf/extension_set.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> #include <google/protobuf/stubs/stl_util.h> @@ -205,6 +207,74 @@ TEST(ExtensionSetTest, ReleaseExtension) { delete released_extension; } +TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) { + ::google::protobuf::Arena arena; + unittest::TestAllExtensions* message = + ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena); + unittest::ForeignMessage extension; + message->UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + &extension); + // No copy when set. + unittest::ForeignMessage* mutable_extension = + message->MutableExtension(unittest::optional_foreign_message_extension); + EXPECT_EQ(&extension, mutable_extension); + // No copy when unsafe released. + unittest::ForeignMessage* released_extension = + message->UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(&extension, released_extension); + EXPECT_FALSE(message->HasExtension( + unittest::optional_foreign_message_extension)); + // Set the ownership back and let the destructors run. It should not take + // ownership, so this should not crash. + message->UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + &extension); +} + +TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) { + unittest::TestAllExtensions message; + unittest::ForeignMessage* extension = new unittest::ForeignMessage(); + message.UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); + // No copy when set. + unittest::ForeignMessage* mutable_extension = + message.MutableExtension(unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, mutable_extension); + // No copy when unsafe released. + unittest::ForeignMessage* released_extension = + message.UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, released_extension); + EXPECT_FALSE(message.HasExtension( + unittest::optional_foreign_message_extension)); + // Set the ownership back and let the destructors run. It should take + // ownership, so this should not leak. + message.UnsafeArenaSetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); +} + +TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) { + ::google::protobuf::Arena arena; + unittest::TestAllExtensions* message = + ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena); + unittest::ForeignMessage* extension = new unittest::ForeignMessage; + message->SetAllocatedExtension( + unittest::optional_foreign_message_extension, + extension); + // The arena should maintain ownership of the heap allocated proto because we + // used UnsafeArenaReleaseExtension. The leak checker will ensure this. + unittest::ForeignMessage* released_extension = + message->UnsafeArenaReleaseExtension( + unittest::optional_foreign_message_extension); + EXPECT_EQ(extension, released_extension); + EXPECT_FALSE(message->HasExtension( + unittest::optional_foreign_message_extension)); +} + TEST(ExtensionSetTest, CopyFrom) { unittest::TestAllExtensions message1, message2; @@ -216,7 +286,7 @@ TEST(ExtensionSetTest, CopyFrom) { TestUtil::ExpectAllExtensionsSet(message2); } -TEST(ExtensioSetTest, CopyFromPacked) { +TEST(ExtensionSetTest, CopyFromPacked) { unittest::TestPackedExtensions message1, message2; TestUtil::SetPackedExtensions(&message1); @@ -263,7 +333,7 @@ TEST(ExtensionSetTest, SwapExtension) { unittest::TestAllExtensions message2; TestUtil::SetAllExtensions(&message1); - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; // Swap empty fields. const Reflection* reflection = message1.GetReflection(); @@ -295,7 +365,7 @@ TEST(ExtensionSetTest, SwapExtensionWithEmpty) { TestUtil::SetAllExtensions(&message3); const Reflection* reflection = message3.GetReflection(); - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; reflection->ListFields(message3, &fields); reflection->SwapFields(&message1, &message2, fields); @@ -312,7 +382,7 @@ TEST(ExtensionSetTest, SwapExtensionBothFull) { TestUtil::SetAllExtensions(&message2); const Reflection* reflection = message1.GetReflection(); - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; reflection->ListFields(message1, &fields); reflection->SwapFields(&message1, &message2, fields); @@ -375,7 +445,7 @@ TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) { TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) { ::google::protobuf::Arena arena1; - google::protobuf::scoped_ptr<google::protobuf::Arena> arena2(new ::google::protobuf::Arena()); + std::unique_ptr<google::protobuf::Arena> arena2(new ::google::protobuf::Arena()); unittest::TestAllExtensions* message1 = Arena::CreateMessage<unittest::TestAllExtensions>(&arena1); @@ -422,7 +492,7 @@ TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) { TestUtil::SetAllExtensions(message2); const Reflection* reflection = message1->GetReflection(); - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; reflection->ListFields(*message1, &fields); reflection->SwapFields(message1, message2, fields); TestUtil::ExpectAllExtensionsSet(*message1); @@ -436,7 +506,7 @@ TEST(ExtensionSetTest, SwapExtensionWithSelf) { TestUtil::SetAllExtensions(&message1); - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; const Reflection* reflection = message1.GetReflection(); reflection->ListFields(message1, &fields); reflection->SwapFields(&message1, &message1, fields); @@ -532,6 +602,26 @@ TEST(ExtensionSetTest, PackedSerializationToStream) { TestUtil::ExpectPackedFieldsSet(destination); } +TEST(ExtensionSetTest, NestedExtensionGroup) { + // Serialize as TestGroup and parse as TestGroupExtension. + unittest::TestGroup source; + unittest::TestGroupExtension destination; + string data; + + source.mutable_optionalgroup()->set_a(117); + source.set_optional_foreign_enum(unittest::FOREIGN_BAZ); + source.SerializeToString(&data); + EXPECT_TRUE(destination.ParseFromString(data)); + EXPECT_TRUE(destination.GetExtension( + unittest::TestNestedExtension::optionalgroup_extension).has_a()); + EXPECT_EQ(117, destination.GetExtension( + unittest::TestNestedExtension::optionalgroup_extension).a()); + EXPECT_TRUE(destination.HasExtension( + unittest::TestNestedExtension::optional_foreign_enum_extension)); + EXPECT_EQ(unittest::FOREIGN_BAZ, destination.GetExtension( + unittest::TestNestedExtension::optional_foreign_enum_extension)); +} + TEST(ExtensionSetTest, Parsing) { // Serialize as TestAllTypes and parse as TestAllExtensions. unittest::TestAllTypes source; @@ -723,12 +813,17 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { message.AddExtension(unittest::repeated_##type##_extension, value); \ EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \ message.ClearExtension(unittest::repeated_##type##_extension); \ + const int old_capacity = \ + message.GetRepeatedExtension(unittest::repeated_##type##_extension) \ + .Capacity(); \ + EXPECT_GE(old_capacity, kMinRepeatedFieldAllocationSize); \ for (int i = 0; i < 16; ++i) { \ message.AddExtension(unittest::repeated_##type##_extension, value); \ } \ - int expected_size = sizeof(cpptype) * (16 - \ - kMinRepeatedFieldAllocationSize) + empty_repeated_field_size; \ - EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \ + int expected_size = sizeof(cpptype) * \ + (message.GetRepeatedExtension(unittest::repeated_##type##_extension) \ + .Capacity() - old_capacity) + empty_repeated_field_size; \ + EXPECT_LE(expected_size, message.SpaceUsed()) << #type; \ } while (0) TEST_REPEATED_EXTENSIONS_SPACE_USED(int32 , int32 , 101); @@ -924,8 +1019,8 @@ TEST(ExtensionSetTest, RepeatedFields) { ASSERT_EQ(110, SumAllExtensions<double>( message, unittest::repeated_double_extension, 0)); - RepeatedPtrField< ::std::string>::iterator string_iter; - RepeatedPtrField< ::std::string>::iterator string_end; + RepeatedPtrField<::std::string>::iterator string_iter; + RepeatedPtrField<::std::string>::iterator string_end; for (string_iter = message.MutableRepeatedExtension( unittest::repeated_string_extension)->begin(), string_end = message.MutableRepeatedExtension( @@ -933,8 +1028,8 @@ TEST(ExtensionSetTest, RepeatedFields) { string_iter != string_end; ++string_iter) { *string_iter += "test"; } - RepeatedPtrField< ::std::string>::const_iterator string_const_iter; - RepeatedPtrField< ::std::string>::const_iterator string_const_end; + RepeatedPtrField<::std::string>::const_iterator string_const_iter; + RepeatedPtrField<::std::string>::const_iterator string_const_end; for (string_const_iter = message.GetRepeatedExtension( unittest::repeated_string_extension).begin(), string_const_end = message.GetRepeatedExtension( |