OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #include "client/simple_string_dictionary.h" |
| 16 |
| 17 #include "base/logging.h" |
| 18 #include "gtest/gtest.h" |
| 19 |
| 20 namespace { |
| 21 |
| 22 using namespace crashpad; |
| 23 |
| 24 TEST(SimpleStringDictionary, Entry) { |
| 25 typedef TSimpleStringDictionary<5, 9, 15> TestMap; |
| 26 TestMap map; |
| 27 |
| 28 const TestMap::Entry* entry = TestMap::Iterator(map).Next(); |
| 29 EXPECT_FALSE(entry); |
| 30 |
| 31 // Try setting a key/value and then verify. |
| 32 map.SetKeyValue("key1", "value1"); |
| 33 entry = TestMap::Iterator(map).Next(); |
| 34 ASSERT_TRUE(entry); |
| 35 EXPECT_STREQ(entry->key, "key1"); |
| 36 EXPECT_STREQ(entry->value, "value1"); |
| 37 |
| 38 // Try setting a new value. |
| 39 map.SetKeyValue("key1", "value3"); |
| 40 EXPECT_STREQ(entry->value, "value3"); |
| 41 |
| 42 // Make sure the key didn't change. |
| 43 EXPECT_STREQ(entry->key, "key1"); |
| 44 |
| 45 // Clear the entry and verify the key and value are empty strings. |
| 46 map.RemoveKey("key1"); |
| 47 EXPECT_FALSE(entry->is_active()); |
| 48 EXPECT_EQ(strlen(entry->key), 0u); |
| 49 EXPECT_EQ(strlen(entry->value), 0u); |
| 50 } |
| 51 |
| 52 TEST(SimpleStringDictionary, SimpleStringDictionary) { |
| 53 // Make a new dictionary |
| 54 SimpleStringDictionary dict; |
| 55 |
| 56 // Set three distinct values on three keys |
| 57 dict.SetKeyValue("key1", "value1"); |
| 58 dict.SetKeyValue("key2", "value2"); |
| 59 dict.SetKeyValue("key3", "value3"); |
| 60 |
| 61 EXPECT_NE(dict.GetValueForKey("key1"), "value1"); |
| 62 EXPECT_NE(dict.GetValueForKey("key2"), "value2"); |
| 63 EXPECT_NE(dict.GetValueForKey("key3"), "value3"); |
| 64 EXPECT_EQ(dict.GetCount(), 3u); |
| 65 // try an unknown key |
| 66 EXPECT_FALSE(dict.GetValueForKey("key4")); |
| 67 |
| 68 // Remove a key |
| 69 dict.RemoveKey("key3"); |
| 70 |
| 71 // Now make sure it's not there anymore |
| 72 EXPECT_FALSE(dict.GetValueForKey("key3")); |
| 73 |
| 74 // Remove by setting value to NULL |
| 75 dict.SetKeyValue("key2", NULL); |
| 76 |
| 77 // Now make sure it's not there anymore |
| 78 EXPECT_FALSE(dict.GetValueForKey("key2")); |
| 79 } |
| 80 |
| 81 TEST(SimpleStringDictionary, CopyAndAssign) { |
| 82 TSimpleStringDictionary<10, 10, 10> map; |
| 83 map.SetKeyValue("one", "a"); |
| 84 map.SetKeyValue("two", "b"); |
| 85 map.SetKeyValue("three", "c"); |
| 86 map.RemoveKey("two"); |
| 87 EXPECT_EQ(2u, map.GetCount()); |
| 88 |
| 89 // Test copy. |
| 90 TSimpleStringDictionary<10, 10, 10> map_copy(map); |
| 91 EXPECT_EQ(2u, map_copy.GetCount()); |
| 92 EXPECT_STREQ("a", map_copy.GetValueForKey("one")); |
| 93 EXPECT_STREQ("c", map_copy.GetValueForKey("three")); |
| 94 map_copy.SetKeyValue("four", "d"); |
| 95 EXPECT_STREQ("d", map_copy.GetValueForKey("four")); |
| 96 EXPECT_FALSE(map.GetValueForKey("four")); |
| 97 |
| 98 // Test assign. |
| 99 TSimpleStringDictionary<10, 10, 10> map_assign; |
| 100 map_assign = map; |
| 101 EXPECT_EQ(2u, map_assign.GetCount()); |
| 102 EXPECT_STREQ("a", map_assign.GetValueForKey("one")); |
| 103 EXPECT_STREQ("c", map_assign.GetValueForKey("three")); |
| 104 map_assign.SetKeyValue("four", "d"); |
| 105 EXPECT_STREQ("d", map_assign.GetValueForKey("four")); |
| 106 EXPECT_FALSE(map.GetValueForKey("four")); |
| 107 |
| 108 map.RemoveKey("one"); |
| 109 EXPECT_FALSE(map.GetValueForKey("one")); |
| 110 EXPECT_STREQ("a", map_copy.GetValueForKey("one")); |
| 111 EXPECT_STREQ("a", map_assign.GetValueForKey("one")); |
| 112 } |
| 113 |
| 114 // Add a bunch of values to the dictionary, remove some entries in the middle, |
| 115 // and then add more. |
| 116 TEST(SimpleStringDictionary, Iterator) { |
| 117 SimpleStringDictionary* dict = new SimpleStringDictionary; |
| 118 ASSERT_TRUE(dict); |
| 119 |
| 120 char key[SimpleStringDictionary::key_size]; |
| 121 char value[SimpleStringDictionary::value_size]; |
| 122 |
| 123 const int kDictionaryCapacity = SimpleStringDictionary::num_entries; |
| 124 const int kPartitionIndex = kDictionaryCapacity - 5; |
| 125 |
| 126 // We assume at least this size in the tests below |
| 127 ASSERT_GE(kDictionaryCapacity, 64); |
| 128 |
| 129 // We'll keep track of the number of key/value pairs we think should be in the |
| 130 // dictionary |
| 131 int expectedDictionarySize = 0; |
| 132 |
| 133 // Set a bunch of key/value pairs like key0/value0, key1/value1, ... |
| 134 for (int i = 0; i < kPartitionIndex; ++i) { |
| 135 sprintf(key, "key%d", i); |
| 136 sprintf(value, "value%d", i); |
| 137 dict->SetKeyValue(key, value); |
| 138 } |
| 139 expectedDictionarySize = kPartitionIndex; |
| 140 |
| 141 // set a couple of the keys twice (with the same value) - should be nop |
| 142 dict->SetKeyValue("key2", "value2"); |
| 143 dict->SetKeyValue("key4", "value4"); |
| 144 dict->SetKeyValue("key15", "value15"); |
| 145 |
| 146 // Remove some random elements in the middle |
| 147 dict->RemoveKey("key7"); |
| 148 dict->RemoveKey("key18"); |
| 149 dict->RemoveKey("key23"); |
| 150 dict->RemoveKey("key31"); |
| 151 expectedDictionarySize -= 4; // we just removed four key/value pairs |
| 152 |
| 153 // Set some more key/value pairs like key59/value59, key60/value60, ... |
| 154 for (int i = kPartitionIndex; i < kDictionaryCapacity; ++i) { |
| 155 sprintf(key, "key%d", i); |
| 156 sprintf(value, "value%d", i); |
| 157 dict->SetKeyValue(key, value); |
| 158 } |
| 159 expectedDictionarySize += kDictionaryCapacity - kPartitionIndex; |
| 160 |
| 161 // Now create an iterator on the dictionary |
| 162 SimpleStringDictionary::Iterator iter(*dict); |
| 163 |
| 164 // We then verify that it iterates through exactly the number of key/value |
| 165 // pairs we expect, and that they match one-for-one with what we would expect. |
| 166 // The ordering of the iteration does not matter... |
| 167 |
| 168 // used to keep track of number of occurrences found for key/value pairs |
| 169 int count[kDictionaryCapacity]; |
| 170 memset(count, 0, sizeof(count)); |
| 171 |
| 172 int totalCount = 0; |
| 173 |
| 174 const SimpleStringDictionary::Entry* entry; |
| 175 while ((entry = iter.Next())) { |
| 176 totalCount++; |
| 177 |
| 178 // Extract keyNumber from a string of the form key<keyNumber> |
| 179 int keyNumber; |
| 180 sscanf(entry->key, "key%d", &keyNumber); |
| 181 |
| 182 // Extract valueNumber from a string of the form value<valueNumber> |
| 183 int valueNumber; |
| 184 sscanf(entry->value, "value%d", &valueNumber); |
| 185 |
| 186 // The value number should equal the key number since that's how we set them |
| 187 EXPECT_EQ(keyNumber, valueNumber); |
| 188 |
| 189 // Key and value numbers should be in proper range: 0 <= keyNumber < |
| 190 // kDictionaryCapacity |
| 191 bool isKeyInGoodRange = (keyNumber >= 0 && keyNumber < kDictionaryCapacity); |
| 192 bool isValueInGoodRange = |
| 193 (valueNumber >= 0 && valueNumber < kDictionaryCapacity); |
| 194 EXPECT_TRUE(isKeyInGoodRange); |
| 195 EXPECT_TRUE(isValueInGoodRange); |
| 196 |
| 197 if (isKeyInGoodRange && isValueInGoodRange) { |
| 198 ++count[keyNumber]; |
| 199 } |
| 200 } |
| 201 |
| 202 // Make sure each of the key/value pairs showed up exactly one time, except |
| 203 // for the ones which we removed. |
| 204 for (size_t i = 0; i < kDictionaryCapacity; ++i) { |
| 205 // Skip over key7, key18, key23, and key31, since we removed them |
| 206 if (!(i == 7 || i == 18 || i == 23 || i == 31)) { |
| 207 EXPECT_EQ(count[i], 1); |
| 208 } |
| 209 } |
| 210 |
| 211 // Make sure the number of iterations matches the expected dictionary size. |
| 212 EXPECT_EQ(totalCount, expectedDictionarySize); |
| 213 } |
| 214 |
| 215 TEST(SimpleStringDictionary, AddRemove) { |
| 216 TSimpleStringDictionary<5, 7, 6> map; |
| 217 map.SetKeyValue("rob", "ert"); |
| 218 map.SetKeyValue("mike", "pink"); |
| 219 map.SetKeyValue("mark", "allays"); |
| 220 |
| 221 EXPECT_EQ(3u, map.GetCount()); |
| 222 EXPECT_STREQ("ert", map.GetValueForKey("rob")); |
| 223 EXPECT_STREQ("pink", map.GetValueForKey("mike")); |
| 224 EXPECT_STREQ("allays", map.GetValueForKey("mark")); |
| 225 |
| 226 map.RemoveKey("mike"); |
| 227 |
| 228 EXPECT_EQ(2u, map.GetCount()); |
| 229 EXPECT_FALSE(map.GetValueForKey("mike")); |
| 230 |
| 231 map.SetKeyValue("mark", "mal"); |
| 232 EXPECT_EQ(2u, map.GetCount()); |
| 233 EXPECT_STREQ("mal", map.GetValueForKey("mark")); |
| 234 |
| 235 map.RemoveKey("mark"); |
| 236 EXPECT_EQ(1u, map.GetCount()); |
| 237 EXPECT_FALSE(map.GetValueForKey("mark")); |
| 238 } |
| 239 |
| 240 TEST(SimpleStringDictionary, Serialize) { |
| 241 typedef TSimpleStringDictionary<4, 5, 7> TestMap; |
| 242 TestMap map; |
| 243 map.SetKeyValue("one", "abc"); |
| 244 map.SetKeyValue("two", "def"); |
| 245 map.SetKeyValue("tre", "hig"); |
| 246 |
| 247 EXPECT_STREQ("abc", map.GetValueForKey("one")); |
| 248 EXPECT_STREQ("def", map.GetValueForKey("two")); |
| 249 EXPECT_STREQ("hig", map.GetValueForKey("tre")); |
| 250 |
| 251 const SerializedSimpleStringDictionary* serialized; |
| 252 size_t size = map.Serialize(&serialized); |
| 253 |
| 254 SerializedSimpleStringDictionary* serialized_copy = |
| 255 reinterpret_cast<SerializedSimpleStringDictionary*>(malloc(size)); |
| 256 ASSERT_TRUE(serialized_copy); |
| 257 memcpy(serialized_copy, serialized, size); |
| 258 |
| 259 TestMap deserialized(serialized_copy, size); |
| 260 free(serialized_copy); |
| 261 |
| 262 EXPECT_EQ(3u, deserialized.GetCount()); |
| 263 EXPECT_STREQ("abc", deserialized.GetValueForKey("one")); |
| 264 EXPECT_STREQ("def", deserialized.GetValueForKey("two")); |
| 265 EXPECT_STREQ("hig", deserialized.GetValueForKey("tre")); |
| 266 } |
| 267 |
| 268 // Running out of space shouldn't crash. |
| 269 TEST(SimpleStringDictionary, OutOfSpace) { |
| 270 TSimpleStringDictionary<3, 2, 2> map; |
| 271 map.SetKeyValue("a", "1"); |
| 272 map.SetKeyValue("b", "2"); |
| 273 map.SetKeyValue("c", "3"); |
| 274 EXPECT_EQ(2u, map.GetCount()); |
| 275 EXPECT_FALSE(map.GetValueForKey("c")); |
| 276 } |
| 277 |
| 278 #if DCHECK_IS_ON |
| 279 |
| 280 TEST(SimpleStringDictionaryDeathTest, NullKey) { |
| 281 TSimpleStringDictionary<4, 6, 6> map; |
| 282 ASSERT_DEATH(map.SetKeyValue(NULL, "hello"), "key"); |
| 283 |
| 284 map.SetKeyValue("hi", "there"); |
| 285 ASSERT_DEATH(map.GetValueForKey(NULL), "key"); |
| 286 EXPECT_STREQ("there", map.GetValueForKey("hi")); |
| 287 |
| 288 ASSERT_DEATH(map.GetValueForKey(NULL), "key"); |
| 289 map.RemoveKey("hi"); |
| 290 EXPECT_EQ(0u, map.GetCount()); |
| 291 } |
| 292 |
| 293 #endif |
| 294 |
| 295 } // namespace |
OLD | NEW |