1 // Copyright (c) 2010 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. 4 5 #include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h" 6 7 #include "base/file_util.h" 8 9 namespace { 10 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; 18 const int kSubChunk3 = 6; 19 20 const SBFullHash kHash1 = SBFullHashFromString("one"); 21 const SBFullHash kHash2 = SBFullHashFromString("two"); 22 const SBFullHash kHash3 = SBFullHashFromString("three"); 23 const SBFullHash kHash4 = SBFullHashFromString("four"); 24 const SBFullHash kHash5 = SBFullHashFromString("five"); 25 26 } // namespace 27 28 void SafeBrowsingStoreTestEmpty(SafeBrowsingStore* store) { 29 EXPECT_TRUE(store->BeginUpdate()); 30 31 std::vector<int> chunks; 32 store->GetAddChunks(&chunks); 33 EXPECT_TRUE(chunks.empty()); 34 store->GetSubChunks(&chunks); 35 EXPECT_TRUE(chunks.empty()); 36 37 // Shouldn't see anything, but anything is a big set to test. 38 EXPECT_FALSE(store->CheckAddChunk(0)); 39 EXPECT_FALSE(store->CheckAddChunk(1)); 40 EXPECT_FALSE(store->CheckAddChunk(-1)); 41 42 EXPECT_FALSE(store->CheckSubChunk(0)); 43 EXPECT_FALSE(store->CheckSubChunk(1)); 44 EXPECT_FALSE(store->CheckSubChunk(-1)); 45 46 std::vector<SBAddFullHash> pending_adds; 47 std::set<SBPrefix> prefix_misses; 48 std::vector<SBAddPrefix> add_prefixes_result; 49 std::vector<SBAddFullHash> add_full_hashes_result; 50 51 EXPECT_TRUE(store->FinishUpdate(pending_adds, 52 prefix_misses, 53 &add_prefixes_result, 54 &add_full_hashes_result)); 55 EXPECT_TRUE(add_prefixes_result.empty()); 56 EXPECT_TRUE(add_full_hashes_result.empty()); 57 } 58 59 void SafeBrowsingStoreTestStorePrefix(SafeBrowsingStore* store) { 60 EXPECT_TRUE(store->BeginUpdate()); 61 62 const base::Time now = base::Time::Now(); 63 64 EXPECT_TRUE(store->BeginChunk()); 65 store->SetAddChunk(kAddChunk1); 66 EXPECT_TRUE(store->CheckAddChunk(kAddChunk1)); 67 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash1.prefix)); 68 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash2.prefix)); 69 EXPECT_TRUE(store->WriteAddHash(kAddChunk1, now, kHash2)); 70 71 store->SetSubChunk(kSubChunk1); 72 EXPECT_TRUE(store->CheckSubChunk(kSubChunk1)); 73 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk3, kHash3.prefix)); 74 EXPECT_TRUE(store->WriteSubHash(kSubChunk1, kAddChunk3, kHash3)); 75 EXPECT_TRUE(store->FinishChunk()); 76 77 // Chunk numbers shouldn't leak over. 78 EXPECT_FALSE(store->CheckAddChunk(kSubChunk1)); 79 EXPECT_FALSE(store->CheckAddChunk(kAddChunk3)); 80 EXPECT_FALSE(store->CheckSubChunk(kAddChunk1)); 81 82 std::vector<int> chunks; 83 store->GetAddChunks(&chunks); 84 ASSERT_EQ(1U, chunks.size()); 85 EXPECT_EQ(kAddChunk1, chunks[0]); 86 87 store->GetSubChunks(&chunks); 88 ASSERT_EQ(1U, chunks.size()); 89 EXPECT_EQ(kSubChunk1, chunks[0]); 90 91 std::vector<SBAddFullHash> pending_adds; 92 std::set<SBPrefix> prefix_misses; 93 std::vector<SBAddPrefix> add_prefixes_result; 94 std::vector<SBAddFullHash> add_full_hashes_result; 95 96 EXPECT_TRUE(store->FinishUpdate(pending_adds, 97 prefix_misses, 98 &add_prefixes_result, 99 &add_full_hashes_result)); 100 101 ASSERT_EQ(2U, add_prefixes_result.size()); 102 EXPECT_EQ(kAddChunk1, add_prefixes_result[0].chunk_id); 103 EXPECT_EQ(kHash1.prefix, add_prefixes_result[0].prefix); 104 EXPECT_EQ(kAddChunk1, add_prefixes_result[1].chunk_id); 105 EXPECT_EQ(kHash2.prefix, add_prefixes_result[1].prefix); 106 107 ASSERT_EQ(1U, add_full_hashes_result.size()); 108 EXPECT_EQ(kAddChunk1, add_full_hashes_result[0].chunk_id); 109 // EXPECT_TRUE(add_full_hashes_result[0].received == now)? 110 EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received); 111 EXPECT_TRUE(SBFullHashEq(kHash2, add_full_hashes_result[0].full_hash)); 112 113 add_prefixes_result.clear(); 114 add_full_hashes_result.clear(); 115 116 EXPECT_TRUE(store->BeginUpdate()); 117 118 // Still has the chunks expected in the next update. 119 store->GetAddChunks(&chunks); 120 ASSERT_EQ(1U, chunks.size()); 121 EXPECT_EQ(kAddChunk1, chunks[0]); 122 123 store->GetSubChunks(&chunks); 124 ASSERT_EQ(1U, chunks.size()); 125 EXPECT_EQ(kSubChunk1, chunks[0]); 126 127 EXPECT_TRUE(store->CheckAddChunk(kAddChunk1)); 128 EXPECT_TRUE(store->CheckSubChunk(kSubChunk1)); 129 130 EXPECT_TRUE(store->FinishUpdate(pending_adds, 131 prefix_misses, 132 &add_prefixes_result, 133 &add_full_hashes_result)); 134 135 // Still has the expected contents. 136 ASSERT_EQ(2U, add_prefixes_result.size()); 137 EXPECT_EQ(kAddChunk1, add_prefixes_result[0].chunk_id); 138 EXPECT_EQ(kHash1.prefix, add_prefixes_result[0].prefix); 139 EXPECT_EQ(kAddChunk1, add_prefixes_result[1].chunk_id); 140 EXPECT_EQ(kHash2.prefix, add_prefixes_result[1].prefix); 141 142 ASSERT_EQ(1U, add_full_hashes_result.size()); 143 EXPECT_EQ(kAddChunk1, add_full_hashes_result[0].chunk_id); 144 EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received); 145 EXPECT_TRUE(SBFullHashEq(kHash2, add_full_hashes_result[0].full_hash)); 146 } 147 148 void SafeBrowsingStoreTestSubKnockout(SafeBrowsingStore* store) { 149 EXPECT_TRUE(store->BeginUpdate()); 150 151 const base::Time now = base::Time::Now(); 152 153 EXPECT_TRUE(store->BeginChunk()); 154 store->SetAddChunk(kAddChunk1); 155 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash1.prefix)); 156 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash2.prefix)); 157 EXPECT_TRUE(store->WriteAddHash(kAddChunk1, now, kHash2)); 158 159 store->SetSubChunk(kSubChunk1); 160 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk3, kHash3.prefix)); 161 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk1, kHash2.prefix)); 162 EXPECT_TRUE(store->FinishChunk()); 163 164 std::vector<SBAddFullHash> pending_adds; 165 std::set<SBPrefix> prefix_misses; 166 std::vector<SBAddPrefix> add_prefixes_result; 167 std::vector<SBAddFullHash> add_full_hashes_result; 168 169 EXPECT_TRUE(store->FinishUpdate(pending_adds, 170 prefix_misses, 171 &add_prefixes_result, 172 &add_full_hashes_result)); 173 174 // Knocked out the chunk expected. 175 ASSERT_EQ(1U, add_prefixes_result.size()); 176 EXPECT_EQ(kAddChunk1, add_prefixes_result[0].chunk_id); 177 EXPECT_EQ(kHash1.prefix, add_prefixes_result[0].prefix); 178 EXPECT_TRUE(add_full_hashes_result.empty()); 179 180 add_prefixes_result.clear(); 181 182 EXPECT_TRUE(store->BeginUpdate()); 183 184 // This add should be knocked out by an existing sub. 185 EXPECT_TRUE(store->BeginChunk()); 186 store->SetAddChunk(kAddChunk3); 187 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk3, kHash3.prefix)); 188 EXPECT_TRUE(store->FinishChunk()); 189 190 EXPECT_TRUE(store->FinishUpdate(pending_adds, 191 prefix_misses, 192 &add_prefixes_result, 193 &add_full_hashes_result)); 194 EXPECT_EQ(1U, add_prefixes_result.size()); 195 EXPECT_EQ(kAddChunk1, add_prefixes_result[0].chunk_id); 196 EXPECT_EQ(kHash1.prefix, add_prefixes_result[0].prefix); 197 EXPECT_TRUE(add_full_hashes_result.empty()); 198 199 add_prefixes_result.clear(); 200 201 EXPECT_TRUE(store->BeginUpdate()); 202 203 // But by here the sub should be gone, so it should stick this time. 204 EXPECT_TRUE(store->BeginChunk()); 205 store->SetAddChunk(kAddChunk3); 206 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk3, kHash3.prefix)); 207 EXPECT_TRUE(store->FinishChunk()); 208 209 EXPECT_TRUE(store->FinishUpdate(pending_adds, 210 prefix_misses, 211 &add_prefixes_result, 212 &add_full_hashes_result)); 213 ASSERT_EQ(2U, add_prefixes_result.size()); 214 EXPECT_EQ(kAddChunk1, add_prefixes_result[0].chunk_id); 215 EXPECT_EQ(kHash1.prefix, add_prefixes_result[0].prefix); 216 EXPECT_EQ(kAddChunk3, add_prefixes_result[1].chunk_id); 217 EXPECT_EQ(kHash3.prefix, add_prefixes_result[1].prefix); 218 EXPECT_TRUE(add_full_hashes_result.empty()); 219 } 220 221 void SafeBrowsingStoreTestDeleteChunks(SafeBrowsingStore* store) { 222 EXPECT_TRUE(store->BeginUpdate()); 223 224 const base::Time now = base::Time::Now(); 225 226 // A chunk which will be deleted. 227 EXPECT_FALSE(store->CheckAddChunk(kAddChunk1)); 228 store->SetAddChunk(kAddChunk1); 229 EXPECT_TRUE(store->BeginChunk()); 230 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash1.prefix)); 231 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash2.prefix)); 232 EXPECT_TRUE(store->WriteAddHash(kAddChunk1, now, kHash2)); 233 EXPECT_TRUE(store->FinishChunk()); 234 235 // Another which won't. 236 EXPECT_FALSE(store->CheckAddChunk(kAddChunk2)); 237 store->SetAddChunk(kAddChunk2); 238 EXPECT_TRUE(store->BeginChunk()); 239 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk2, kHash3.prefix)); 240 EXPECT_TRUE(store->WriteAddHash(kAddChunk2, now, kHash3)); 241 EXPECT_TRUE(store->FinishChunk()); 242 243 // A sub chunk to delete. 244 EXPECT_FALSE(store->CheckSubChunk(kSubChunk1)); 245 store->SetSubChunk(kSubChunk1); 246 EXPECT_TRUE(store->BeginChunk()); 247 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk3, kHash4.prefix)); 248 EXPECT_TRUE(store->WriteSubHash(kSubChunk1, kAddChunk3, kHash4)); 249 EXPECT_TRUE(store->FinishChunk()); 250 251 // A sub chunk to keep. 252 EXPECT_FALSE(store->CheckSubChunk(kSubChunk2)); 253 store->SetSubChunk(kSubChunk2); 254 EXPECT_TRUE(store->BeginChunk()); 255 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk2, kAddChunk4, kHash5.prefix)); 256 EXPECT_TRUE(store->WriteSubHash(kSubChunk2, kAddChunk4, kHash5)); 257 EXPECT_TRUE(store->FinishChunk()); 258 259 store->DeleteAddChunk(kAddChunk1); 260 store->DeleteSubChunk(kSubChunk1); 261 262 // Not actually deleted until finish. 263 EXPECT_TRUE(store->CheckAddChunk(kAddChunk1)); 264 EXPECT_TRUE(store->CheckAddChunk(kAddChunk2)); 265 EXPECT_TRUE(store->CheckSubChunk(kSubChunk1)); 266 EXPECT_TRUE(store->CheckSubChunk(kSubChunk2)); 267 268 std::vector<SBAddFullHash> pending_adds; 269 std::set<SBPrefix> prefix_misses; 270 std::vector<SBAddPrefix> add_prefixes_result; 271 std::vector<SBAddFullHash> add_full_hashes_result; 272 273 EXPECT_TRUE(store->FinishUpdate(pending_adds, 274 prefix_misses, 275 &add_prefixes_result, 276 &add_full_hashes_result)); 277 278 EXPECT_EQ(1U, add_prefixes_result.size()); 279 EXPECT_EQ(kAddChunk2, add_prefixes_result[0].chunk_id); 280 EXPECT_EQ(kHash3.prefix, add_prefixes_result[0].prefix); 281 EXPECT_EQ(1U, add_full_hashes_result.size()); 282 EXPECT_EQ(kAddChunk2, add_full_hashes_result[0].chunk_id); 283 EXPECT_EQ(now.ToTimeT(), add_full_hashes_result[0].received); 284 EXPECT_TRUE(SBFullHashEq(kHash3, add_full_hashes_result[0].full_hash)); 285 286 // Expected chunks are there in another update. 287 EXPECT_TRUE(store->BeginUpdate()); 288 EXPECT_FALSE(store->CheckAddChunk(kAddChunk1)); 289 EXPECT_TRUE(store->CheckAddChunk(kAddChunk2)); 290 EXPECT_FALSE(store->CheckSubChunk(kSubChunk1)); 291 EXPECT_TRUE(store->CheckSubChunk(kSubChunk2)); 292 293 // Delete them, too. 294 store->DeleteAddChunk(kAddChunk2); 295 store->DeleteSubChunk(kSubChunk2); 296 297 add_prefixes_result.clear(); 298 add_full_hashes_result.clear(); 299 EXPECT_TRUE(store->FinishUpdate(pending_adds, 300 prefix_misses, 301 &add_prefixes_result, 302 &add_full_hashes_result)); 303 304 // Expect no more chunks. 305 EXPECT_TRUE(store->BeginUpdate()); 306 EXPECT_FALSE(store->CheckAddChunk(kAddChunk1)); 307 EXPECT_FALSE(store->CheckAddChunk(kAddChunk2)); 308 EXPECT_FALSE(store->CheckSubChunk(kSubChunk1)); 309 EXPECT_FALSE(store->CheckSubChunk(kSubChunk2)); 310 add_prefixes_result.clear(); 311 add_full_hashes_result.clear(); 312 EXPECT_TRUE(store->FinishUpdate(pending_adds, 313 prefix_misses, 314 &add_prefixes_result, 315 &add_full_hashes_result)); 316 EXPECT_TRUE(add_prefixes_result.empty()); 317 EXPECT_TRUE(add_full_hashes_result.empty()); 318 } 319 320 void SafeBrowsingStoreTestDelete(SafeBrowsingStore* store, 321 const FilePath& filename) { 322 // Delete should work if the file wasn't there in the first place. 323 EXPECT_FALSE(file_util::PathExists(filename)); 324 EXPECT_TRUE(store->Delete()); 325 326 // Create a store file. 327 EXPECT_TRUE(store->BeginUpdate()); 328 329 EXPECT_TRUE(store->BeginChunk()); 330 store->SetAddChunk(kAddChunk1); 331 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash1.prefix)); 332 EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kHash2.prefix)); 333 334 store->SetSubChunk(kSubChunk1); 335 EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk3, kHash3.prefix)); 336 EXPECT_TRUE(store->FinishChunk()); 337 338 std::vector<SBAddFullHash> pending_adds; 339 std::set<SBPrefix> prefix_misses; 340 std::vector<SBAddPrefix> add_prefixes_result; 341 std::vector<SBAddFullHash> add_full_hashes_result; 342 343 EXPECT_TRUE(store->FinishUpdate(pending_adds, 344 prefix_misses, 345 &add_prefixes_result, 346 &add_full_hashes_result)); 347 348 EXPECT_TRUE(file_util::PathExists(filename)); 349 EXPECT_TRUE(store->Delete()); 350 EXPECT_FALSE(file_util::PathExists(filename)); 351 } 352