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

Side by Side Diff: third_party/protobuf/src/google/protobuf/map_field_test.cc

Issue 1291903002: Pull new version of protobuf sources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include <map>
32 #include <memory>
33 #ifndef _SHARED_PTR_H
34 #include <google/protobuf/stubs/shared_ptr.h>
35 #endif
36
37 #include <google/protobuf/stubs/common.h>
38 #include <google/protobuf/arena.h>
39 #include <google/protobuf/map.h>
40 #include <google/protobuf/arena_test_util.h>
41 #include <google/protobuf/map_unittest.pb.h>
42 #include <google/protobuf/map_test_util.h>
43 #include <google/protobuf/unittest.pb.h>
44 #include <google/protobuf/map_field_inl.h>
45 #include <google/protobuf/message.h>
46 #include <google/protobuf/repeated_field.h>
47 #include <google/protobuf/wire_format_lite_inl.h>
48 #include <gtest/gtest.h>
49
50 namespace google {
51 namespace protobuf {
52
53 namespace internal {
54
55 using unittest::TestAllTypes;
56
57 class MapFieldBaseStub : public MapFieldBase {
58 public:
59 typedef void InternalArenaConstructable_;
60 typedef void DestructorSkippable_;
61 MapFieldBaseStub() {}
62 explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
63 void SyncRepeatedFieldWithMap() const {
64 MapFieldBase::SyncRepeatedFieldWithMap();
65 }
66 void SyncMapWithRepeatedField() const {
67 MapFieldBase::SyncMapWithRepeatedField();
68 }
69 // Get underlined repeated field without synchronizing map.
70 RepeatedPtrField<Message>* InternalRepeatedField() {
71 return repeated_field_;
72 }
73 bool IsMapClean() { return state_ != 0; }
74 bool IsRepeatedClean() { return state_ != 1; }
75 void SetMapDirty() { state_ = 0; }
76 void SetRepeatedDirty() { state_ = 1; }
77 };
78
79 class MapFieldBasePrimitiveTest : public ::testing::Test {
80 protected:
81 typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
82 WireFormatLite::TYPE_INT32, false> MapFieldType;
83
84 MapFieldBasePrimitiveTest() {
85 // Get descriptors
86 map_descriptor_ = unittest::TestMap::descriptor()
87 ->FindFieldByName("map_int32_int32")
88 ->message_type();
89 key_descriptor_ = map_descriptor_->FindFieldByName("key");
90 value_descriptor_ = map_descriptor_->FindFieldByName("value");
91
92 // Build map field
93 default_entry_ =
94 MessageFactory::generated_factory()->GetPrototype(map_descriptor_);
95 map_field_.reset(new MapFieldType(default_entry_));
96 map_field_base_ = map_field_.get();
97 map_ = map_field_->MutableMap();
98 initial_value_map_[0] = 100;
99 initial_value_map_[1] = 101;
100 map_->insert(initial_value_map_.begin(), initial_value_map_.end());
101 EXPECT_EQ(2, map_->size());
102 }
103
104 google::protobuf::scoped_ptr<MapFieldType> map_field_;
105 MapFieldBase* map_field_base_;
106 Map<int32, int32>* map_;
107 const Descriptor* map_descriptor_;
108 const FieldDescriptor* key_descriptor_;
109 const FieldDescriptor* value_descriptor_;
110 const Message* default_entry_;
111 std::map<int32, int32> initial_value_map_; // copy of initial values inserted
112 };
113
114 TEST_F(MapFieldBasePrimitiveTest, SpaceUsedExcludingSelf) {
115 EXPECT_LT(0, map_field_base_->SpaceUsedExcludingSelf());
116 }
117
118 TEST_F(MapFieldBasePrimitiveTest, GetRepeatedField) {
119 const RepeatedPtrField<Message>& repeated =
120 reinterpret_cast<const RepeatedPtrField<Message>&>(
121 map_field_base_->GetRepeatedField());
122 EXPECT_EQ(2, repeated.size());
123 for (int i = 0; i < repeated.size(); i++) {
124 const Message& message = repeated.Get(i);
125 int key = message.GetReflection()->GetInt32(message, key_descriptor_);
126 int value = message.GetReflection()->GetInt32(message, value_descriptor_);
127 EXPECT_EQ(value, initial_value_map_[key]);
128 }
129 }
130
131 TEST_F(MapFieldBasePrimitiveTest, MutableRepeatedField) {
132 RepeatedPtrField<Message>* repeated =
133 reinterpret_cast<RepeatedPtrField<Message>*>(
134 map_field_base_->MutableRepeatedField());
135 EXPECT_EQ(2, repeated->size());
136 for (int i = 0; i < repeated->size(); i++) {
137 const Message& message = repeated->Get(i);
138 int key = message.GetReflection()->GetInt32(message, key_descriptor_);
139 int value = message.GetReflection()->GetInt32(message, value_descriptor_);
140 EXPECT_EQ(value, initial_value_map_[key]);
141 }
142 }
143
144 TEST_F(MapFieldBasePrimitiveTest, Arena) {
145 // Allocate a large initial block to avoid mallocs during hooked test.
146 std::vector<char> arena_block(128 * 1024);
147 ArenaOptions options;
148 options.initial_block = &arena_block[0];
149 options.initial_block_size = arena_block.size();
150 Arena arena(options);
151
152 {
153 // TODO(liujisi): Re-write the test to ensure the memory for the map and
154 // repeated fields are allocated from arenas.
155 // NoHeapChecker no_heap;
156
157 MapFieldType* map_field =
158 Arena::CreateMessage<MapFieldType>(&arena, default_entry_);
159
160 // Set content in map
161 (*map_field->MutableMap())[100] = 101;
162
163 // Trigger conversion to repeated field.
164 map_field->GetRepeatedField();
165 }
166
167 {
168 // TODO(liujisi): Re-write the test to ensure the memory for the map and
169 // repeated fields are allocated from arenas.
170 // NoHeapChecker no_heap;
171
172 MapFieldBaseStub* map_field =
173 Arena::CreateMessage<MapFieldBaseStub>(&arena);
174
175 // Trigger conversion to repeated field.
176 EXPECT_TRUE(map_field->MutableRepeatedField() != NULL);
177 }
178 }
179
180 namespace {
181 enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
182 } // anonymous namespace
183
184 class MapFieldStateTest
185 : public testing::TestWithParam<State> {
186 public:
187 protected:
188 typedef MapField<int32, int32, WireFormatLite::TYPE_INT32,
189 WireFormatLite::TYPE_INT32, false> MapFieldType;
190 typedef MapFieldLite<int32, int32, WireFormatLite::TYPE_INT32,
191 WireFormatLite::TYPE_INT32, false> MapFieldLiteType;
192 MapFieldStateTest() : state_(GetParam()) {
193 // Build map field
194 const Descriptor* map_descriptor =
195 unittest::TestMap::descriptor()
196 ->FindFieldByName("map_int32_int32")
197 ->message_type();
198 default_entry_ =
199 MessageFactory::generated_factory()->GetPrototype(map_descriptor);
200 map_field_.reset(new MapFieldType(default_entry_));
201 map_field_base_ = map_field_.get();
202
203 Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
204 switch (state_) {
205 case CLEAN:
206 AddOneStillClean(map_field_.get());
207 break;
208 case MAP_DIRTY:
209 MakeMapDirty(map_field_.get());
210 break;
211 case REPEATED_DIRTY:
212 MakeRepeatedDirty(map_field_.get());
213 break;
214 default:
215 break;
216 }
217 }
218
219 void AddOneStillClean(MapFieldType* map_field) {
220 MapFieldBase* map_field_base = map_field;
221 Map<int32, int32>* map = map_field->MutableMap();
222 (*map)[0] = 0;
223 map_field_base->GetRepeatedField();
224 Expect(map_field, CLEAN, 1, 1, false);
225 }
226
227 void MakeMapDirty(MapFieldType* map_field) {
228 Map<int32, int32>* map = map_field->MutableMap();
229 (*map)[0] = 0;
230 Expect(map_field, MAP_DIRTY, 1, 0, true);
231 }
232
233 void MakeRepeatedDirty(MapFieldType* map_field) {
234 MakeMapDirty(map_field);
235 MapFieldBase* map_field_base = map_field;
236 map_field_base->MutableRepeatedField();
237 Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
238 ->MapFieldLiteType::MutableMap();
239 map->clear();
240
241 Expect(map_field, REPEATED_DIRTY, 0, 1, false);
242 }
243
244 void Expect(MapFieldType* map_field, State state, int map_size,
245 int repeated_size, bool is_repeated_null) {
246 MapFieldBase* map_field_base = map_field;
247 MapFieldBaseStub* stub =
248 reinterpret_cast<MapFieldBaseStub*>(map_field_base);
249
250 Map<int32, int32>* map = implicit_cast<MapFieldLiteType*>(map_field)
251 ->MapFieldLiteType::MutableMap();
252 RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
253
254 switch (state) {
255 case MAP_DIRTY:
256 EXPECT_FALSE(stub->IsMapClean());
257 EXPECT_TRUE(stub->IsRepeatedClean());
258 break;
259 case REPEATED_DIRTY:
260 EXPECT_TRUE(stub->IsMapClean());
261 EXPECT_FALSE(stub->IsRepeatedClean());
262 break;
263 case CLEAN:
264 EXPECT_TRUE(stub->IsMapClean());
265 EXPECT_TRUE(stub->IsRepeatedClean());
266 break;
267 default:
268 FAIL();
269 }
270
271 EXPECT_EQ(map_size, map->size());
272 if (is_repeated_null) {
273 EXPECT_TRUE(repeated_field == NULL);
274 } else {
275 EXPECT_EQ(repeated_size, repeated_field->size());
276 }
277 }
278
279 google::protobuf::scoped_ptr<MapFieldType> map_field_;
280 MapFieldBase* map_field_base_;
281 State state_;
282 const Message* default_entry_;
283 };
284
285 INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
286 ::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
287
288 TEST_P(MapFieldStateTest, GetMap) {
289 map_field_->GetMap();
290 if (state_ != MAP_DIRTY) {
291 Expect(map_field_.get(), CLEAN, 1, 1, false);
292 } else {
293 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
294 }
295 }
296
297 TEST_P(MapFieldStateTest, MutableMap) {
298 map_field_->MutableMap();
299 if (state_ != MAP_DIRTY) {
300 Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
301 } else {
302 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
303 }
304 }
305
306 TEST_P(MapFieldStateTest, MergeFromClean) {
307 MapFieldType other(default_entry_);
308 AddOneStillClean(&other);
309
310 map_field_->MergeFrom(other);
311
312 if (state_ != MAP_DIRTY) {
313 Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
314 } else {
315 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
316 }
317
318 Expect(&other, CLEAN, 1, 1, false);
319 }
320
321 TEST_P(MapFieldStateTest, MergeFromMapDirty) {
322 MapFieldType other(default_entry_);
323 MakeMapDirty(&other);
324
325 map_field_->MergeFrom(other);
326
327 if (state_ != MAP_DIRTY) {
328 Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
329 } else {
330 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
331 }
332
333 Expect(&other, MAP_DIRTY, 1, 0, true);
334 }
335
336 TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
337 MapFieldType other(default_entry_);
338 MakeRepeatedDirty(&other);
339
340 map_field_->MergeFrom(other);
341
342 if (state_ != MAP_DIRTY) {
343 Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
344 } else {
345 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
346 }
347
348 Expect(&other, CLEAN, 1, 1, false);
349 }
350
351 TEST_P(MapFieldStateTest, SwapClean) {
352 MapFieldType other(default_entry_);
353 AddOneStillClean(&other);
354
355 map_field_->Swap(&other);
356
357 Expect(map_field_.get(), CLEAN, 1, 1, false);
358
359 switch (state_) {
360 case CLEAN:
361 Expect(&other, CLEAN, 1, 1, false);
362 break;
363 case MAP_DIRTY:
364 Expect(&other, MAP_DIRTY, 1, 0, true);
365 break;
366 case REPEATED_DIRTY:
367 Expect(&other, REPEATED_DIRTY, 0, 1, false);
368 break;
369 default:
370 break;
371 }
372 }
373
374 TEST_P(MapFieldStateTest, SwapMapDirty) {
375 MapFieldType other(default_entry_);
376 MakeMapDirty(&other);
377
378 map_field_->Swap(&other);
379
380 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
381
382 switch (state_) {
383 case CLEAN:
384 Expect(&other, CLEAN, 1, 1, false);
385 break;
386 case MAP_DIRTY:
387 Expect(&other, MAP_DIRTY, 1, 0, true);
388 break;
389 case REPEATED_DIRTY:
390 Expect(&other, REPEATED_DIRTY, 0, 1, false);
391 break;
392 default:
393 break;
394 }
395 }
396
397 TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
398 MapFieldType other(default_entry_);
399 MakeRepeatedDirty(&other);
400
401 map_field_->Swap(&other);
402
403 Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
404
405 switch (state_) {
406 case CLEAN:
407 Expect(&other, CLEAN, 1, 1, false);
408 break;
409 case MAP_DIRTY:
410 Expect(&other, MAP_DIRTY, 1, 0, true);
411 break;
412 case REPEATED_DIRTY:
413 Expect(&other, REPEATED_DIRTY, 0, 1, false);
414 break;
415 default:
416 break;
417 }
418 }
419
420 TEST_P(MapFieldStateTest, Clear) {
421 map_field_->Clear();
422
423 if (state_ != MAP_DIRTY) {
424 Expect(map_field_.get(), MAP_DIRTY, 0, 1, false);
425 } else {
426 Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
427 }
428 }
429
430 TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
431 map_field_base_->SpaceUsedExcludingSelf();
432
433 switch (state_) {
434 case CLEAN:
435 Expect(map_field_.get(), CLEAN, 1, 1, false);
436 break;
437 case MAP_DIRTY:
438 Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
439 break;
440 case REPEATED_DIRTY:
441 Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
442 break;
443 default:
444 break;
445 }
446 }
447
448 TEST_P(MapFieldStateTest, GetMapField) {
449 map_field_base_->GetRepeatedField();
450
451 if (state_ != REPEATED_DIRTY) {
452 Expect(map_field_.get(), CLEAN, 1, 1, false);
453 } else {
454 Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
455 }
456 }
457
458 TEST_P(MapFieldStateTest, MutableMapField) {
459 map_field_base_->MutableRepeatedField();
460
461 if (state_ != REPEATED_DIRTY) {
462 Expect(map_field_.get(), REPEATED_DIRTY, 1, 1, false);
463 } else {
464 Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
465 }
466 }
467
468
469 } // namespace internal
470 } // namespace protobuf
471 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698