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// static_address_map_unittest.cc: Unit tests for StaticAddressMap. 31// 32// Author: Siyang Xie (lambxsy@google.com) 33 34#include <climits> 35#include <cstdlib> 36#include <ctime> 37#include <string> 38#include <iostream> 39#include <sstream> 40 41#include "breakpad_googletest_includes.h" 42#include "common/using_std_string.h" 43#include "processor/address_map-inl.h" 44#include "processor/static_address_map-inl.h" 45#include "processor/simple_serializer-inl.h" 46#include "map_serializers-inl.h" 47 48typedef google_breakpad::StaticAddressMap<int, char> TestMap; 49typedef google_breakpad::AddressMap<int, string> AddrMap; 50 51class TestStaticAddressMap : public ::testing::Test { 52 protected: 53 void SetUp() { 54 for (int testcase = 0; testcase < kNumberTestCases; ++testcase) { 55 testdata[testcase] = new int[testsize[testcase]]; 56 } 57 58 // Test data set0: NULL (empty map) 59 60 // Test data set1: single element. 61 testdata[1][0] = 10; 62 63 // Test data set2: six elements. 64 const int tempdata[] = {5, 10, 14, 15, 16, 20}; 65 for (int i = 0; i < testsize[2]; ++i) 66 testdata[2][i] = tempdata[i]; 67 68 // Test data set3: 69 srand(time(NULL)); 70 for (int i = 0; i < testsize[3]; ++i) 71 testdata[3][i] = rand(); 72 73 // Setup maps. 74 std::stringstream sstream; 75 for (int testcase = 0; testcase < kNumberTestCases; ++testcase) { 76 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 77 sstream.clear(); 78 sstream << "test " << testdata[testcase][data_item]; 79 addr_map[testcase].Store(testdata[testcase][data_item], sstream.str()); 80 } 81 map_data[testcase] = serializer.Serialize(addr_map[testcase], NULL); 82 test_map[testcase] = TestMap(map_data[testcase]); 83 } 84 } 85 86 void TearDown() { 87 for (int i = 0; i < kNumberTestCases; ++i) { 88 delete [] map_data[i]; 89 delete [] testdata[i]; 90 } 91 } 92 93 void CompareRetrieveResult(int testcase, int target) { 94 int address; 95 int address_test; 96 string entry; 97 string entry_test; 98 const char *entry_cstring = NULL; 99 bool found; 100 bool found_test; 101 102 found = addr_map[testcase].Retrieve(target, &entry, &address); 103 found_test = 104 test_map[testcase].Retrieve(target, entry_cstring, &address_test); 105 106 ASSERT_EQ(found, found_test); 107 108 if (found && found_test) { 109 ASSERT_EQ(address, address_test); 110 entry_test = entry_cstring; 111 ASSERT_EQ(entry, entry_test); 112 } 113 } 114 115 void RetrieveTester(int testcase) { 116 int target; 117 target = INT_MIN; 118 CompareRetrieveResult(testcase, target); 119 target = INT_MAX; 120 CompareRetrieveResult(testcase, target); 121 122 srand(time(0)); 123 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 124 // Retrive (aka, search) for target address and compare results from 125 // AddressMap and StaticAddressMap. 126 127 // First, assign the search target to be one of original testdata that is 128 // known to exist in the map. 129 target = testdata[testcase][data_item]; 130 CompareRetrieveResult(testcase, target); 131 // Then, add +2 / -1 bias to target value, in order to test searching for 132 // a target address not stored in the map. 133 target -= 1; 134 CompareRetrieveResult(testcase, target); 135 target += 3; 136 CompareRetrieveResult(testcase, target); 137 // Repeatedly test searching for random target addresses. 138 target = rand(); 139 CompareRetrieveResult(testcase, target); 140 } 141 } 142 143 // Test data sets: 144 static const int kNumberTestCases = 4; 145 static const int testsize[]; 146 int *testdata[kNumberTestCases]; 147 148 AddrMap addr_map[kNumberTestCases]; 149 TestMap test_map[kNumberTestCases]; 150 char *map_data[kNumberTestCases]; 151 google_breakpad::AddressMapSerializer<int, string> serializer; 152}; 153 154const int TestStaticAddressMap::testsize[] = {0, 1, 6, 1000}; 155 156TEST_F(TestStaticAddressMap, TestEmptyMap) { 157 int testcase = 0; 158 int target; 159 target = INT_MIN; 160 CompareRetrieveResult(testcase, target); 161 target = INT_MAX; 162 CompareRetrieveResult(testcase, target); 163 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 164 target = testdata[testcase][data_item]; 165 CompareRetrieveResult(testcase, target); 166 target -= 1; 167 CompareRetrieveResult(testcase, target); 168 target += 3; 169 CompareRetrieveResult(testcase, target); 170 target = rand(); 171 CompareRetrieveResult(testcase, target); 172 } 173} 174 175TEST_F(TestStaticAddressMap, TestOneElementMap) { 176 int testcase = 1; 177 int target; 178 target = INT_MIN; 179 CompareRetrieveResult(testcase, target); 180 target = INT_MAX; 181 CompareRetrieveResult(testcase, target); 182 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 183 target = testdata[testcase][data_item]; 184 CompareRetrieveResult(testcase, target); 185 target -= 1; 186 CompareRetrieveResult(testcase, target); 187 target += 3; 188 CompareRetrieveResult(testcase, target); 189 target = rand(); 190 CompareRetrieveResult(testcase, target); 191 } 192} 193 194TEST_F(TestStaticAddressMap, TestSixElementsMap) { 195 int testcase = 2; 196 int target; 197 target = INT_MIN; 198 CompareRetrieveResult(testcase, target); 199 target = INT_MAX; 200 CompareRetrieveResult(testcase, target); 201 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 202 target = testdata[testcase][data_item]; 203 CompareRetrieveResult(testcase, target); 204 target -= 1; 205 CompareRetrieveResult(testcase, target); 206 target += 3; 207 CompareRetrieveResult(testcase, target); 208 target = rand(); 209 CompareRetrieveResult(testcase, target); 210 } 211} 212 213TEST_F(TestStaticAddressMap, Test1000RandomElementsMap) { 214 int testcase = 3; 215 int target; 216 target = INT_MIN; 217 CompareRetrieveResult(testcase, target); 218 target = INT_MAX; 219 CompareRetrieveResult(testcase, target); 220 for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { 221 target = testdata[testcase][data_item]; 222 CompareRetrieveResult(testcase, target); 223 target -= 1; 224 CompareRetrieveResult(testcase, target); 225 target += 3; 226 CompareRetrieveResult(testcase, target); 227 target = rand(); 228 CompareRetrieveResult(testcase, target); 229 } 230} 231 232int main(int argc, char *argv[]) { 233 ::testing::InitGoogleTest(&argc, argv); 234 235 return RUN_ALL_TESTS(); 236} 237