/src/mozilla-central/toolkit/components/url-classifier/tests/gtest/TestVariableLengthPrefixSet.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #include <mozilla/RefPtr.h> |
6 | | #include "nsString.h" |
7 | | #include "nsTArray.h" |
8 | | #include "nsClassHashtable.h" |
9 | | #include "VariableLengthPrefixSet.h" |
10 | | #include "nsAppDirectoryServiceDefs.h" |
11 | | #include "nsIFile.h" |
12 | | #include "gtest/gtest.h" |
13 | | |
14 | | using namespace mozilla::safebrowsing; |
15 | | |
16 | | typedef nsCString _Prefix; |
17 | | typedef nsTArray<_Prefix> _PrefixArray; |
18 | | |
19 | | // Create fullhash by appending random characters. |
20 | | static nsCString* CreateFullHash(const nsACString& in) |
21 | 0 | { |
22 | 0 | nsCString* out = new nsCString(in); |
23 | 0 | out->SetLength(32); |
24 | 0 | for (size_t i = in.Length(); i < 32; i++) { |
25 | 0 | out->SetCharAt(char(rand() % 256), i); |
26 | 0 | } |
27 | 0 |
|
28 | 0 | return out; |
29 | 0 | } |
30 | | |
31 | | // This function generate N prefixes with size between MIN and MAX. |
32 | | // The output array will not be cleared, random result will append to it |
33 | | static void RandomPrefixes(uint32_t N, uint32_t MIN, uint32_t MAX, _PrefixArray& array) |
34 | 0 | { |
35 | 0 | array.SetCapacity(array.Length() + N); |
36 | 0 |
|
37 | 0 | uint32_t range = (MAX - MIN + 1); |
38 | 0 |
|
39 | 0 | for (uint32_t i = 0; i < N; i++) { |
40 | 0 | uint32_t prefixSize = (rand() % range) + MIN; |
41 | 0 | _Prefix prefix; |
42 | 0 | prefix.SetLength(prefixSize); |
43 | 0 |
|
44 | 0 | bool added = false; |
45 | 0 | while(!added) { |
46 | 0 | char* dst = prefix.BeginWriting(); |
47 | 0 | for (uint32_t j = 0; j < prefixSize; j++) { |
48 | 0 | dst[j] = rand() % 256; |
49 | 0 | } |
50 | 0 |
|
51 | 0 | if (!array.Contains(prefix)) { |
52 | 0 | array.AppendElement(prefix); |
53 | 0 | added = true; |
54 | 0 | } |
55 | 0 | } |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | static void CheckContent(VariableLengthPrefixSet* pset, |
60 | | PrefixStringMap& expected) |
61 | 0 | { |
62 | 0 | PrefixStringMap vlPSetMap; |
63 | 0 | pset->GetPrefixes(vlPSetMap); |
64 | 0 |
|
65 | 0 | for (auto iter = vlPSetMap.Iter(); !iter.Done(); iter.Next()) { |
66 | 0 | nsCString* expectedPrefix = expected.Get(iter.Key()); |
67 | 0 | nsCString* resultPrefix = iter.Data(); |
68 | 0 |
|
69 | 0 | ASSERT_TRUE(resultPrefix->Equals(*expectedPrefix)); |
70 | 0 | } |
71 | 0 | } |
72 | | |
73 | | // This test loops through all the prefixes and converts each prefix to |
74 | | // fullhash by appending random characters, each converted fullhash |
75 | | // should at least match its original length in the prefixSet. |
76 | | static void DoExpectedLookup(VariableLengthPrefixSet* pset, |
77 | | _PrefixArray& array) |
78 | 0 | { |
79 | 0 | uint32_t matchLength = 0; |
80 | 0 | for (uint32_t i = 0; i < array.Length(); i++) { |
81 | 0 | const nsCString& prefix = array[i]; |
82 | 0 | UniquePtr<nsCString> fullhash(CreateFullHash(prefix)); |
83 | 0 |
|
84 | 0 | // Find match for prefix-generated full hash |
85 | 0 | pset->Matches(*fullhash, &matchLength); |
86 | 0 | MOZ_ASSERT(matchLength != 0); |
87 | 0 |
|
88 | 0 | if (matchLength != prefix.Length()) { |
89 | 0 | // Return match size is not the same as prefix size. |
90 | 0 | // In this case it could be because the generated fullhash match other |
91 | 0 | // prefixes, check if this prefix exist. |
92 | 0 | bool found = false; |
93 | 0 |
|
94 | 0 | for (uint32_t j = 0; j < array.Length(); j++) { |
95 | 0 | if (array[j].Length() != matchLength) { |
96 | 0 | continue; |
97 | 0 | } |
98 | 0 | |
99 | 0 | if (0 == memcmp(fullhash->BeginReading(), |
100 | 0 | array[j].BeginReading(), |
101 | 0 | matchLength)) { |
102 | 0 | found = true; |
103 | 0 | break; |
104 | 0 | } |
105 | 0 | } |
106 | 0 | ASSERT_TRUE(found); |
107 | 0 | } |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | static void DoRandomLookup(VariableLengthPrefixSet* pset, |
112 | | uint32_t N, |
113 | | _PrefixArray& array) |
114 | 0 | { |
115 | 0 | for (uint32_t i = 0; i < N; i++) { |
116 | 0 | // Random 32-bytes test fullhash |
117 | 0 | char buf[32]; |
118 | 0 | for (uint32_t j = 0; j < 32; j++) { |
119 | 0 | buf[j] = (char)(rand() % 256); |
120 | 0 | } |
121 | 0 |
|
122 | 0 | // Get the expected result. |
123 | 0 | nsTArray<uint32_t> expected; |
124 | 0 | for (uint32_t j = 0; j < array.Length(); j++) { |
125 | 0 | const nsACString& str = array[j]; |
126 | 0 | if (0 == memcmp(buf, str.BeginReading(), str.Length())) { |
127 | 0 | expected.AppendElement(str.Length()); |
128 | 0 | } |
129 | 0 | } |
130 | 0 |
|
131 | 0 | uint32_t matchLength = 0; |
132 | 0 | pset->Matches(nsDependentCSubstring(buf, 32), &matchLength); |
133 | 0 |
|
134 | 0 | ASSERT_TRUE(expected.IsEmpty() ? !matchLength : expected.Contains(matchLength)); |
135 | 0 | } |
136 | 0 | } |
137 | | |
138 | | static void SetupPrefixMap(const _PrefixArray& array, |
139 | | PrefixStringMap& map) |
140 | 0 | { |
141 | 0 | map.Clear(); |
142 | 0 |
|
143 | 0 | // Buckets are keyed by prefix length and contain an array of |
144 | 0 | // all prefixes of that length. |
145 | 0 | nsClassHashtable<nsUint32HashKey, _PrefixArray> table; |
146 | 0 |
|
147 | 0 | for (uint32_t i = 0; i < array.Length(); i++) { |
148 | 0 | _PrefixArray* prefixes = table.Get(array[i].Length()); |
149 | 0 | if (!prefixes) { |
150 | 0 | prefixes = new _PrefixArray(); |
151 | 0 | table.Put(array[i].Length(), prefixes); |
152 | 0 | } |
153 | 0 |
|
154 | 0 | prefixes->AppendElement(array[i]); |
155 | 0 | } |
156 | 0 |
|
157 | 0 | // The resulting map entries will be a concatenation of all |
158 | 0 | // prefix data for the prefixes of a given size. |
159 | 0 | for (auto iter = table.Iter(); !iter.Done(); iter.Next()) { |
160 | 0 | uint32_t size = iter.Key(); |
161 | 0 | uint32_t count = iter.Data()->Length(); |
162 | 0 |
|
163 | 0 | _Prefix* str = new _Prefix(); |
164 | 0 | str->SetLength(size * count); |
165 | 0 |
|
166 | 0 | char* dst = str->BeginWriting(); |
167 | 0 |
|
168 | 0 | iter.Data()->Sort(); |
169 | 0 | for (uint32_t i = 0; i < count; i++) { |
170 | 0 | memcpy(dst, iter.Data()->ElementAt(i).get(), size); |
171 | 0 | dst += size; |
172 | 0 | } |
173 | 0 |
|
174 | 0 | map.Put(size, str); |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | | |
179 | | // Test setting prefix set with only 4-bytes prefixes |
180 | | TEST(UrlClassifierVLPrefixSet, FixedLengthSet) |
181 | 0 | { |
182 | 0 | srand(time(nullptr)); |
183 | 0 |
|
184 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
185 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
186 | 0 |
|
187 | 0 | PrefixStringMap map; |
188 | 0 | _PrefixArray array = { _Prefix("alph"), _Prefix("brav"), _Prefix("char"), |
189 | 0 | _Prefix("delt"), _Prefix("echo"), _Prefix("foxt"), |
190 | 0 | }; |
191 | 0 |
|
192 | 0 | SetupPrefixMap(array, map); |
193 | 0 | pset->SetPrefixes(map); |
194 | 0 |
|
195 | 0 | DoExpectedLookup(pset, array); |
196 | 0 |
|
197 | 0 | DoRandomLookup(pset, 1000, array); |
198 | 0 |
|
199 | 0 | CheckContent(pset, map); |
200 | 0 |
|
201 | 0 | // Run random test |
202 | 0 | array.Clear(); |
203 | 0 | map.Clear(); |
204 | 0 |
|
205 | 0 | RandomPrefixes(1500, 4, 4, array); |
206 | 0 |
|
207 | 0 | SetupPrefixMap(array, map); |
208 | 0 | pset->SetPrefixes(map); |
209 | 0 |
|
210 | 0 | DoExpectedLookup(pset, array); |
211 | 0 |
|
212 | 0 | DoRandomLookup(pset, 1000, array); |
213 | 0 |
|
214 | 0 | CheckContent(pset, map); |
215 | 0 | } |
216 | | |
217 | | // Test setting prefix set with only 5~32 bytes prefixes |
218 | | TEST(UrlClassifierVLPrefixSet, VariableLengthSet) |
219 | 0 | { |
220 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
221 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
222 | 0 |
|
223 | 0 | PrefixStringMap map; |
224 | 0 | _PrefixArray array = { _Prefix("bravo"), _Prefix("charlie"), _Prefix("delta"), |
225 | 0 | _Prefix("EchoEchoEchoEchoEcho"), _Prefix("foxtrot"), |
226 | 0 | _Prefix("GolfGolfGolfGolfGolfGolfGolfGolf"), |
227 | 0 | _Prefix("hotel"), _Prefix("november"), |
228 | 0 | _Prefix("oscar"), _Prefix("quebec"), _Prefix("romeo"), |
229 | 0 | _Prefix("sierrasierrasierrasierrasierra"), |
230 | 0 | _Prefix("Tango"), _Prefix("whiskey"), _Prefix("yankee"), |
231 | 0 | _Prefix("ZuluZuluZuluZulu") |
232 | 0 | }; |
233 | 0 |
|
234 | 0 | SetupPrefixMap(array, map); |
235 | 0 | pset->SetPrefixes(map); |
236 | 0 |
|
237 | 0 | DoExpectedLookup(pset, array); |
238 | 0 |
|
239 | 0 | DoRandomLookup(pset, 1000, array); |
240 | 0 |
|
241 | 0 | CheckContent(pset, map); |
242 | 0 |
|
243 | 0 | // Run random test |
244 | 0 | array.Clear(); |
245 | 0 | map.Clear(); |
246 | 0 |
|
247 | 0 | RandomPrefixes(1500, 5, 32, array); |
248 | 0 |
|
249 | 0 | SetupPrefixMap(array, map); |
250 | 0 | pset->SetPrefixes(map); |
251 | 0 |
|
252 | 0 | DoExpectedLookup(pset, array); |
253 | 0 |
|
254 | 0 | DoRandomLookup(pset, 1000, array); |
255 | 0 |
|
256 | 0 | CheckContent(pset, map); |
257 | 0 |
|
258 | 0 | } |
259 | | |
260 | | // Test setting prefix set with both 4-bytes prefixes and 5~32 bytes prefixes |
261 | | TEST(UrlClassifierVLPrefixSet, MixedPrefixSet) |
262 | 0 | { |
263 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
264 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
265 | 0 |
|
266 | 0 | PrefixStringMap map; |
267 | 0 | _PrefixArray array = { _Prefix("enus"), _Prefix("apollo"), _Prefix("mars"), |
268 | 0 | _Prefix("Hecatonchires cyclopes"), |
269 | 0 | _Prefix("vesta"), _Prefix("neptunus"), _Prefix("jupiter"), |
270 | 0 | _Prefix("diana"), _Prefix("minerva"), _Prefix("ceres"), |
271 | 0 | _Prefix("Aidos,Adephagia,Adikia,Aletheia"), |
272 | 0 | _Prefix("hecatonchires"), _Prefix("alcyoneus"), _Prefix("hades"), |
273 | 0 | _Prefix("vulcanus"), _Prefix("juno"), _Prefix("mercury"), |
274 | 0 | _Prefix("Stheno, Euryale and Medusa") |
275 | 0 | }; |
276 | 0 |
|
277 | 0 | SetupPrefixMap(array, map); |
278 | 0 | pset->SetPrefixes(map); |
279 | 0 |
|
280 | 0 | DoExpectedLookup(pset, array); |
281 | 0 |
|
282 | 0 | DoRandomLookup(pset, 1000, array); |
283 | 0 |
|
284 | 0 | CheckContent(pset, map); |
285 | 0 |
|
286 | 0 | // Run random test |
287 | 0 | array.Clear(); |
288 | 0 | map.Clear(); |
289 | 0 |
|
290 | 0 | RandomPrefixes(1500, 4, 32, array); |
291 | 0 |
|
292 | 0 | SetupPrefixMap(array, map); |
293 | 0 | pset->SetPrefixes(map); |
294 | 0 |
|
295 | 0 | DoExpectedLookup(pset, array); |
296 | 0 |
|
297 | 0 | DoRandomLookup(pset, 1000, array); |
298 | 0 |
|
299 | 0 | CheckContent(pset, map); |
300 | 0 | } |
301 | | |
302 | | // Test resetting prefix set |
303 | | TEST(UrlClassifierVLPrefixSet, ResetPrefix) |
304 | 0 | { |
305 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
306 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
307 | 0 |
|
308 | 0 | // First prefix set |
309 | 0 | _PrefixArray array1 = { _Prefix("Iceland"), _Prefix("Peru"), _Prefix("Mexico"), |
310 | 0 | _Prefix("Australia"), _Prefix("Japan"), _Prefix("Egypt"), |
311 | 0 | _Prefix("America"), _Prefix("Finland"), _Prefix("Germany"), |
312 | 0 | _Prefix("Italy"), _Prefix("France"), _Prefix("Taiwan"), |
313 | 0 | }; |
314 | 0 | { |
315 | 0 | PrefixStringMap map; |
316 | 0 |
|
317 | 0 | SetupPrefixMap(array1, map); |
318 | 0 | pset->SetPrefixes(map); |
319 | 0 |
|
320 | 0 | DoExpectedLookup(pset, array1); |
321 | 0 | } |
322 | 0 |
|
323 | 0 | // Second |
324 | 0 | _PrefixArray array2 = { _Prefix("Pikachu"), _Prefix("Bulbasaur"), _Prefix("Charmander"), |
325 | 0 | _Prefix("Blastoise"), _Prefix("Pidgey"), _Prefix("Mewtwo"), |
326 | 0 | _Prefix("Jigglypuff"), _Prefix("Persian"), _Prefix("Tentacool"), |
327 | 0 | _Prefix("Onix"), _Prefix("Eevee"), _Prefix("Jynx"), |
328 | 0 | }; |
329 | 0 | { |
330 | 0 | PrefixStringMap map; |
331 | 0 |
|
332 | 0 | SetupPrefixMap(array2, map); |
333 | 0 | pset->SetPrefixes(map); |
334 | 0 |
|
335 | 0 | DoExpectedLookup(pset, array2); |
336 | 0 | } |
337 | 0 |
|
338 | 0 | // Should not match any of the first prefix set |
339 | 0 | uint32_t matchLength = 0; |
340 | 0 | for (uint32_t i = 0; i < array1.Length(); i++) { |
341 | 0 | UniquePtr<nsACString> fullhash(CreateFullHash(array1[i])); |
342 | 0 |
|
343 | 0 | pset->Matches(*fullhash, &matchLength); |
344 | 0 | ASSERT_TRUE(matchLength == 0); |
345 | 0 | } |
346 | 0 | } |
347 | | |
348 | | // Test only set one 4-bytes prefix and one full-length prefix |
349 | | TEST(UrlClassifierVLPrefixSet, TinyPrefixSet) |
350 | 0 | { |
351 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
352 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
353 | 0 |
|
354 | 0 | PrefixStringMap map; |
355 | 0 | _PrefixArray array = { _Prefix("AAAA"), |
356 | 0 | _Prefix("11112222333344445555666677778888"), |
357 | 0 | }; |
358 | 0 |
|
359 | 0 | SetupPrefixMap(array, map); |
360 | 0 | pset->SetPrefixes(map); |
361 | 0 |
|
362 | 0 | DoExpectedLookup(pset, array); |
363 | 0 |
|
364 | 0 | DoRandomLookup(pset, 1000, array); |
365 | 0 |
|
366 | 0 | CheckContent(pset, map); |
367 | 0 | } |
368 | | |
369 | | // Test empty prefix set and IsEmpty function |
370 | | TEST(UrlClassifierVLPrefixSet, EmptyPrefixSet) |
371 | 0 | { |
372 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
373 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
374 | 0 |
|
375 | 0 | bool empty; |
376 | 0 | pset->IsEmpty(&empty); |
377 | 0 | ASSERT_TRUE(empty); |
378 | 0 |
|
379 | 0 | PrefixStringMap map; |
380 | 0 | _PrefixArray array1; |
381 | 0 |
|
382 | 0 | // Lookup an empty array should never match |
383 | 0 | DoRandomLookup(pset, 100, array1); |
384 | 0 |
|
385 | 0 | // Insert an 4-bytes prefix, then IsEmpty should return false |
386 | 0 | _PrefixArray array2 = { _Prefix("test") }; |
387 | 0 | SetupPrefixMap(array2, map); |
388 | 0 | pset->SetPrefixes(map); |
389 | 0 |
|
390 | 0 | pset->IsEmpty(&empty); |
391 | 0 | ASSERT_TRUE(!empty); |
392 | 0 |
|
393 | 0 | _PrefixArray array3 = { _Prefix("test variable length") }; |
394 | 0 |
|
395 | 0 | // Insert an 5~32 bytes prefix, then IsEmpty should return false |
396 | 0 | SetupPrefixMap(array3, map); |
397 | 0 | pset->SetPrefixes(map); |
398 | 0 |
|
399 | 0 | pset->IsEmpty(&empty); |
400 | 0 | ASSERT_TRUE(!empty); |
401 | 0 | } |
402 | | |
403 | | // Test prefix size should only between 4~32 bytes |
404 | | TEST(UrlClassifierVLPrefixSet, MinMaxPrefixSet) |
405 | 0 | { |
406 | 0 | RefPtr<VariableLengthPrefixSet> pset = new VariableLengthPrefixSet; |
407 | 0 | pset->Init(NS_LITERAL_CSTRING("test")); |
408 | 0 |
|
409 | 0 | PrefixStringMap map; |
410 | 0 | { |
411 | 0 | _PrefixArray array = { _Prefix("1234"), |
412 | 0 | _Prefix("ABCDEFGHIJKKMNOP"), |
413 | 0 | _Prefix("1aaa2bbb3ccc4ddd5eee6fff7ggg8hhh") }; |
414 | 0 |
|
415 | 0 | SetupPrefixMap(array, map); |
416 | 0 | nsresult rv = pset->SetPrefixes(map); |
417 | 0 | ASSERT_TRUE(rv == NS_OK); |
418 | 0 | } |
419 | 0 |
|
420 | 0 | // Prefix size less than 4-bytes should fail |
421 | 0 | { |
422 | 0 | _PrefixArray array = { _Prefix("123") }; |
423 | 0 |
|
424 | 0 | SetupPrefixMap(array, map); |
425 | 0 | nsresult rv = pset->SetPrefixes(map); |
426 | 0 | ASSERT_TRUE(NS_FAILED(rv)); |
427 | 0 | } |
428 | 0 |
|
429 | 0 | // Prefix size greater than 32-bytes should fail |
430 | 0 | { |
431 | 0 | _PrefixArray array = { _Prefix("1aaa2bbb3ccc4ddd5eee6fff7ggg8hhh9") }; |
432 | 0 |
|
433 | 0 | SetupPrefixMap(array, map); |
434 | 0 | nsresult rv = pset->SetPrefixes(map); |
435 | 0 | ASSERT_TRUE(NS_FAILED(rv)); |
436 | 0 | } |
437 | 0 | } |
438 | | |
439 | | // Test save then load prefix set with only 4-bytes prefixes |
440 | | TEST(UrlClassifierVLPrefixSet, LoadSaveFixedLengthPrefixSet) |
441 | 0 | { |
442 | 0 | RefPtr<VariableLengthPrefixSet> save = new VariableLengthPrefixSet; |
443 | 0 | save->Init(NS_LITERAL_CSTRING("test-save")); |
444 | 0 |
|
445 | 0 | _PrefixArray array; |
446 | 0 | RandomPrefixes(10000, 4, 4, array); |
447 | 0 |
|
448 | 0 | PrefixStringMap map; |
449 | 0 | SetupPrefixMap(array, map); |
450 | 0 | save->SetPrefixes(map); |
451 | 0 |
|
452 | 0 | DoExpectedLookup(save, array); |
453 | 0 |
|
454 | 0 | DoRandomLookup(save, 1000, array); |
455 | 0 |
|
456 | 0 | CheckContent(save, map); |
457 | 0 |
|
458 | 0 | nsCOMPtr<nsIFile> file; |
459 | 0 | NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, |
460 | 0 | getter_AddRefs(file)); |
461 | 0 | file->Append(NS_LITERAL_STRING("test.vlpset")); |
462 | 0 |
|
463 | 0 | save->StoreToFile(file); |
464 | 0 |
|
465 | 0 | RefPtr<VariableLengthPrefixSet> load = new VariableLengthPrefixSet; |
466 | 0 | load->Init(NS_LITERAL_CSTRING("test-load")); |
467 | 0 |
|
468 | 0 | load->LoadFromFile(file); |
469 | 0 |
|
470 | 0 | DoExpectedLookup(load, array); |
471 | 0 |
|
472 | 0 | DoRandomLookup(load, 1000, array); |
473 | 0 |
|
474 | 0 | CheckContent(load, map); |
475 | 0 |
|
476 | 0 | file->Remove(false); |
477 | 0 | } |
478 | | |
479 | | // Test save then load prefix set with only 5~32 bytes prefixes |
480 | | TEST(UrlClassifierVLPrefixSet, LoadSaveVariableLengthPrefixSet) |
481 | 0 | { |
482 | 0 | RefPtr<VariableLengthPrefixSet> save = new VariableLengthPrefixSet; |
483 | 0 | save->Init(NS_LITERAL_CSTRING("test-save")); |
484 | 0 |
|
485 | 0 | _PrefixArray array; |
486 | 0 | RandomPrefixes(10000, 5, 32, array); |
487 | 0 |
|
488 | 0 | PrefixStringMap map; |
489 | 0 | SetupPrefixMap(array, map); |
490 | 0 | save->SetPrefixes(map); |
491 | 0 |
|
492 | 0 | DoExpectedLookup(save, array); |
493 | 0 |
|
494 | 0 | DoRandomLookup(save, 1000, array); |
495 | 0 |
|
496 | 0 | CheckContent(save, map); |
497 | 0 |
|
498 | 0 | nsCOMPtr<nsIFile> file; |
499 | 0 | NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, |
500 | 0 | getter_AddRefs(file)); |
501 | 0 | file->Append(NS_LITERAL_STRING("test.vlpset")); |
502 | 0 |
|
503 | 0 | save->StoreToFile(file); |
504 | 0 |
|
505 | 0 | RefPtr<VariableLengthPrefixSet> load = new VariableLengthPrefixSet; |
506 | 0 | load->Init(NS_LITERAL_CSTRING("test-load")); |
507 | 0 |
|
508 | 0 | load->LoadFromFile(file); |
509 | 0 |
|
510 | 0 | DoExpectedLookup(load, array); |
511 | 0 |
|
512 | 0 | DoRandomLookup(load, 1000, array); |
513 | 0 |
|
514 | 0 | CheckContent(load, map); |
515 | 0 |
|
516 | 0 | file->Remove(false); |
517 | 0 | } |
518 | | |
519 | | // Test save then load prefix with both 4 bytes prefixes and 5~32 bytes prefixes |
520 | | TEST(UrlClassifierVLPrefixSet, LoadSavePrefixSet) |
521 | 0 | { |
522 | 0 | RefPtr<VariableLengthPrefixSet> save = new VariableLengthPrefixSet; |
523 | 0 | save->Init(NS_LITERAL_CSTRING("test-save")); |
524 | 0 |
|
525 | 0 | // Try to simulate the real case that most prefixes are 4bytes |
526 | 0 | _PrefixArray array; |
527 | 0 | RandomPrefixes(20000, 4, 4, array); |
528 | 0 | RandomPrefixes(1000, 5, 32, array); |
529 | 0 |
|
530 | 0 | PrefixStringMap map; |
531 | 0 | SetupPrefixMap(array, map); |
532 | 0 | save->SetPrefixes(map); |
533 | 0 |
|
534 | 0 | DoExpectedLookup(save, array); |
535 | 0 |
|
536 | 0 | DoRandomLookup(save, 1000, array); |
537 | 0 |
|
538 | 0 | CheckContent(save, map); |
539 | 0 |
|
540 | 0 | nsCOMPtr<nsIFile> file; |
541 | 0 | NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, |
542 | 0 | getter_AddRefs(file)); |
543 | 0 | file->Append(NS_LITERAL_STRING("test.vlpset")); |
544 | 0 |
|
545 | 0 | save->StoreToFile(file); |
546 | 0 |
|
547 | 0 | RefPtr<VariableLengthPrefixSet> load = new VariableLengthPrefixSet; |
548 | 0 | load->Init(NS_LITERAL_CSTRING("test-load")); |
549 | 0 |
|
550 | 0 | load->LoadFromFile(file); |
551 | 0 |
|
552 | 0 | DoExpectedLookup(load, array); |
553 | 0 |
|
554 | 0 | DoRandomLookup(load, 1000, array); |
555 | 0 |
|
556 | 0 | CheckContent(load, map); |
557 | 0 |
|
558 | 0 | file->Remove(false); |
559 | 0 | } |