aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/extension_set_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/extension_set_unittest.cc')
-rw-r--r--src/google/protobuf/extension_set_unittest.cc133
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(