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