1 // Copyright (c) 2010, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // map_serializers_unittest.cc: Unit tests for std::map serializer and
31 // std::map wrapper serializers.
32 //
33 // Author: Siyang Xie (lambxsy@google.com)
34
35 #include <climits>
36 #include <map>
37 #include <string>
38 #include <utility>
39 #include <iostream>
40 #include <sstream>
41
42 #include "breakpad_googletest_includes.h"
43 #include "map_serializers-inl.h"
44
45 #include "processor/address_map-inl.h"
46 #include "processor/range_map-inl.h"
47 #include "processor/contained_range_map-inl.h"
48
49 typedef int32_t AddrType;
50 typedef int32_t EntryType;
51
52 class TestStdMapSerializer : public ::testing::Test {
53 protected:
SetUp()54 void SetUp() {
55 serialized_size_ = 0;
56 serialized_data_ = NULL;
57 }
58
TearDown()59 void TearDown() {
60 delete [] serialized_data_;
61 }
62
63 std::map<AddrType, EntryType> std_map_;
64 google_breakpad::StdMapSerializer<AddrType, EntryType> serializer_;
65 uint32_t serialized_size_;
66 char *serialized_data_;
67 };
68
TEST_F(TestStdMapSerializer,EmptyMapTestCase)69 TEST_F(TestStdMapSerializer, EmptyMapTestCase) {
70 const int32_t correct_data[] = { 0 };
71 uint32_t correct_size = sizeof(correct_data);
72
73 // std_map_ is empty.
74 serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_);
75
76 EXPECT_EQ(correct_size, serialized_size_);
77 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
78 }
79
TEST_F(TestStdMapSerializer,MapWithTwoElementsTestCase)80 TEST_F(TestStdMapSerializer, MapWithTwoElementsTestCase) {
81 const int32_t correct_data[] = {
82 // # of nodes
83 2,
84 // Offsets
85 20, 24,
86 // Keys
87 1, 3,
88 // Values
89 2, 6
90 };
91 uint32_t correct_size = sizeof(correct_data);
92
93 std_map_.insert(std::make_pair(1, 2));
94 std_map_.insert(std::make_pair(3, 6));
95
96 serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_);
97
98 EXPECT_EQ(correct_size, serialized_size_);
99 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
100 }
101
TEST_F(TestStdMapSerializer,MapWithFiveElementsTestCase)102 TEST_F(TestStdMapSerializer, MapWithFiveElementsTestCase) {
103 const int32_t correct_data[] = {
104 // # of nodes
105 5,
106 // Offsets
107 44, 48, 52, 56, 60,
108 // Keys
109 1, 2, 3, 4, 5,
110 // Values
111 11, 12, 13, 14, 15
112 };
113 uint32_t correct_size = sizeof(correct_data);
114
115 for (int i = 1; i < 6; ++i)
116 std_map_.insert(std::make_pair(i, 10 + i));
117
118 serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_);
119
120 EXPECT_EQ(correct_size, serialized_size_);
121 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
122 }
123
124 class TestAddressMapSerializer : public ::testing::Test {
125 protected:
SetUp()126 void SetUp() {
127 serialized_size_ = 0;
128 serialized_data_ = 0;
129 }
130
TearDown()131 void TearDown() {
132 delete [] serialized_data_;
133 }
134
135 google_breakpad::AddressMap<AddrType, EntryType> address_map_;
136 google_breakpad::AddressMapSerializer<AddrType, EntryType> serializer_;
137 uint32_t serialized_size_;
138 char *serialized_data_;
139 };
140
TEST_F(TestAddressMapSerializer,EmptyMapTestCase)141 TEST_F(TestAddressMapSerializer, EmptyMapTestCase) {
142 const int32_t correct_data[] = { 0 };
143 uint32_t correct_size = sizeof(correct_data);
144
145 // std_map_ is empty.
146 serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_);
147
148 EXPECT_EQ(correct_size, serialized_size_);
149 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
150 }
151
TEST_F(TestAddressMapSerializer,MapWithTwoElementsTestCase)152 TEST_F(TestAddressMapSerializer, MapWithTwoElementsTestCase) {
153 const int32_t correct_data[] = {
154 // # of nodes
155 2,
156 // Offsets
157 20, 24,
158 // Keys
159 1, 3,
160 // Values
161 2, 6
162 };
163 uint32_t correct_size = sizeof(correct_data);
164
165 address_map_.Store(1, 2);
166 address_map_.Store(3, 6);
167
168 serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_);
169
170 EXPECT_EQ(correct_size, serialized_size_);
171 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
172 }
173
TEST_F(TestAddressMapSerializer,MapWithFourElementsTestCase)174 TEST_F(TestAddressMapSerializer, MapWithFourElementsTestCase) {
175 const int32_t correct_data[] = {
176 // # of nodes
177 4,
178 // Offsets
179 36, 40, 44, 48,
180 // Keys
181 -6, -4, 8, 123,
182 // Values
183 2, 3, 5, 8
184 };
185 uint32_t correct_size = sizeof(correct_data);
186
187 address_map_.Store(-6, 2);
188 address_map_.Store(-4, 3);
189 address_map_.Store(8, 5);
190 address_map_.Store(123, 8);
191
192 serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_);
193
194 EXPECT_EQ(correct_size, serialized_size_);
195 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
196 }
197
198
199 class TestRangeMapSerializer : public ::testing::Test {
200 protected:
SetUp()201 void SetUp() {
202 serialized_size_ = 0;
203 serialized_data_ = 0;
204 }
205
TearDown()206 void TearDown() {
207 delete [] serialized_data_;
208 }
209
210 google_breakpad::RangeMap<AddrType, EntryType> range_map_;
211 google_breakpad::RangeMapSerializer<AddrType, EntryType> serializer_;
212 uint32_t serialized_size_;
213 char *serialized_data_;
214 };
215
TEST_F(TestRangeMapSerializer,EmptyMapTestCase)216 TEST_F(TestRangeMapSerializer, EmptyMapTestCase) {
217 const int32_t correct_data[] = { 0 };
218 uint32_t correct_size = sizeof(correct_data);
219
220 // range_map_ is empty.
221 serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_);
222
223 EXPECT_EQ(correct_size, serialized_size_);
224 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
225 }
226
TEST_F(TestRangeMapSerializer,MapWithOneRangeTestCase)227 TEST_F(TestRangeMapSerializer, MapWithOneRangeTestCase) {
228 const int32_t correct_data[] = {
229 // # of nodes
230 1,
231 // Offsets
232 12,
233 // Keys: high address
234 10,
235 // Values: (low address, entry) pairs
236 1, 6
237 };
238 uint32_t correct_size = sizeof(correct_data);
239
240 range_map_.StoreRange(1, 10, 6);
241
242 serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_);
243
244 EXPECT_EQ(correct_size, serialized_size_);
245 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
246 }
247
TEST_F(TestRangeMapSerializer,MapWithThreeRangesTestCase)248 TEST_F(TestRangeMapSerializer, MapWithThreeRangesTestCase) {
249 const int32_t correct_data[] = {
250 // # of nodes
251 3,
252 // Offsets
253 28, 36, 44,
254 // Keys: high address
255 5, 9, 20,
256 // Values: (low address, entry) pairs
257 2, 1, 6, 2, 10, 3
258 };
259 uint32_t correct_size = sizeof(correct_data);
260
261 ASSERT_TRUE(range_map_.StoreRange(2, 4, 1));
262 ASSERT_TRUE(range_map_.StoreRange(6, 4, 2));
263 ASSERT_TRUE(range_map_.StoreRange(10, 11, 3));
264
265 serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_);
266
267 EXPECT_EQ(correct_size, serialized_size_);
268 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
269 }
270
271
272 class TestContainedRangeMapSerializer : public ::testing::Test {
273 protected:
SetUp()274 void SetUp() {
275 serialized_size_ = 0;
276 serialized_data_ = 0;
277 }
278
TearDown()279 void TearDown() {
280 delete [] serialized_data_;
281 }
282
283 google_breakpad::ContainedRangeMap<AddrType, EntryType> crm_map_;
284 google_breakpad::ContainedRangeMapSerializer<AddrType, EntryType> serializer_;
285 uint32_t serialized_size_;
286 char *serialized_data_;
287 };
288
TEST_F(TestContainedRangeMapSerializer,EmptyMapTestCase)289 TEST_F(TestContainedRangeMapSerializer, EmptyMapTestCase) {
290 const int32_t correct_data[] = {
291 0, // base address of root
292 4, // size of entry
293 0, // entry stored at root
294 0 // empty map stored at root
295 };
296 uint32_t correct_size = sizeof(correct_data);
297
298 // crm_map_ is empty.
299 serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_);
300
301 EXPECT_EQ(correct_size, serialized_size_);
302 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
303 }
304
TEST_F(TestContainedRangeMapSerializer,MapWithOneRangeTestCase)305 TEST_F(TestContainedRangeMapSerializer, MapWithOneRangeTestCase) {
306 const int32_t correct_data[] = {
307 0, // base address of root
308 4, // size of entry
309 0, // entry stored at root
310 // Map stored at root node:
311 1, // # of nodes
312 12, // offset
313 9, // key
314 // value: a child ContainedRangeMap
315 3, // base address of child CRM
316 4, // size of entry
317 -1, // entry stored in child CRM
318 0 // empty sub-map stored in child CRM
319 };
320 uint32_t correct_size = sizeof(correct_data);
321
322 crm_map_.StoreRange(3, 7, -1);
323
324 serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_);
325
326 EXPECT_EQ(correct_size, serialized_size_);
327 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
328 }
329
TEST_F(TestContainedRangeMapSerializer,MapWithTwoLevelsTestCase)330 TEST_F(TestContainedRangeMapSerializer, MapWithTwoLevelsTestCase) {
331 // Tree structure of ranges:
332 // root level 0
333 // |
334 // map
335 // / \ level 1: child1, child2
336 // 2~8 10~20
337 // | |
338 // map map
339 // / \ |
340 // 3~4 6~7 16-20 level 2: grandchild1, grandchild2, grandchild3
341
342 const int32_t correct_data[] = {
343 // root: base, entry_size, entry
344 0, 4, 0,
345 // root's map: # of nodes, offset1, offset2, key1, key2
346 2, 20, 84, 8, 20,
347 // child1: base, entry_size, entry:
348 2, 4, -1,
349 // child1's map: # of nodes, offset1, offset2, key1, key2
350 2, 20, 36, 4, 7,
351 // grandchild1: base, entry_size, entry, empty_map
352 3, 4, -1, 0,
353 // grandchild2: base, entry_size, entry, empty_map
354 6, 4, -1, 0,
355 // child2: base, entry_size, entry:
356 10, 4, -1,
357 // child2's map: # of nodes, offset1, key1
358 1, 12, 20,
359 // grandchild3: base, entry_size, entry, empty_map
360 16, 4, -1, 0
361 };
362 uint32_t correct_size = sizeof(correct_data);
363
364 // Store child1.
365 ASSERT_TRUE(crm_map_.StoreRange(2, 7, -1));
366 // Store child2.
367 ASSERT_TRUE(crm_map_.StoreRange(10, 11, -1));
368 // Store grandchild1.
369 ASSERT_TRUE(crm_map_.StoreRange(3, 2, -1));
370 // Store grandchild2.
371 ASSERT_TRUE(crm_map_.StoreRange(6, 2, -1));
372 // Store grandchild3.
373 ASSERT_TRUE(crm_map_.StoreRange(16, 5, -1));
374
375 serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_);
376
377 EXPECT_EQ(correct_size, serialized_size_);
378 EXPECT_EQ(memcmp(correct_data, serialized_data_, correct_size), 0);
379 }
380
381
main(int argc,char * argv[])382 int main(int argc, char *argv[]) {
383 ::testing::InitGoogleTest(&argc, argv);
384
385 return RUN_ALL_TESTS();
386 }
387