Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(622)

Unified Diff: third_party/protobuf/src/google/protobuf/map_field_test.cc

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/map_field_test.cc
diff --git a/third_party/protobuf/src/google/protobuf/map_field_test.cc b/third_party/protobuf/src/google/protobuf/map_field_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2ff1d6bbc4f0a0cf9077b2aa588aa007052508de
--- /dev/null
+++ b/third_party/protobuf/src/google/protobuf/map_field_test.cc
@@ -0,0 +1,494 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/map.h>
+#include <google/protobuf/arena_test_util.h>
+#include <google/protobuf/map_unittest.pb.h>
+#include <google/protobuf/map_test_util.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/map_field_inl.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+using unittest::TestAllTypes;
+
+class MapFieldBaseStub : public MapFieldBase {
+ public:
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
+ MapFieldBaseStub() {}
+ explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
+ void SyncRepeatedFieldWithMap() const {
+ MapFieldBase::SyncRepeatedFieldWithMap();
+ }
+ void SyncMapWithRepeatedField() const {
+ MapFieldBase::SyncMapWithRepeatedField();
+ }
+ // Get underlined repeated field without synchronizing map.
+ RepeatedPtrField<Message>* InternalRepeatedField() {
+ return repeated_field_;
+ }
+ bool IsMapClean() { return state_ != 0; }
+ bool IsRepeatedClean() { return state_ != 1; }
+ void SetMapDirty() { state_ = 0; }
+ void SetRepeatedDirty() { state_ = 1; }
+ bool ContainsMapKey(const MapKey& map_key) const {
+ return false;
+ }
+ bool InsertMapValue(const MapKey& map_key, MapValueRef* val) {
+ return false;
+ }
+ bool DeleteMapValue(const MapKey& map_key) {
+ return false;
+ }
+ bool EqualIterator(const MapIterator& a, const MapIterator& b) const {
+ return false;
+ }
+ int size() const { return 0; }
+ void MapBegin(MapIterator* map_iter) const {}
+ void MapEnd(MapIterator* map_iter) const {}
+ void InitializeIterator(MapIterator* map_iter) const {}
+ void DeleteIterator(MapIterator* map_iter) const {}
+ void CopyIterator(MapIterator* this_iterator,
+ const MapIterator& other_iterator) const {}
+ void IncreaseIterator(MapIterator* map_iter) const {}
+ void SetDefaultMessageEntry(const Message* message) const {}
+ const Message* GetDefaultMessageEntry() const { return NULL; }
+};
+
+class MapFieldBasePrimitiveTest : public ::testing::Test {
+ protected:
+ typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
+ WireFormatLite::TYPE_INT32, false> MapFieldType;
+
+ MapFieldBasePrimitiveTest() {
+ // Get descriptors
+ map_descriptor_ = unittest::TestMap::descriptor()
+ ->FindFieldByName("map_int32_int32")
+ ->message_type();
+ key_descriptor_ = map_descriptor_->FindFieldByName("key");
+ value_descriptor_ = map_descriptor_->FindFieldByName("value");
+
+ // Build map field
+ default_entry_ =
+ MessageFactory::generated_factory()->GetPrototype(map_descriptor_);
+ map_field_.reset(new MapFieldType(default_entry_));
+ map_field_base_ = map_field_.get();
+ map_ = map_field_->MutableMap();
+ initial_value_map_[0] = 100;
+ initial_value_map_[1] = 101;
+ map_->insert(initial_value_map_.begin(), initial_value_map_.end());
+ EXPECT_EQ(2, map_->size());
+ }
+
+ google::protobuf::scoped_ptr<MapFieldType> map_field_;
+ MapFieldBase* map_field_base_;
+ Map<int32, int32>* map_;
+ const Descriptor* map_descriptor_;
+ const FieldDescriptor* key_descriptor_;
+ const FieldDescriptor* value_descriptor_;
+ const Message* default_entry_;
+ std::map<int32, int32> initial_value_map_; // copy of initial values inserted
+};
+
+TEST_F(MapFieldBasePrimitiveTest, SpaceUsedExcludingSelf) {
+ EXPECT_LT(0, map_field_base_->SpaceUsedExcludingSelf());
+}
+
+TEST_F(MapFieldBasePrimitiveTest, GetRepeatedField) {
+ const RepeatedPtrField<Message>& repeated =
+ reinterpret_cast<const RepeatedPtrField<Message>&>(
+ map_field_base_->GetRepeatedField());
+ EXPECT_EQ(2, repeated.size());
+ for (int i = 0; i < repeated.size(); i++) {
+ const Message& message = repeated.Get(i);
+ int key = message.GetReflection()->GetInt32(message, key_descriptor_);
+ int value = message.GetReflection()->GetInt32(message, value_descriptor_);
+ EXPECT_EQ(value, initial_value_map_[key]);
+ }
+}
+
+TEST_F(MapFieldBasePrimitiveTest, MutableRepeatedField) {
+ RepeatedPtrField<Message>* repeated =
+ reinterpret_cast<RepeatedPtrField<Message>*>(
+ map_field_base_->MutableRepeatedField());
+ EXPECT_EQ(2, repeated->size());
+ for (int i = 0; i < repeated->size(); i++) {
+ const Message& message = repeated->Get(i);
+ int key = message.GetReflection()->GetInt32(message, key_descriptor_);
+ int value = message.GetReflection()->GetInt32(message, value_descriptor_);
+ EXPECT_EQ(value, initial_value_map_[key]);
+ }
+}
+
+TEST_F(MapFieldBasePrimitiveTest, Arena) {
+ // Allocate a large initial block to avoid mallocs during hooked test.
+ std::vector<char> arena_block(128 * 1024);
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+
+ {
+ // TODO(liujisi): Re-write the test to ensure the memory for the map and
+ // repeated fields are allocated from arenas.
+ // NoHeapChecker no_heap;
+
+ MapFieldType* map_field =
+ Arena::CreateMessage<MapFieldType>(&arena, default_entry_);
+
+ // Set content in map
+ (*map_field->MutableMap())[100] = 101;
+
+ // Trigger conversion to repeated field.
+ map_field->GetRepeatedField();
+ }
+
+ {
+ // TODO(liujisi): Re-write the test to ensure the memory for the map and
+ // repeated fields are allocated from arenas.
+ // NoHeapChecker no_heap;
+
+ MapFieldBaseStub* map_field =
+ Arena::CreateMessage<MapFieldBaseStub>(&arena);
+
+ // Trigger conversion to repeated field.
+ EXPECT_TRUE(map_field->MutableRepeatedField() != NULL);
+ }
+}
+
+namespace {
+enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
+} // anonymous namespace
+
+class MapFieldStateTest
+ : public testing::TestWithParam<State> {
+ public:
+ protected:
+ typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
+ WireFormatLite::TYPE_INT32, false> MapFieldType;
+ typedef MapFieldLite<int32, int32, WireFormatLite::TYPE_INT32,
+ WireFormatLite::TYPE_INT32, false> MapFieldLiteType;
+ MapFieldStateTest() : state_(GetParam()) {
+ // Build map field
+ const Descriptor* map_descriptor =
+ unittest::TestMap::descriptor()
+ ->FindFieldByName("map_int32_int32")
+ ->message_type();
+ default_entry_ =
+ MessageFactory::generated_factory()->GetPrototype(map_descriptor);
+ map_field_.reset(new MapFieldType(default_entry_));
+ map_field_base_ = map_field_.get();
+
+ Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
+ switch (state_) {
+ case CLEAN:
+ AddOneStillClean(map_field_.get());
+ break;
+ case MAP_DIRTY:
+ MakeMapDirty(map_field_.get());
+ break;
+ case REPEATED_DIRTY:
+ MakeRepeatedDirty(map_field_.get());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AddOneStillClean(MapFieldType* map_field) {
+ MapFieldBase* map_field_base = map_field;
+ Map<int32, int32>* map = map_field->MutableMap();
+ (*map)[0] = 0;
+ map_field_base->GetRepeatedField();
+ Expect(map_field, CLEAN, 1, 1, false);
+ }
+
+ void MakeMapDirty(MapFieldType* map_field) {
+ Map<int32, int32>* map = map_field->MutableMap();
+ (*map)[0] = 0;
+ Expect(map_field, MAP_DIRTY, 1, 0, true);
+ }
+
+ void MakeRepeatedDirty(MapFieldType* map_field) {
+ MakeMapDirty(map_field);
+ MapFieldBase* map_field_base = map_field;
+ map_field_base->MutableRepeatedField();
+ Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
+ ->MapFieldLiteType::MutableMap();
+ map->clear();
+
+ Expect(map_field, REPEATED_DIRTY, 0, 1, false);
+ }
+
+ void Expect(MapFieldType* map_field, State state, int map_size,
+ int repeated_size, bool is_repeated_null) {
+ MapFieldBase* map_field_base = map_field;
+ MapFieldBaseStub* stub =
+ reinterpret_cast<MapFieldBaseStub*>(map_field_base);
+
+ Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
+ ->MapFieldLiteType::MutableMap();
+ RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
+
+ switch (state) {
+ case MAP_DIRTY:
+ EXPECT_FALSE(stub->IsMapClean());
+ EXPECT_TRUE(stub->IsRepeatedClean());
+ break;
+ case REPEATED_DIRTY:
+ EXPECT_TRUE(stub->IsMapClean());
+ EXPECT_FALSE(stub->IsRepeatedClean());
+ break;
+ case CLEAN:
+ EXPECT_TRUE(stub->IsMapClean());
+ EXPECT_TRUE(stub->IsRepeatedClean());
+ break;
+ default:
+ FAIL();
+ }
+
+ EXPECT_EQ(map_size, map->size());
+ if (is_repeated_null) {
+ EXPECT_TRUE(repeated_field == NULL);
+ } else {
+ EXPECT_EQ(repeated_size, repeated_field->size());
+ }
+ }
+
+ google::protobuf::scoped_ptr<MapFieldType> map_field_;
+ MapFieldBase* map_field_base_;
+ State state_;
+ const Message* default_entry_;
+};
+
+INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
+ ::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
+
+TEST_P(MapFieldStateTest, GetMap) {
+ map_field_->GetMap();
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+}
+
+TEST_P(MapFieldStateTest, MutableMap) {
+ map_field_->MutableMap();
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+}
+
+TEST_P(MapFieldStateTest, MergeFromClean) {
+ MapFieldType other(default_entry_);
+ AddOneStillClean(&other);
+
+ map_field_->MergeFrom(other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(&other, CLEAN, 1, 1, false);
+}
+
+TEST_P(MapFieldStateTest, MergeFromMapDirty) {
+ MapFieldType other(default_entry_);
+ MakeMapDirty(&other);
+
+ map_field_->MergeFrom(other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(&other, MAP_DIRTY, 1, 0, true);
+}
+
+TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
+ MapFieldType other(default_entry_);
+ MakeRepeatedDirty(&other);
+
+ map_field_->MergeFrom(other);
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ }
+
+ Expect(&other, CLEAN, 1, 1, false);
+}
+
+TEST_P(MapFieldStateTest, SwapClean) {
+ MapFieldType other(default_entry_);
+ AddOneStillClean(&other);
+
+ map_field_->Swap(&other);
+
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(&other, CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(&other, MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(&other, REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, SwapMapDirty) {
+ MapFieldType other(default_entry_);
+ MakeMapDirty(&other);
+
+ map_field_->Swap(&other);
+
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(&other, CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(&other, MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(&other, REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
+ MapFieldType other(default_entry_);
+ MakeRepeatedDirty(&other);
+
+ map_field_->Swap(&other);
+
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+
+ switch (state_) {
+ case CLEAN:
+ Expect(&other, CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(&other, MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(&other, REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, Clear) {
+ map_field_->Clear();
+
+ if (state_ != MAP_DIRTY) {
+ Expect(map_field_.get(), MAP_DIRTY, 0, 1, false);
+ } else {
+ Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
+ }
+}
+
+TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
+ map_field_base_->SpaceUsedExcludingSelf();
+
+ switch (state_) {
+ case CLEAN:
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ break;
+ case MAP_DIRTY:
+ Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
+ break;
+ case REPEATED_DIRTY:
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ break;
+ default:
+ break;
+ }
+}
+
+TEST_P(MapFieldStateTest, GetMapField) {
+ map_field_base_->GetRepeatedField();
+
+ if (state_ != REPEATED_DIRTY) {
+ Expect(map_field_.get(), CLEAN, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ }
+}
+
+TEST_P(MapFieldStateTest, MutableMapField) {
+ map_field_base_->MutableRepeatedField();
+
+ if (state_ != REPEATED_DIRTY) {
+ Expect(map_field_.get(), REPEATED_DIRTY, 1, 1, false);
+ } else {
+ Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
+ }
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google

Powered by Google App Engine
This is Rietveld 408576698