/src/mozilla-central/toolkit/components/url-classifier/tests/gtest/TestChunkSet.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include <stdio.h> |
7 | | #include <stdlib.h> |
8 | | #include <set> |
9 | | |
10 | | #include "gtest/gtest.h" |
11 | | #include "ChunkSet.h" |
12 | | #include "mozilla/ArrayUtils.h" |
13 | | |
14 | | TEST(UrlClassifierChunkSet, Empty) |
15 | 0 | { |
16 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
17 | 0 | mozilla::safebrowsing::ChunkSet removeSet; |
18 | 0 |
|
19 | 0 | removeSet.Set(0); |
20 | 0 |
|
21 | 0 | ASSERT_FALSE(chunkSet.Has(0)); |
22 | 0 | ASSERT_FALSE(chunkSet.Has(1)); |
23 | 0 | ASSERT_TRUE(chunkSet.Remove(removeSet) == NS_OK); |
24 | 0 | ASSERT_TRUE(chunkSet.Length() == 0); |
25 | 0 |
|
26 | 0 | chunkSet.Set(0); |
27 | 0 |
|
28 | 0 | ASSERT_TRUE(chunkSet.Has(0)); |
29 | 0 | ASSERT_TRUE(chunkSet.Length() == 1); |
30 | 0 | ASSERT_TRUE(chunkSet.Remove(removeSet) == NS_OK); |
31 | 0 | ASSERT_FALSE(chunkSet.Has(0)); |
32 | 0 | ASSERT_TRUE(chunkSet.Length() == 0); |
33 | 0 | } |
34 | | |
35 | | TEST(UrlClassifierChunkSet, Main) |
36 | 0 | { |
37 | 0 | static int testVals[] = {2, 1, 5, 6, 8, 7, 14, 10, 12, 13}; |
38 | 0 |
|
39 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
40 | 0 |
|
41 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
42 | 0 | chunkSet.Set(testVals[i]); |
43 | 0 | } |
44 | 0 |
|
45 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
46 | 0 | ASSERT_TRUE(chunkSet.Has(testVals[i])); |
47 | 0 | } |
48 | 0 |
|
49 | 0 | ASSERT_FALSE(chunkSet.Has(3)); |
50 | 0 | ASSERT_FALSE(chunkSet.Has(4)); |
51 | 0 | ASSERT_FALSE(chunkSet.Has(9)); |
52 | 0 | ASSERT_FALSE(chunkSet.Has(11)); |
53 | 0 |
|
54 | 0 | ASSERT_TRUE(chunkSet.Length() == MOZ_ARRAY_LENGTH(testVals)); |
55 | 0 | } |
56 | | |
57 | | TEST(UrlClassifierChunkSet, Merge) |
58 | 0 | { |
59 | 0 | static int testVals[] = {2, 1, 5, 6, 8, 7, 14, 10, 12, 13}; |
60 | 0 | static int mergeVals[] = {9, 3, 4, 20, 14, 16}; |
61 | 0 |
|
62 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
63 | 0 | mozilla::safebrowsing::ChunkSet mergeSet; |
64 | 0 |
|
65 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
66 | 0 | chunkSet.Set(testVals[i]); |
67 | 0 | } |
68 | 0 |
|
69 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
70 | 0 | mergeSet.Set(mergeVals[i]); |
71 | 0 | } |
72 | 0 |
|
73 | 0 | chunkSet.Merge(mergeSet); |
74 | 0 |
|
75 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
76 | 0 | ASSERT_TRUE(chunkSet.Has(testVals[i])); |
77 | 0 | } |
78 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
79 | 0 | ASSERT_TRUE(chunkSet.Has(mergeVals[i])); |
80 | 0 | } |
81 | 0 |
|
82 | 0 | // -1 because 14 is duplicated in both sets |
83 | 0 | ASSERT_TRUE(chunkSet.Length() == |
84 | 0 | MOZ_ARRAY_LENGTH(testVals) + MOZ_ARRAY_LENGTH(mergeVals) - 1); |
85 | 0 |
|
86 | 0 | ASSERT_FALSE(chunkSet.Has(11)); |
87 | 0 | ASSERT_FALSE(chunkSet.Has(15)); |
88 | 0 | ASSERT_FALSE(chunkSet.Has(17)); |
89 | 0 | ASSERT_FALSE(chunkSet.Has(18)); |
90 | 0 | ASSERT_FALSE(chunkSet.Has(19)); |
91 | 0 | } |
92 | | |
93 | | TEST(UrlClassifierChunkSet, Merge2) |
94 | 0 | { |
95 | 0 | static int testVals[] = {2, 1, 5, 6, 8, 7, 14, 10, 12, 13}; |
96 | 0 | static int mergeVals[] = {9, 3, 4, 20, 14, 16}; |
97 | 0 | static int mergeVals2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; |
98 | 0 |
|
99 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
100 | 0 | mozilla::safebrowsing::ChunkSet mergeSet; |
101 | 0 | mozilla::safebrowsing::ChunkSet mergeSet2; |
102 | 0 |
|
103 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
104 | 0 | chunkSet.Set(testVals[i]); |
105 | 0 | } |
106 | 0 |
|
107 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
108 | 0 | mergeSet.Set(mergeVals[i]); |
109 | 0 | } |
110 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals2); i++) { |
111 | 0 | mergeSet2.Set(mergeVals2[i]); |
112 | 0 | } |
113 | 0 |
|
114 | 0 | chunkSet.Merge(mergeSet); |
115 | 0 | chunkSet.Merge(mergeSet2); |
116 | 0 |
|
117 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
118 | 0 | ASSERT_TRUE(chunkSet.Has(testVals[i])); |
119 | 0 | } |
120 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
121 | 0 | ASSERT_TRUE(chunkSet.Has(mergeVals[i])); |
122 | 0 | } |
123 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals2); i++) { |
124 | 0 | ASSERT_TRUE(chunkSet.Has(mergeVals2[i])); |
125 | 0 | } |
126 | 0 |
|
127 | 0 | ASSERT_FALSE(chunkSet.Has(15)); |
128 | 0 | ASSERT_FALSE(chunkSet.Has(17)); |
129 | 0 | ASSERT_FALSE(chunkSet.Has(18)); |
130 | 0 | ASSERT_FALSE(chunkSet.Has(19)); |
131 | 0 | } |
132 | | |
133 | | TEST(UrlClassifierChunkSet, Stress) |
134 | 0 | { |
135 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
136 | 0 | mozilla::safebrowsing::ChunkSet mergeSet; |
137 | 0 | std::set<int> refSet; |
138 | 0 | std::set<int> refMergeSet; |
139 | 0 | static const int TEST_ITERS = 7000; |
140 | 0 | static const int REMOVE_ITERS = 3000; |
141 | 0 | static const int TEST_RANGE = 10000; |
142 | 0 |
|
143 | 0 | // Construction by Set |
144 | 0 | for (int i = 0; i < TEST_ITERS; i++) { |
145 | 0 | int chunk = rand() % TEST_RANGE; |
146 | 0 | chunkSet.Set(chunk); |
147 | 0 | refSet.insert(chunk); |
148 | 0 | } |
149 | 0 |
|
150 | 0 | // Same elements as reference set |
151 | 0 | for (auto it = refSet.begin(); it != refSet.end(); ++it) { |
152 | 0 | ASSERT_TRUE(chunkSet.Has(*it)); |
153 | 0 | } |
154 | 0 |
|
155 | 0 | // Hole punching via Remove |
156 | 0 | for (int i = 0; i < REMOVE_ITERS; i++) { |
157 | 0 | int chunk = rand() % TEST_RANGE; |
158 | 0 | mozilla::safebrowsing::ChunkSet helpChunk; |
159 | 0 | helpChunk.Set(chunk); |
160 | 0 |
|
161 | 0 | chunkSet.Remove(helpChunk); |
162 | 0 | refSet.erase(chunk); |
163 | 0 |
|
164 | 0 | ASSERT_FALSE(chunkSet.Has(chunk)); |
165 | 0 | } |
166 | 0 |
|
167 | 0 | // Should have chunks present in reference set |
168 | 0 | // Should not have chunks absent in reference set |
169 | 0 | for (int it = 0; it < TEST_RANGE; ++it) { |
170 | 0 | auto found = refSet.find(it); |
171 | 0 | if (chunkSet.Has(it)) { |
172 | 0 | ASSERT_FALSE(found == refSet.end()); |
173 | 0 | } else { |
174 | 0 | ASSERT_TRUE(found == refSet.end()); |
175 | 0 | } |
176 | 0 | } |
177 | 0 |
|
178 | 0 | // Construct set to merge with |
179 | 0 | for (int i = 0; i < TEST_ITERS; i++) { |
180 | 0 | int chunk = rand() % TEST_RANGE; |
181 | 0 | mergeSet.Set(chunk); |
182 | 0 | refMergeSet.insert(chunk); |
183 | 0 | } |
184 | 0 |
|
185 | 0 | // Merge set constructed correctly |
186 | 0 | for (auto it = refMergeSet.begin(); it != refMergeSet.end(); ++it) { |
187 | 0 | ASSERT_TRUE(mergeSet.Has(*it)); |
188 | 0 | } |
189 | 0 |
|
190 | 0 | mozilla::safebrowsing::ChunkSet origSet; |
191 | 0 | origSet = chunkSet; |
192 | 0 |
|
193 | 0 | chunkSet.Merge(mergeSet); |
194 | 0 | refSet.insert(refMergeSet.begin(), refMergeSet.end()); |
195 | 0 |
|
196 | 0 | // Check for presence of elements from both source |
197 | 0 | // Should not have chunks absent in reference set |
198 | 0 | for (int it = 0; it < TEST_RANGE; ++it) { |
199 | 0 | auto found = refSet.find(it); |
200 | 0 | if (chunkSet.Has(it)) { |
201 | 0 | ASSERT_FALSE(found == refSet.end()); |
202 | 0 | } else { |
203 | 0 | ASSERT_TRUE(found == refSet.end()); |
204 | 0 | } |
205 | 0 | } |
206 | 0 |
|
207 | 0 | // Unmerge |
208 | 0 | chunkSet.Remove(origSet); |
209 | 0 | for (int it = 0; it < TEST_RANGE; ++it) { |
210 | 0 | if (origSet.Has(it)) { |
211 | 0 | ASSERT_FALSE(chunkSet.Has(it)); |
212 | 0 | } else if (mergeSet.Has(it)) { |
213 | 0 | ASSERT_TRUE(chunkSet.Has(it)); |
214 | 0 | } |
215 | 0 | } |
216 | 0 | } |
217 | | |
218 | | TEST(UrlClassifierChunkSet, RemoveClear) |
219 | 0 | { |
220 | 0 | static int testVals[] = {2, 1, 5, 6, 8, 7, 14, 10, 12, 13}; |
221 | 0 | static int mergeVals[] = {3, 4, 9, 16, 20}; |
222 | 0 |
|
223 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
224 | 0 | mozilla::safebrowsing::ChunkSet mergeSet; |
225 | 0 | mozilla::safebrowsing::ChunkSet removeSet; |
226 | 0 |
|
227 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
228 | 0 | chunkSet.Set(testVals[i]); |
229 | 0 | removeSet.Set(testVals[i]); |
230 | 0 | } |
231 | 0 |
|
232 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
233 | 0 | mergeSet.Set(mergeVals[i]); |
234 | 0 | } |
235 | 0 |
|
236 | 0 | ASSERT_TRUE(chunkSet.Merge(mergeSet) == NS_OK); |
237 | 0 | ASSERT_TRUE(chunkSet.Remove(removeSet) == NS_OK); |
238 | 0 |
|
239 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
240 | 0 | ASSERT_TRUE(chunkSet.Has(mergeVals[i])); |
241 | 0 | } |
242 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
243 | 0 | ASSERT_FALSE(chunkSet.Has(testVals[i])); |
244 | 0 | } |
245 | 0 |
|
246 | 0 | chunkSet.Clear(); |
247 | 0 |
|
248 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
249 | 0 | ASSERT_FALSE(chunkSet.Has(mergeVals[i])); |
250 | 0 | } |
251 | 0 | } |
252 | | |
253 | | TEST(UrlClassifierChunkSet, Serialize) |
254 | 0 | { |
255 | 0 | static int testVals[] = {2, 1, 5, 6, 8, 7, 14, 10, 12, 13}; |
256 | 0 | static int mergeVals[] = {3, 4, 9, 16, 20}; |
257 | 0 |
|
258 | 0 | mozilla::safebrowsing::ChunkSet chunkSet; |
259 | 0 | mozilla::safebrowsing::ChunkSet mergeSet; |
260 | 0 |
|
261 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(testVals); i++) { |
262 | 0 | chunkSet.Set(testVals[i]); |
263 | 0 | } |
264 | 0 |
|
265 | 0 | for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mergeVals); i++) { |
266 | 0 | mergeSet.Set(mergeVals[i]); |
267 | 0 | } |
268 | 0 |
|
269 | 0 | chunkSet.Merge(mergeSet); |
270 | 0 |
|
271 | 0 | nsAutoCString mergeResult; |
272 | 0 | chunkSet.Serialize(mergeResult); |
273 | 0 |
|
274 | 0 | printf("mergeResult: %s\n", mergeResult.get()); |
275 | 0 |
|
276 | 0 | nsAutoCString expected(NS_LITERAL_CSTRING("1-10,12-14,16,20")); |
277 | 0 |
|
278 | 0 | ASSERT_TRUE(mergeResult.Equals(expected)); |
279 | 0 | } |