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

Side by Side Diff: components/safe_browsing_db/database_manager_unittest.cc

Issue 2009183002: SafeBrowsing: Implement cache lookup for full hash checks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments Created 4 years, 6 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 | « components/safe_browsing_db/database_manager.cc ('k') | components/safe_browsing_db/util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/safe_browsing_db/database_manager.h" 5 #include "components/safe_browsing_db/database_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 negative_cache_expire_), 54 negative_cache_expire_),
55 base::TimeDelta::FromSeconds(delay_seconds_)); 55 base::TimeDelta::FromSeconds(delay_seconds_));
56 } 56 }
57 57
58 void SetDelaySeconds(int delay) { 58 void SetDelaySeconds(int delay) {
59 delay_seconds_ = delay; 59 delay_seconds_ = delay;
60 } 60 }
61 61
62 void SetNegativeCacheDurationMins(base::Time now, 62 void SetNegativeCacheDurationMins(base::Time now,
63 int negative_cache_duration_mins) { 63 int negative_cache_duration_mins) {
64 negative_cache_expire_ = now + 64 negative_cache_expire_ = negative_cache_duration_mins ? now +
65 base::TimeDelta::FromMinutes(negative_cache_duration_mins); 65 base::TimeDelta::FromMinutes(negative_cache_duration_mins) : now;
Nathan Parker 2016/06/01 17:56:01 Does this ternary conditional do anything? If the
kcarattini 2016/06/02 01:43:43 This was my reaction to a comment in time.h that s
66 } 66 }
67 67
68 // Prepare the GetFullHash results for the next request. 68 // Prepare the GetFullHash results for the next request.
69 void AddGetFullHashResponse(const SBFullHashResult& full_hash_result) { 69 void AddGetFullHashResponse(const SBFullHashResult& full_hash_result) {
70 full_hashes_.push_back(full_hash_result); 70 full_hashes_.push_back(full_hash_result);
71 } 71 }
72 72
73 // Clear the GetFullHash results for the next request.
74 void ClearFullHashResponse() {
75 full_hashes_.clear();
76 }
77
73 // Returns the prefixes that were sent in the last request. 78 // Returns the prefixes that were sent in the last request.
74 const std::vector<SBPrefix>& GetRequestPrefixes() { return prefixes_; } 79 const std::vector<SBPrefix>& GetRequestPrefixes() { return prefixes_; }
75 80
76 private: 81 private:
77 std::vector<SBPrefix> prefixes_; 82 std::vector<SBPrefix> prefixes_;
78 std::vector<SBFullHashResult> full_hashes_; 83 std::vector<SBFullHashResult> full_hashes_;
79 base::Time negative_cache_expire_; 84 base::Time negative_cache_expire_;
80 int delay_seconds_; 85 int delay_seconds_;
81 }; 86 };
82 87
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>( 261 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>(
257 db_manager_->v4_get_hash_protocol_manager_); 262 db_manager_->v4_get_hash_protocol_manager_);
258 base::Time now = base::Time::UnixEpoch(); 263 base::Time now = base::Time::UnixEpoch();
259 SBFullHashResult full_hash_result; 264 SBFullHashResult full_hash_result;
260 full_hash_result.hash = SBFullHashForString("example.com/"); 265 full_hash_result.hash = SBFullHashForString("example.com/");
261 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION"); 266 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION");
262 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3); 267 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3);
263 pm->AddGetFullHashResponse(full_hash_result); 268 pm->AddGetFullHashResponse(full_hash_result);
264 pm->SetNegativeCacheDurationMins(now, 5); 269 pm->SetNegativeCacheDurationMins(now, 5);
265 270
266 EXPECT_TRUE(db_manager_->api_cache_.empty()); 271 EXPECT_TRUE(db_manager_->v4_full_hash_cache_.empty());
267 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client)); 272 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client));
268 base::RunLoop().RunUntilIdle(); 273 base::RunLoop().RunUntilIdle();
269 274
270 EXPECT_TRUE(client.callback_invoked()); 275 EXPECT_TRUE(client.callback_invoked());
271 const std::vector<std::string>& permissions = client.GetBlockedPermissions(); 276 const std::vector<std::string>& permissions = client.GetBlockedPermissions();
272 EXPECT_EQ(1ul, permissions.size()); 277 EXPECT_EQ(1ul, permissions.size());
273 EXPECT_EQ("GEOLOCATION", permissions[0]); 278 EXPECT_EQ("GEOLOCATION", permissions[0]);
274 279
275 // Check the cache. 280 // Check the cache.
281 const SafeBrowsingDatabaseManager::PrefixToFullHashResultsMap& cache =
282 db_manager_->v4_full_hash_cache_[SB_THREAT_TYPE_API_ABUSE];
276 // Generated from the sorted output of UrlToFullHashes in util.h. 283 // Generated from the sorted output of UrlToFullHashes in util.h.
277 std::vector<SBPrefix> expected_prefixes = 284 std::vector<SBPrefix> expected_prefixes =
278 {1237562338, 2871045197, 3553205461, 3766933875}; 285 {1237562338, 2871045197, 3553205461, 3766933875};
279 EXPECT_EQ(expected_prefixes.size(), db_manager_->api_cache_.size()); 286 EXPECT_EQ(expected_prefixes.size(),
287 db_manager_->v4_full_hash_cache_[SB_THREAT_TYPE_API_ABUSE].size());
280 288
281 auto entry = db_manager_->api_cache_.find(expected_prefixes[0]); 289 auto entry = cache.find(expected_prefixes[0]);
282 EXPECT_NE(db_manager_->api_cache_.end(), entry); 290 EXPECT_NE(cache.end(), entry);
283 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after); 291 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after);
284 EXPECT_EQ(0ul, entry->second.full_hashes.size()); 292 EXPECT_EQ(0ul, entry->second.full_hashes.size());
285 293
286 entry = db_manager_->api_cache_.find(expected_prefixes[1]); 294 entry = cache.find(expected_prefixes[1]);
287 EXPECT_NE(db_manager_->api_cache_.end(), entry); 295 EXPECT_NE(cache.end(), entry);
288 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after); 296 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after);
289 EXPECT_EQ(0ul, entry->second.full_hashes.size()); 297 EXPECT_EQ(0ul, entry->second.full_hashes.size());
290 298
291 entry = db_manager_->api_cache_.find(expected_prefixes[2]); 299 entry = cache.find(expected_prefixes[2]);
292 EXPECT_NE(db_manager_->api_cache_.end(), entry); 300 EXPECT_NE(cache.end(), entry);
293 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after); 301 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after);
294 EXPECT_EQ(0ul, entry->second.full_hashes.size()); 302 EXPECT_EQ(0ul, entry->second.full_hashes.size());
295 303
296 entry = db_manager_->api_cache_.find(expected_prefixes[3]); 304 entry = cache.find(expected_prefixes[3]);
297 EXPECT_NE(db_manager_->api_cache_.end(), entry); 305 EXPECT_NE(cache.end(), entry);
298 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after); 306 EXPECT_EQ(now + base::TimeDelta::FromMinutes(5), entry->second.expire_after);
299 EXPECT_EQ(1ul, entry->second.full_hashes.size()); 307 EXPECT_EQ(1ul, entry->second.full_hashes.size());
300 EXPECT_TRUE(SBFullHashEqual(full_hash_result.hash, 308 EXPECT_TRUE(SBFullHashEqual(full_hash_result.hash,
301 entry->second.full_hashes[0].hash)); 309 entry->second.full_hashes[0].hash));
302 EXPECT_EQ(1ul, entry->second.full_hashes[0].metadata.api_permissions.size()); 310 EXPECT_EQ(1ul, entry->second.full_hashes[0].metadata.api_permissions.size());
303 EXPECT_EQ("GEOLOCATION", 311 EXPECT_EQ("GEOLOCATION",
304 entry->second.full_hashes[0].metadata.api_permissions[0]); 312 entry->second.full_hashes[0].metadata.api_permissions[0]);
305 EXPECT_EQ(full_hash_result.cache_expire_after, 313 EXPECT_EQ(full_hash_result.cache_expire_after,
306 entry->second.full_hashes[0].cache_expire_after); 314 entry->second.full_hashes[0].cache_expire_after);
307 } 315 }
308 316
309 // An uninitialized value for negative cache expire does not cache results. 317 // An uninitialized value for negative cache expire does not cache results.
310 TEST_F(SafeBrowsingDatabaseManagerTest, ResultsAreNotCachedOnNull) { 318 TEST_F(SafeBrowsingDatabaseManagerTest, ResultsAreNotCachedOnNull) {
311 TestClient client; 319 TestClient client;
312 const GURL url("https://www.example.com/more"); 320 const GURL url("https://www.example.com/more");
313 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>( 321 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>(
314 db_manager_->v4_get_hash_protocol_manager_); 322 db_manager_->v4_get_hash_protocol_manager_);
315 base::Time now = base::Time::UnixEpoch(); 323 base::Time now = base::Time::UnixEpoch();
316 SBFullHashResult full_hash_result; 324 SBFullHashResult full_hash_result;
317 full_hash_result.hash = SBFullHashForString("example.com/"); 325 full_hash_result.hash = SBFullHashForString("example.com/");
318 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION"); 326 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION");
319 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3); 327 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3);
320 pm->AddGetFullHashResponse(full_hash_result); 328 pm->AddGetFullHashResponse(full_hash_result);
321 329
322 EXPECT_TRUE(db_manager_->api_cache_.empty()); 330 EXPECT_TRUE(db_manager_->v4_full_hash_cache_.empty());
323 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client)); 331 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client));
324 base::RunLoop().RunUntilIdle(); 332 base::RunLoop().RunUntilIdle();
325 333
326 EXPECT_TRUE(client.callback_invoked()); 334 EXPECT_TRUE(client.callback_invoked());
327 EXPECT_TRUE(db_manager_->api_cache_.empty()); 335 EXPECT_TRUE(
336 db_manager_->v4_full_hash_cache_[SB_THREAT_TYPE_API_ABUSE].empty());
337 }
338
339 // Checks that results are looked up correctly in the cache.
340 TEST_F(SafeBrowsingDatabaseManagerTest, GetCachedResults) {
341 base::Time now = base::Time::UnixEpoch();
342 std::vector<SBFullHash> full_hashes;
343 SBFullHash full_hash = SBFullHashForString("example.com/");
344 full_hashes.push_back(full_hash);
345 std::vector<SBFullHashResult> cached_results;
346 std::vector<SBPrefix> prefixes;
347 db_manager_->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
348 full_hashes, now, &prefixes, &cached_results);
349
350 // The cache is empty.
351 EXPECT_TRUE(cached_results.empty());
352 EXPECT_EQ(1ul, prefixes.size());
353 EXPECT_EQ(full_hash.prefix, prefixes[0]);
354
355 // Prefix has a cache entry but full hash is not there.
356 SBCachedFullHashResult& entry = db_manager_->
357 v4_full_hash_cache_[SB_THREAT_TYPE_API_ABUSE][full_hash.prefix] =
358 SBCachedFullHashResult(now + base::TimeDelta::FromMinutes(5));
359 db_manager_->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
360 full_hashes, now, &prefixes, &cached_results);
361
362 EXPECT_TRUE(prefixes.empty());
363 EXPECT_TRUE(cached_results.empty());
364
365 // Expired negative cache entry.
366 entry.expire_after = now - base::TimeDelta::FromMinutes(5);
367 db_manager_->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
368 full_hashes, now, &prefixes, &cached_results);
369
370 EXPECT_TRUE(cached_results.empty());
371 EXPECT_EQ(1ul, prefixes.size());
372 EXPECT_EQ(full_hash.prefix, prefixes[0]);
373
374 // Now put the full hash in the cache.
375 SBFullHashResult full_hash_result;
376 full_hash_result.hash = full_hash;
377 full_hash_result.cache_expire_after = now + base::TimeDelta::FromMinutes(3);
378 entry.full_hashes.push_back(full_hash_result);
379 db_manager_->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
380 full_hashes, now, &prefixes, &cached_results);
381
382 EXPECT_TRUE(prefixes.empty());
383 EXPECT_EQ(1ul, cached_results.size());
384 EXPECT_TRUE(SBFullHashEqual(full_hash, cached_results[0].hash));
385
386 // Expired full hash in cache.
387 entry.full_hashes.clear();
388 full_hash_result.cache_expire_after = now - base::TimeDelta::FromMinutes(3);
389 entry.full_hashes.push_back(full_hash_result);
390 db_manager_->GetFullHashCachedResults(SB_THREAT_TYPE_API_ABUSE,
391 full_hashes, now, &prefixes, &cached_results);
392
393 EXPECT_TRUE(cached_results.empty());
394 EXPECT_EQ(1ul, prefixes.size());
395 EXPECT_EQ(full_hash.prefix, prefixes[0]);
396 }
397
398 // Checks that the cached results and request results are merged.
399 TEST_F(SafeBrowsingDatabaseManagerTest, CachedResultsMerged) {
400 TestClient client;
401 const GURL url("https://www.example.com/more");
402 TestV4GetHashProtocolManager* pm = static_cast<TestV4GetHashProtocolManager*>(
403 db_manager_->v4_get_hash_protocol_manager_);
404 // Set now to max time so the cache expire times are in the future.
405 SBFullHashResult full_hash_result;
406 full_hash_result.hash = SBFullHashForString("example.com/");
407 full_hash_result.metadata.api_permissions.push_back("GEOLOCATION");
408 full_hash_result.cache_expire_after = base::Time::Max();
409 pm->AddGetFullHashResponse(full_hash_result);
410 pm->SetNegativeCacheDurationMins(base::Time::Max(), 0);
411
412 EXPECT_TRUE(db_manager_->v4_full_hash_cache_.empty());
413 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client));
414 base::RunLoop().RunUntilIdle();
415
416 EXPECT_TRUE(client.callback_invoked());
417 const std::vector<std::string>& permissions = client.GetBlockedPermissions();
418 EXPECT_EQ(1ul, permissions.size());
419 EXPECT_EQ("GEOLOCATION", permissions[0]);
420
421 // The results should be cached, so remove them from the protocol manager
422 // response.
423 TestClient client2;
424 pm->ClearFullHashResponse();
425 pm->SetNegativeCacheDurationMins(base::Time(), 0);
426 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url, &client2));
427 base::RunLoop().RunUntilIdle();
428
429 EXPECT_TRUE(client2.callback_invoked());
430 const std::vector<std::string>& permissions2 =
431 client2.GetBlockedPermissions();
432 EXPECT_EQ(1ul, permissions2.size());
433 EXPECT_EQ("GEOLOCATION", permissions2[0]);
434
435 // Add a different result to the protocol manager response and ensure it is
436 // merged with the cached result in the metadata.
437 TestClient client3;
438 const GURL url2("https://m.example.com/more");
439 full_hash_result.hash = SBFullHashForString("m.example.com/");
440 full_hash_result.metadata.api_permissions.push_back("NOTIFICATIONS");
441 pm->AddGetFullHashResponse(full_hash_result);
442 pm->SetNegativeCacheDurationMins(base::Time::Max(), 0);
443 EXPECT_FALSE(db_manager_->CheckApiBlacklistUrl(url2, &client3));
444 base::RunLoop().RunUntilIdle();
445
446 EXPECT_TRUE(client3.callback_invoked());
447 const std::vector<std::string>& permissions3 =
448 client3.GetBlockedPermissions();
449 EXPECT_EQ(3ul, permissions3.size());
450 // TODO(kcarattini): Fix the metadata storage of permissions to avoid
451 // duplicates.
452 EXPECT_EQ("GEOLOCATION", permissions3[0]);
453 EXPECT_EQ("NOTIFICATIONS", permissions3[1]);
454 EXPECT_EQ("GEOLOCATION", permissions3[2]);
328 } 455 }
329 456
330 } // namespace safe_browsing 457 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « components/safe_browsing_db/database_manager.cc ('k') | components/safe_browsing_db/util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698