1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
7 #include "base/file_util.h"
11 const int kAddChunk1
= 1;
12 const int kAddChunk2
= 3;
13 const int kAddChunk3
= 5;
14 const int kAddChunk4
= 7;
15 // Disjoint chunk numbers for subs to flush out typos.
16 const int kSubChunk1
= 2;
17 const int kSubChunk2
= 4;
19 const SBFullHash kHash1
= SBFullHashFromString("one");
20 const SBFullHash kHash2
= SBFullHashFromString("two");
21 const SBFullHash kHash3
= SBFullHashFromString("three");
22 const SBFullHash kHash4
= SBFullHashFromString("four");
23 const SBFullHash kHash5
= SBFullHashFromString("five");
27 void SafeBrowsingStoreTestEmpty(SafeBrowsingStore
* store
) {
28 EXPECT_TRUE(store
->BeginUpdate());
30 std::vector
<int> chunks
;
31 store
->GetAddChunks(&chunks
);
32 EXPECT_TRUE(chunks
.empty());
33 store
->GetSubChunks(&chunks
);
34 EXPECT_TRUE(chunks
.empty());
36 // Shouldn't see anything, but anything is a big set to test.
37 EXPECT_FALSE(store
->CheckAddChunk(0));
38 EXPECT_FALSE(store
->CheckAddChunk(1));
39 EXPECT_FALSE(store
->CheckAddChunk(-1));
41 EXPECT_FALSE(store
->CheckSubChunk(0));
42 EXPECT_FALSE(store
->CheckSubChunk(1));
43 EXPECT_FALSE(store
->CheckSubChunk(-1));
45 std::vector
<SBAddFullHash
> pending_adds
;
46 SBAddPrefixes add_prefixes_result
;
47 std::vector
<SBAddFullHash
> add_full_hashes_result
;
49 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
51 &add_full_hashes_result
));
52 EXPECT_TRUE(add_prefixes_result
.empty());
53 EXPECT_TRUE(add_full_hashes_result
.empty());
56 void SafeBrowsingStoreTestStorePrefix(SafeBrowsingStore
* store
) {
57 EXPECT_TRUE(store
->BeginUpdate());
59 const base::Time now
= base::Time::Now();
61 EXPECT_TRUE(store
->BeginChunk());
62 store
->SetAddChunk(kAddChunk1
);
63 EXPECT_TRUE(store
->CheckAddChunk(kAddChunk1
));
64 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash1
.prefix
));
65 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash2
.prefix
));
66 EXPECT_TRUE(store
->WriteAddHash(kAddChunk1
, now
, kHash2
));
68 store
->SetSubChunk(kSubChunk1
);
69 EXPECT_TRUE(store
->CheckSubChunk(kSubChunk1
));
70 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk1
, kAddChunk3
, kHash3
.prefix
));
71 EXPECT_TRUE(store
->WriteSubHash(kSubChunk1
, kAddChunk3
, kHash3
));
72 EXPECT_TRUE(store
->FinishChunk());
74 // Chunk numbers shouldn't leak over.
75 EXPECT_FALSE(store
->CheckAddChunk(kSubChunk1
));
76 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk3
));
77 EXPECT_FALSE(store
->CheckSubChunk(kAddChunk1
));
79 std::vector
<int> chunks
;
80 store
->GetAddChunks(&chunks
);
81 ASSERT_EQ(1U, chunks
.size());
82 EXPECT_EQ(kAddChunk1
, chunks
[0]);
84 store
->GetSubChunks(&chunks
);
85 ASSERT_EQ(1U, chunks
.size());
86 EXPECT_EQ(kSubChunk1
, chunks
[0]);
88 std::vector
<SBAddFullHash
> pending_adds
;
89 SBAddPrefixes add_prefixes_result
;
90 std::vector
<SBAddFullHash
> add_full_hashes_result
;
92 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
94 &add_full_hashes_result
));
96 ASSERT_EQ(2U, add_prefixes_result
.size());
97 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[0].chunk_id
);
98 EXPECT_EQ(kHash1
.prefix
, add_prefixes_result
[0].prefix
);
99 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[1].chunk_id
);
100 EXPECT_EQ(kHash2
.prefix
, add_prefixes_result
[1].prefix
);
102 ASSERT_EQ(1U, add_full_hashes_result
.size());
103 EXPECT_EQ(kAddChunk1
, add_full_hashes_result
[0].chunk_id
);
104 // EXPECT_TRUE(add_full_hashes_result[0].received == now)?
105 EXPECT_EQ(now
.ToTimeT(), add_full_hashes_result
[0].received
);
106 EXPECT_TRUE(SBFullHashEq(kHash2
, add_full_hashes_result
[0].full_hash
));
108 add_prefixes_result
.clear();
109 add_full_hashes_result
.clear();
111 EXPECT_TRUE(store
->BeginUpdate());
113 // Still has the chunks expected in the next update.
114 store
->GetAddChunks(&chunks
);
115 ASSERT_EQ(1U, chunks
.size());
116 EXPECT_EQ(kAddChunk1
, chunks
[0]);
118 store
->GetSubChunks(&chunks
);
119 ASSERT_EQ(1U, chunks
.size());
120 EXPECT_EQ(kSubChunk1
, chunks
[0]);
122 EXPECT_TRUE(store
->CheckAddChunk(kAddChunk1
));
123 EXPECT_TRUE(store
->CheckSubChunk(kSubChunk1
));
125 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
126 &add_prefixes_result
,
127 &add_full_hashes_result
));
129 // Still has the expected contents.
130 ASSERT_EQ(2U, add_prefixes_result
.size());
131 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[0].chunk_id
);
132 EXPECT_EQ(kHash1
.prefix
, add_prefixes_result
[0].prefix
);
133 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[1].chunk_id
);
134 EXPECT_EQ(kHash2
.prefix
, add_prefixes_result
[1].prefix
);
136 ASSERT_EQ(1U, add_full_hashes_result
.size());
137 EXPECT_EQ(kAddChunk1
, add_full_hashes_result
[0].chunk_id
);
138 EXPECT_EQ(now
.ToTimeT(), add_full_hashes_result
[0].received
);
139 EXPECT_TRUE(SBFullHashEq(kHash2
, add_full_hashes_result
[0].full_hash
));
142 void SafeBrowsingStoreTestSubKnockout(SafeBrowsingStore
* store
) {
143 EXPECT_TRUE(store
->BeginUpdate());
145 const base::Time now
= base::Time::Now();
147 EXPECT_TRUE(store
->BeginChunk());
148 store
->SetAddChunk(kAddChunk1
);
149 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash1
.prefix
));
150 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash2
.prefix
));
151 EXPECT_TRUE(store
->WriteAddHash(kAddChunk1
, now
, kHash2
));
153 store
->SetSubChunk(kSubChunk1
);
154 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk1
, kAddChunk3
, kHash3
.prefix
));
155 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk1
, kAddChunk1
, kHash2
.prefix
));
156 EXPECT_TRUE(store
->FinishChunk());
158 std::vector
<SBAddFullHash
> pending_adds
;
159 SBAddPrefixes add_prefixes_result
;
160 std::vector
<SBAddFullHash
> add_full_hashes_result
;
162 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
163 &add_prefixes_result
,
164 &add_full_hashes_result
));
166 // Knocked out the chunk expected.
167 ASSERT_EQ(1U, add_prefixes_result
.size());
168 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[0].chunk_id
);
169 EXPECT_EQ(kHash1
.prefix
, add_prefixes_result
[0].prefix
);
170 EXPECT_TRUE(add_full_hashes_result
.empty());
172 add_prefixes_result
.clear();
174 EXPECT_TRUE(store
->BeginUpdate());
176 // This add should be knocked out by an existing sub.
177 EXPECT_TRUE(store
->BeginChunk());
178 store
->SetAddChunk(kAddChunk3
);
179 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk3
, kHash3
.prefix
));
180 EXPECT_TRUE(store
->FinishChunk());
182 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
183 &add_prefixes_result
,
184 &add_full_hashes_result
));
185 EXPECT_EQ(1U, add_prefixes_result
.size());
186 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[0].chunk_id
);
187 EXPECT_EQ(kHash1
.prefix
, add_prefixes_result
[0].prefix
);
188 EXPECT_TRUE(add_full_hashes_result
.empty());
190 add_prefixes_result
.clear();
192 EXPECT_TRUE(store
->BeginUpdate());
194 // But by here the sub should be gone, so it should stick this time.
195 EXPECT_TRUE(store
->BeginChunk());
196 store
->SetAddChunk(kAddChunk3
);
197 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk3
, kHash3
.prefix
));
198 EXPECT_TRUE(store
->FinishChunk());
200 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
201 &add_prefixes_result
,
202 &add_full_hashes_result
));
203 ASSERT_EQ(2U, add_prefixes_result
.size());
204 EXPECT_EQ(kAddChunk1
, add_prefixes_result
[0].chunk_id
);
205 EXPECT_EQ(kHash1
.prefix
, add_prefixes_result
[0].prefix
);
206 EXPECT_EQ(kAddChunk3
, add_prefixes_result
[1].chunk_id
);
207 EXPECT_EQ(kHash3
.prefix
, add_prefixes_result
[1].prefix
);
208 EXPECT_TRUE(add_full_hashes_result
.empty());
211 void SafeBrowsingStoreTestDeleteChunks(SafeBrowsingStore
* store
) {
212 EXPECT_TRUE(store
->BeginUpdate());
214 const base::Time now
= base::Time::Now();
216 // A chunk which will be deleted.
217 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk1
));
218 store
->SetAddChunk(kAddChunk1
);
219 EXPECT_TRUE(store
->BeginChunk());
220 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash1
.prefix
));
221 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash2
.prefix
));
222 EXPECT_TRUE(store
->WriteAddHash(kAddChunk1
, now
, kHash2
));
223 EXPECT_TRUE(store
->FinishChunk());
225 // Another which won't.
226 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk2
));
227 store
->SetAddChunk(kAddChunk2
);
228 EXPECT_TRUE(store
->BeginChunk());
229 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk2
, kHash3
.prefix
));
230 EXPECT_TRUE(store
->WriteAddHash(kAddChunk2
, now
, kHash3
));
231 EXPECT_TRUE(store
->FinishChunk());
233 // A sub chunk to delete.
234 EXPECT_FALSE(store
->CheckSubChunk(kSubChunk1
));
235 store
->SetSubChunk(kSubChunk1
);
236 EXPECT_TRUE(store
->BeginChunk());
237 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk1
, kAddChunk3
, kHash4
.prefix
));
238 EXPECT_TRUE(store
->WriteSubHash(kSubChunk1
, kAddChunk3
, kHash4
));
239 EXPECT_TRUE(store
->FinishChunk());
241 // A sub chunk to keep.
242 EXPECT_FALSE(store
->CheckSubChunk(kSubChunk2
));
243 store
->SetSubChunk(kSubChunk2
);
244 EXPECT_TRUE(store
->BeginChunk());
245 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk2
, kAddChunk4
, kHash5
.prefix
));
246 EXPECT_TRUE(store
->WriteSubHash(kSubChunk2
, kAddChunk4
, kHash5
));
247 EXPECT_TRUE(store
->FinishChunk());
249 store
->DeleteAddChunk(kAddChunk1
);
250 store
->DeleteSubChunk(kSubChunk1
);
252 // Not actually deleted until finish.
253 EXPECT_TRUE(store
->CheckAddChunk(kAddChunk1
));
254 EXPECT_TRUE(store
->CheckAddChunk(kAddChunk2
));
255 EXPECT_TRUE(store
->CheckSubChunk(kSubChunk1
));
256 EXPECT_TRUE(store
->CheckSubChunk(kSubChunk2
));
258 std::vector
<SBAddFullHash
> pending_adds
;
259 SBAddPrefixes add_prefixes_result
;
260 std::vector
<SBAddFullHash
> add_full_hashes_result
;
262 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
263 &add_prefixes_result
,
264 &add_full_hashes_result
));
266 EXPECT_EQ(1U, add_prefixes_result
.size());
267 EXPECT_EQ(kAddChunk2
, add_prefixes_result
[0].chunk_id
);
268 EXPECT_EQ(kHash3
.prefix
, add_prefixes_result
[0].prefix
);
269 EXPECT_EQ(1U, add_full_hashes_result
.size());
270 EXPECT_EQ(kAddChunk2
, add_full_hashes_result
[0].chunk_id
);
271 EXPECT_EQ(now
.ToTimeT(), add_full_hashes_result
[0].received
);
272 EXPECT_TRUE(SBFullHashEq(kHash3
, add_full_hashes_result
[0].full_hash
));
274 // Expected chunks are there in another update.
275 EXPECT_TRUE(store
->BeginUpdate());
276 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk1
));
277 EXPECT_TRUE(store
->CheckAddChunk(kAddChunk2
));
278 EXPECT_FALSE(store
->CheckSubChunk(kSubChunk1
));
279 EXPECT_TRUE(store
->CheckSubChunk(kSubChunk2
));
282 store
->DeleteAddChunk(kAddChunk2
);
283 store
->DeleteSubChunk(kSubChunk2
);
285 add_prefixes_result
.clear();
286 add_full_hashes_result
.clear();
287 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
288 &add_prefixes_result
,
289 &add_full_hashes_result
));
291 // Expect no more chunks.
292 EXPECT_TRUE(store
->BeginUpdate());
293 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk1
));
294 EXPECT_FALSE(store
->CheckAddChunk(kAddChunk2
));
295 EXPECT_FALSE(store
->CheckSubChunk(kSubChunk1
));
296 EXPECT_FALSE(store
->CheckSubChunk(kSubChunk2
));
297 add_prefixes_result
.clear();
298 add_full_hashes_result
.clear();
299 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
300 &add_prefixes_result
,
301 &add_full_hashes_result
));
302 EXPECT_TRUE(add_prefixes_result
.empty());
303 EXPECT_TRUE(add_full_hashes_result
.empty());
306 void SafeBrowsingStoreTestDelete(SafeBrowsingStore
* store
,
307 const base::FilePath
& filename
) {
308 // Delete should work if the file wasn't there in the first place.
309 EXPECT_FALSE(base::PathExists(filename
));
310 EXPECT_TRUE(store
->Delete());
312 // Create a store file.
313 EXPECT_TRUE(store
->BeginUpdate());
315 EXPECT_TRUE(store
->BeginChunk());
316 store
->SetAddChunk(kAddChunk1
);
317 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash1
.prefix
));
318 EXPECT_TRUE(store
->WriteAddPrefix(kAddChunk1
, kHash2
.prefix
));
320 store
->SetSubChunk(kSubChunk1
);
321 EXPECT_TRUE(store
->WriteSubPrefix(kSubChunk1
, kAddChunk3
, kHash3
.prefix
));
322 EXPECT_TRUE(store
->FinishChunk());
324 std::vector
<SBAddFullHash
> pending_adds
;
325 SBAddPrefixes add_prefixes_result
;
326 std::vector
<SBAddFullHash
> add_full_hashes_result
;
328 EXPECT_TRUE(store
->FinishUpdate(pending_adds
,
329 &add_prefixes_result
,
330 &add_full_hashes_result
));
332 EXPECT_TRUE(base::PathExists(filename
));
333 EXPECT_TRUE(store
->Delete());
334 EXPECT_FALSE(base::PathExists(filename
));