Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: client/simple_string_dictionary_test.cc

Issue 489993002: Add SimpleStringDictionary and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rename the template to TSimpleStringDictionary<> Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « client/simple_string_dictionary.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « client/simple_string_dictionary.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698