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 (at) 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 48 typedef google_breakpad::StaticAddressMap<int, char> TestMap; 49 typedef google_breakpad::AddressMap<int, string> AddrMap; 50 51 class 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 154 const int TestStaticAddressMap::testsize[] = {0, 1, 6, 1000}; 155 156 TEST_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 175 TEST_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 194 TEST_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 213 TEST_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 232 int main(int argc, char *argv[]) { 233 ::testing::InitGoogleTest(&argc, argv); 234 235 return RUN_ALL_TESTS(); 236 } 237