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