Home | History | Annotate | Download | only in processor
      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 (at) 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:
     54   void SetUp() {
     55     serialized_size_ = 0;
     56     serialized_data_ = NULL;
     57   }
     58 
     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 
     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 
     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 
    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:
    126   void SetUp() {
    127     serialized_size_ = 0;
    128     serialized_data_ = 0;
    129   }
    130 
    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 
    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 
    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 
    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:
    201   void SetUp() {
    202     serialized_size_ = 0;
    203     serialized_data_ = 0;
    204   }
    205 
    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 
    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 
    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 
    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:
    274   void SetUp() {
    275     serialized_size_ = 0;
    276     serialized_data_ = 0;
    277   }
    278 
    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 
    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 
    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 
    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 
    382 int main(int argc, char *argv[]) {
    383   ::testing::InitGoogleTest(&argc, argv);
    384 
    385   return RUN_ALL_TESTS();
    386 }
    387