toolkit/crashreporter/google-breakpad/src/processor/static_map_unittest.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2010 Google Inc.
michael@0 2 // All rights reserved.
michael@0 3 //
michael@0 4 // Redistribution and use in source and binary forms, with or without
michael@0 5 // modification, are permitted provided that the following conditions are
michael@0 6 // met:
michael@0 7 //
michael@0 8 // * Redistributions of source code must retain the above copyright
michael@0 9 // notice, this list of conditions and the following disclaimer.
michael@0 10 // * Redistributions in binary form must reproduce the above
michael@0 11 // copyright notice, this list of conditions and the following disclaimer
michael@0 12 // in the documentation and/or other materials provided with the
michael@0 13 // distribution.
michael@0 14 // * Neither the name of Google Inc. nor the names of its
michael@0 15 // contributors may be used to endorse or promote products derived from
michael@0 16 // this software without specific prior written permission.
michael@0 17 //
michael@0 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 29
michael@0 30 // static_map_unittest.cc: Unit tests for StaticMap.
michael@0 31 //
michael@0 32 // Author: Siyang Xie (lambxsy@google.com)
michael@0 33
michael@0 34 #include <climits>
michael@0 35 #include <map>
michael@0 36
michael@0 37 #include "breakpad_googletest_includes.h"
michael@0 38 #include "processor/static_map-inl.h"
michael@0 39
michael@0 40
michael@0 41 typedef int ValueType;
michael@0 42 typedef int KeyType;
michael@0 43 typedef google_breakpad::StaticMap< KeyType, ValueType > TestMap;
michael@0 44 typedef std::map< KeyType, ValueType > StdMap;
michael@0 45
michael@0 46 template<typename Key, typename Value>
michael@0 47 class SimpleMapSerializer {
michael@0 48 public:
michael@0 49 static char* Serialize(const std::map<Key, Value> &stdmap,
michael@0 50 unsigned int* size = NULL) {
michael@0 51 unsigned int size_per_node =
michael@0 52 sizeof(uint32_t) + sizeof(Key) + sizeof(Value);
michael@0 53 unsigned int memsize = sizeof(int32_t) + size_per_node * stdmap.size();
michael@0 54 if (size) *size = memsize;
michael@0 55
michael@0 56 // Allocate memory for serialized data:
michael@0 57 char* mem = reinterpret_cast<char*>(operator new(memsize));
michael@0 58 char* address = mem;
michael@0 59
michael@0 60 // Writer the number of nodes:
michael@0 61 new (address) uint32_t(static_cast<uint32_t>(stdmap.size()));
michael@0 62 address += sizeof(uint32_t);
michael@0 63
michael@0 64 // Nodes' offset:
michael@0 65 uint32_t* offsets = reinterpret_cast<uint32_t*>(address);
michael@0 66 address += sizeof(uint32_t) * stdmap.size();
michael@0 67
michael@0 68 // Keys:
michael@0 69 Key* keys = reinterpret_cast<Key*>(address);
michael@0 70 address += sizeof(Key) * stdmap.size();
michael@0 71
michael@0 72 // Traversing map:
michael@0 73 typename std::map<Key, Value>::const_iterator iter = stdmap.begin();
michael@0 74 for (int index = 0; iter != stdmap.end(); ++iter, ++index) {
michael@0 75 offsets[index] = static_cast<unsigned int>(address - mem);
michael@0 76 keys[index] = iter->first;
michael@0 77 new (address) Value(iter->second);
michael@0 78 address += sizeof(Value);
michael@0 79 }
michael@0 80 return mem;
michael@0 81 }
michael@0 82 };
michael@0 83
michael@0 84
michael@0 85 class TestInvalidMap : public ::testing::Test {
michael@0 86 protected:
michael@0 87 void SetUp() {
michael@0 88 memset(data, 0, kMemorySize);
michael@0 89 }
michael@0 90
michael@0 91 // 40 Bytes memory can hold a StaticMap with up to 3 nodes.
michael@0 92 static const int kMemorySize = 40;
michael@0 93 char data[kMemorySize];
michael@0 94 TestMap test_map;
michael@0 95 };
michael@0 96
michael@0 97 TEST_F(TestInvalidMap, TestNegativeNumberNodes) {
michael@0 98 memset(data, 0xff, sizeof(uint32_t)); // Set the number of nodes = -1
michael@0 99 test_map = TestMap(data);
michael@0 100 ASSERT_FALSE(test_map.ValidateInMemoryStructure());
michael@0 101 }
michael@0 102
michael@0 103 TEST_F(TestInvalidMap, TestWrongOffsets) {
michael@0 104 uint32_t* header = reinterpret_cast<uint32_t*>(data);
michael@0 105 const uint32_t kNumNodes = 2;
michael@0 106 const uint32_t kHeaderOffset =
michael@0 107 sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType));
michael@0 108
michael@0 109 header[0] = kNumNodes;
michael@0 110 header[1] = kHeaderOffset + 3; // Wrong offset for first node
michael@0 111 test_map = TestMap(data);
michael@0 112 ASSERT_FALSE(test_map.ValidateInMemoryStructure());
michael@0 113
michael@0 114 header[1] = kHeaderOffset; // Correct offset for first node
michael@0 115 header[2] = kHeaderOffset - 1; // Wrong offset for second node
michael@0 116 test_map = TestMap(data);
michael@0 117 ASSERT_FALSE(test_map.ValidateInMemoryStructure());
michael@0 118 }
michael@0 119
michael@0 120 TEST_F(TestInvalidMap, TestUnSortedKeys) {
michael@0 121 uint32_t* header = reinterpret_cast<uint32_t*>(data);
michael@0 122 const uint32_t kNumNodes = 2;
michael@0 123 const uint32_t kHeaderOffset =
michael@0 124 sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType));
michael@0 125 header[0] = kNumNodes;
michael@0 126 header[1] = kHeaderOffset;
michael@0 127 header[2] = kHeaderOffset + sizeof(ValueType);
michael@0 128
michael@0 129 KeyType* keys = reinterpret_cast<KeyType*>(
michael@0 130 data + (kNumNodes + 1) * sizeof(uint32_t));
michael@0 131 // Set keys in non-increasing order.
michael@0 132 keys[0] = 10;
michael@0 133 keys[1] = 7;
michael@0 134 test_map = TestMap(data);
michael@0 135 ASSERT_FALSE(test_map.ValidateInMemoryStructure());
michael@0 136 }
michael@0 137
michael@0 138
michael@0 139 class TestValidMap : public ::testing::Test {
michael@0 140 protected:
michael@0 141 void SetUp() {
michael@0 142 int testcase = 0;
michael@0 143
michael@0 144 // Empty map.
michael@0 145 map_data[testcase] =
michael@0 146 serializer.Serialize(std_map[testcase], &size[testcase]);
michael@0 147 test_map[testcase] = TestMap(map_data[testcase]);
michael@0 148 ++testcase;
michael@0 149
michael@0 150 // Single element.
michael@0 151 std_map[testcase].insert(std::make_pair(2, 8));
michael@0 152 map_data[testcase] =
michael@0 153 serializer.Serialize(std_map[testcase], &size[testcase]);
michael@0 154 test_map[testcase] = TestMap(map_data[testcase]);
michael@0 155 ++testcase;
michael@0 156
michael@0 157 // 100 elements.
michael@0 158 for (int i = 0; i < 100; ++i)
michael@0 159 std_map[testcase].insert(std::make_pair(i, 2 * i));
michael@0 160 map_data[testcase] =
michael@0 161 serializer.Serialize(std_map[testcase], &size[testcase]);
michael@0 162 test_map[testcase] = TestMap(map_data[testcase]);
michael@0 163 ++testcase;
michael@0 164
michael@0 165 // 1000 random elements.
michael@0 166 for (int i = 0; i < 1000; ++i)
michael@0 167 std_map[testcase].insert(std::make_pair(rand(), rand()));
michael@0 168 map_data[testcase] =
michael@0 169 serializer.Serialize(std_map[testcase], &size[testcase]);
michael@0 170 test_map[testcase] = TestMap(map_data[testcase]);
michael@0 171
michael@0 172 // Set correct size of memory allocation for each test case.
michael@0 173 unsigned int size_per_node =
michael@0 174 sizeof(uint32_t) + sizeof(KeyType) + sizeof(ValueType);
michael@0 175 for (testcase = 0; testcase < kNumberTestCases; ++testcase) {
michael@0 176 correct_size[testcase] =
michael@0 177 sizeof(uint32_t) + std_map[testcase].size() * size_per_node;
michael@0 178 }
michael@0 179 }
michael@0 180
michael@0 181 void TearDown() {
michael@0 182 for (int i = 0;i < kNumberTestCases; ++i)
michael@0 183 delete map_data[i];
michael@0 184 }
michael@0 185
michael@0 186
michael@0 187 void IteratorTester(int test_case) {
michael@0 188 // scan through:
michael@0 189 iter_test = test_map[test_case].begin();
michael@0 190 iter_std = std_map[test_case].begin();
michael@0 191
michael@0 192 for (; iter_test != test_map[test_case].end() &&
michael@0 193 iter_std != std_map[test_case].end();
michael@0 194 ++iter_test, ++iter_std) {
michael@0 195 ASSERT_EQ(iter_test.GetKey(), iter_std->first);
michael@0 196 ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second);
michael@0 197 }
michael@0 198 ASSERT_TRUE(iter_test == test_map[test_case].end()
michael@0 199 && iter_std == std_map[test_case].end());
michael@0 200
michael@0 201 // Boundary testcase.
michael@0 202 if (!std_map[test_case].empty()) {
michael@0 203 // rear boundary case:
michael@0 204 iter_test = test_map[test_case].end();
michael@0 205 iter_std = std_map[test_case].end();
michael@0 206 --iter_std;
michael@0 207 --iter_test;
michael@0 208 ASSERT_EQ(iter_test.GetKey(), iter_std->first);
michael@0 209 ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second);
michael@0 210
michael@0 211 ++iter_test;
michael@0 212 ++iter_std;
michael@0 213 ASSERT_TRUE(iter_test == test_map[test_case].end());
michael@0 214
michael@0 215 --iter_test;
michael@0 216 --iter_std;
michael@0 217 ASSERT_TRUE(iter_test != test_map[test_case].end());
michael@0 218 ASSERT_TRUE(iter_test == test_map[test_case].last());
michael@0 219 ASSERT_EQ(iter_test.GetKey(), iter_std->first);
michael@0 220 ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second);
michael@0 221
michael@0 222 // front boundary case:
michael@0 223 iter_test = test_map[test_case].begin();
michael@0 224 --iter_test;
michael@0 225 ASSERT_TRUE(iter_test == test_map[test_case].begin());
michael@0 226 }
michael@0 227 }
michael@0 228
michael@0 229 void CompareLookupResult(int test_case) {
michael@0 230 bool found1 = (iter_test != test_map[test_case].end());
michael@0 231 bool found2 = (iter_std != std_map[test_case].end());
michael@0 232 ASSERT_EQ(found1, found2);
michael@0 233
michael@0 234 if (found1 && found2) {
michael@0 235 ASSERT_EQ(iter_test.GetKey(), iter_std->first);
michael@0 236 ASSERT_EQ(*(iter_test.GetValuePtr()), iter_std->second);
michael@0 237 }
michael@0 238 }
michael@0 239
michael@0 240 void FindTester(int test_case, const KeyType &key) {
michael@0 241 iter_test = test_map[test_case].find(key);
michael@0 242 iter_std = std_map[test_case].find(key);
michael@0 243 CompareLookupResult(test_case);
michael@0 244 }
michael@0 245
michael@0 246 void LowerBoundTester(int test_case, const KeyType &key) {
michael@0 247 iter_test = test_map[test_case].lower_bound(key);
michael@0 248 iter_std = std_map[test_case].lower_bound(key);
michael@0 249 CompareLookupResult(test_case);
michael@0 250 }
michael@0 251
michael@0 252 void UpperBoundTester(int test_case, const KeyType &key) {
michael@0 253 iter_test = test_map[test_case].upper_bound(key);
michael@0 254 iter_std = std_map[test_case].upper_bound(key);
michael@0 255 CompareLookupResult(test_case);
michael@0 256 }
michael@0 257
michael@0 258 void LookupTester(int test_case) {
michael@0 259 StdMap::const_iterator iter;
michael@0 260 // Test find():
michael@0 261 for (iter = std_map[test_case].begin();
michael@0 262 iter != std_map[test_case].end();
michael@0 263 ++iter) {
michael@0 264 FindTester(test_case, iter->first);
michael@0 265 FindTester(test_case, iter->first + 1);
michael@0 266 FindTester(test_case, iter->first - 1);
michael@0 267 }
michael@0 268 FindTester(test_case, INT_MIN);
michael@0 269 FindTester(test_case, INT_MAX);
michael@0 270 // random test:
michael@0 271 for (int i = 0; i < rand()%5000 + 5000; ++i)
michael@0 272 FindTester(test_case, rand());
michael@0 273
michael@0 274 // Test lower_bound():
michael@0 275 for (iter = std_map[test_case].begin();
michael@0 276 iter != std_map[test_case].end();
michael@0 277 ++iter) {
michael@0 278 LowerBoundTester(test_case, iter->first);
michael@0 279 LowerBoundTester(test_case, iter->first + 1);
michael@0 280 LowerBoundTester(test_case, iter->first - 1);
michael@0 281 }
michael@0 282 LowerBoundTester(test_case, INT_MIN);
michael@0 283 LowerBoundTester(test_case, INT_MAX);
michael@0 284 // random test:
michael@0 285 for (int i = 0; i < rand()%5000 + 5000; ++i)
michael@0 286 LowerBoundTester(test_case, rand());
michael@0 287
michael@0 288 // Test upper_bound():
michael@0 289 for (iter = std_map[test_case].begin();
michael@0 290 iter != std_map[test_case].end();
michael@0 291 ++iter) {
michael@0 292 UpperBoundTester(test_case, iter->first);
michael@0 293 UpperBoundTester(test_case, iter->first + 1);
michael@0 294 UpperBoundTester(test_case, iter->first - 1);
michael@0 295 }
michael@0 296 UpperBoundTester(test_case, INT_MIN);
michael@0 297 UpperBoundTester(test_case, INT_MAX);
michael@0 298 // random test:
michael@0 299 for (int i = 0; i < rand()%5000 + 5000; ++i)
michael@0 300 UpperBoundTester(test_case, rand());
michael@0 301 }
michael@0 302
michael@0 303 static const int kNumberTestCases = 4;
michael@0 304 StdMap std_map[kNumberTestCases];
michael@0 305 TestMap test_map[kNumberTestCases];
michael@0 306 TestMap::const_iterator iter_test;
michael@0 307 StdMap::const_iterator iter_std;
michael@0 308 char* map_data[kNumberTestCases];
michael@0 309 unsigned int size[kNumberTestCases];
michael@0 310 unsigned int correct_size[kNumberTestCases];
michael@0 311 SimpleMapSerializer<KeyType, ValueType> serializer;
michael@0 312 };
michael@0 313
michael@0 314 TEST_F(TestValidMap, TestEmptyMap) {
michael@0 315 int test_case = 0;
michael@0 316 // Assert memory size allocated during serialization is correct.
michael@0 317 ASSERT_EQ(correct_size[test_case], size[test_case]);
michael@0 318
michael@0 319 // Sanity check of serialized data:
michael@0 320 ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
michael@0 321 ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty());
michael@0 322 ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size());
michael@0 323
michael@0 324 // Test Iterator.
michael@0 325 IteratorTester(test_case);
michael@0 326
michael@0 327 // Test lookup operations.
michael@0 328 LookupTester(test_case);
michael@0 329 }
michael@0 330
michael@0 331 TEST_F(TestValidMap, TestSingleElement) {
michael@0 332 int test_case = 1;
michael@0 333 // Assert memory size allocated during serialization is correct.
michael@0 334 ASSERT_EQ(correct_size[test_case], size[test_case]);
michael@0 335
michael@0 336 // Sanity check of serialized data:
michael@0 337 ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
michael@0 338 ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty());
michael@0 339 ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size());
michael@0 340
michael@0 341 // Test Iterator.
michael@0 342 IteratorTester(test_case);
michael@0 343
michael@0 344 // Test lookup operations.
michael@0 345 LookupTester(test_case);
michael@0 346 }
michael@0 347
michael@0 348 TEST_F(TestValidMap, Test100Elements) {
michael@0 349 int test_case = 2;
michael@0 350 // Assert memory size allocated during serialization is correct.
michael@0 351 ASSERT_EQ(correct_size[test_case], size[test_case]);
michael@0 352
michael@0 353 // Sanity check of serialized data:
michael@0 354 ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
michael@0 355 ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty());
michael@0 356 ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size());
michael@0 357
michael@0 358 // Test Iterator.
michael@0 359 IteratorTester(test_case);
michael@0 360
michael@0 361 // Test lookup operations.
michael@0 362 LookupTester(test_case);
michael@0 363 }
michael@0 364
michael@0 365 TEST_F(TestValidMap, Test1000RandomElements) {
michael@0 366 int test_case = 3;
michael@0 367 // Assert memory size allocated during serialization is correct.
michael@0 368 ASSERT_EQ(correct_size[test_case], size[test_case]);
michael@0 369
michael@0 370 // Sanity check of serialized data:
michael@0 371 ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
michael@0 372 ASSERT_EQ(std_map[test_case].empty(), test_map[test_case].empty());
michael@0 373 ASSERT_EQ(std_map[test_case].size(), test_map[test_case].size());
michael@0 374
michael@0 375 // Test Iterator.
michael@0 376 IteratorTester(test_case);
michael@0 377
michael@0 378 // Test lookup operations.
michael@0 379 LookupTester(test_case);
michael@0 380 }
michael@0 381
michael@0 382 int main(int argc, char *argv[]) {
michael@0 383 ::testing::InitGoogleTest(&argc, argv);
michael@0 384
michael@0 385 return RUN_ALL_TESTS();
michael@0 386 }

mercurial