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

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

Issue 2565283008: Fix race condition with CancelCheck(). (Closed)
Patch Set: reqs for each platform. Created 3 years, 11 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/v4_local_database_manager.cc ('k') | no next file » | 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 "base/files/scoped_temp_dir.h" 5 #include "base/files/scoped_temp_dir.h"
6 #include "base/memory/ptr_util.h" 6 #include "base/memory/ptr_util.h"
7 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
9 #include "base/test/test_simple_task_runner.h" 10 #include "base/test/test_simple_task_runner.h"
10 #include "components/safe_browsing_db/v4_database.h" 11 #include "components/safe_browsing_db/v4_database.h"
11 #include "components/safe_browsing_db/v4_local_database_manager.h" 12 #include "components/safe_browsing_db/v4_local_database_manager.h"
12 #include "components/safe_browsing_db/v4_test_util.h" 13 #include "components/safe_browsing_db/v4_test_util.h"
13 #include "content/public/test/test_browser_thread_bundle.h" 14 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "crypto/sha2.h" 15 #include "crypto/sha2.h"
15 #include "net/url_request/test_url_fetcher_factory.h" 16 #include "net/url_request/test_url_fetcher_factory.h"
16 #include "testing/platform_test.h" 17 #include "testing/platform_test.h"
17 18
18 namespace safe_browsing { 19 namespace safe_browsing {
19 20
20 namespace { 21 namespace {
21 22
22 // Utility function for populating hashes. 23 // Utility function for populating hashes.
23 FullHash HashForUrl(const GURL& url) { 24 FullHash HashForUrl(const GURL& url) {
24 std::vector<FullHash> full_hashes; 25 std::vector<FullHash> full_hashes;
25 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes); 26 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes);
26 // ASSERT_GE(full_hashes.size(), 1u); 27 // ASSERT_GE(full_hashes.size(), 1u);
27 return full_hashes[0]; 28 return full_hashes[0];
28 } 29 }
29 30
31 // A fullhash response containing no matches.
32 std::string GetEmptyV4HashResponse() {
33 FindFullHashesResponse res;
34 res.mutable_negative_cache_duration()->set_seconds(600);
35
36 std::string res_data;
37 res.SerializeToString(&res_data);
38 return res_data;
39 }
40
30 } // namespace 41 } // namespace
31 42
32 class FakeV4Database : public V4Database { 43 class FakeV4Database : public V4Database {
33 public: 44 public:
34 static void Create( 45 static void Create(
35 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, 46 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
36 std::unique_ptr<StoreMap> store_map, 47 std::unique_ptr<StoreMap> store_map,
37 const StoreAndHashPrefixes& store_and_hash_prefixes, 48 const StoreAndHashPrefixes& store_and_hash_prefixes,
38 NewDatabaseReadyCallback new_db_callback, 49 NewDatabaseReadyCallback new_db_callback,
39 bool stores_available) { 50 bool stores_available) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 : V4Database(db_task_runner, std::move(store_map)), 100 : V4Database(db_task_runner, std::move(store_map)),
90 store_and_hash_prefixes_(store_and_hash_prefixes), 101 store_and_hash_prefixes_(store_and_hash_prefixes),
91 stores_available_(stores_available) {} 102 stores_available_(stores_available) {}
92 103
93 const StoreAndHashPrefixes store_and_hash_prefixes_; 104 const StoreAndHashPrefixes store_and_hash_prefixes_;
94 const bool stores_available_; 105 const bool stores_available_;
95 }; 106 };
96 107
97 class TestClient : public SafeBrowsingDatabaseManager::Client { 108 class TestClient : public SafeBrowsingDatabaseManager::Client {
98 public: 109 public:
99 TestClient(SBThreatType sb_threat_type, const GURL& url) 110 TestClient(SBThreatType sb_threat_type,
100 : expected_sb_threat_type(sb_threat_type), expected_url(url) {} 111 const GURL& url,
112 V4LocalDatabaseManager* manager_to_cancel = nullptr)
113 : expected_sb_threat_type(sb_threat_type),
114 expected_url(url),
115 result_received_(false),
116 manager_to_cancel_(manager_to_cancel) {}
101 117
102 void OnCheckBrowseUrlResult(const GURL& url, 118 void OnCheckBrowseUrlResult(const GURL& url,
103 SBThreatType threat_type, 119 SBThreatType threat_type,
104 const ThreatMetadata& metadata) override { 120 const ThreatMetadata& metadata) override {
105 DCHECK_EQ(expected_url, url); 121 DCHECK_EQ(expected_url, url);
106 DCHECK_EQ(expected_sb_threat_type, threat_type); 122 DCHECK_EQ(expected_sb_threat_type, threat_type);
123 result_received_ = true;
124 if (manager_to_cancel_) {
125 manager_to_cancel_->CancelCheck(this);
126 }
107 } 127 }
108 128
109 SBThreatType expected_sb_threat_type; 129 SBThreatType expected_sb_threat_type;
110 GURL expected_url; 130 GURL expected_url;
131 bool result_received_;
132 V4LocalDatabaseManager* manager_to_cancel_;
111 }; 133 };
112 134
113 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager { 135 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager {
114 public: 136 public:
115 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check, 137 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check,
116 const FullHashToStoreAndHashPrefixesMap& 138 const FullHashToStoreAndHashPrefixesMap&
117 full_hash_to_store_and_hash_prefixes) override { 139 full_hash_to_store_and_hash_prefixes) override {
118 perform_full_hash_check_called_ = true; 140 perform_full_hash_check_called_ = true;
119 } 141 }
120 142
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 363
342 ResetV4Database(); 364 ResetV4Database();
343 v4_local_database_manager_->CheckBrowseUrl(url, &client); 365 v4_local_database_manager_->CheckBrowseUrl(url, &client);
344 // The database is unavailable so the check should get queued. 366 // The database is unavailable so the check should get queued.
345 EXPECT_EQ(1ul, GetQueuedChecks().size()); 367 EXPECT_EQ(1ul, GetQueuedChecks().size());
346 368
347 StopLocalDatabaseManager(); 369 StopLocalDatabaseManager();
348 EXPECT_TRUE(GetQueuedChecks().empty()); 370 EXPECT_TRUE(GetQueuedChecks().empty());
349 } 371 }
350 372
373 // Verify that a window where checks cannot be cancelled is closed.
374 TEST_F(V4LocalDatabaseManagerTest, CancelPending) {
375 WaitForTasksOnTaskRunner();
376 net::FakeURLFetcherFactory factory(NULL);
377 // TODO(shess): Modify this to use a mock protocol manager instead
vakh (use Gerrit instead) 2017/01/05 18:31:41 you can change this to vakh, if you like and don't
378 // of faking the requests.
379 const char* kReqs[] = {
Scott Hess - ex-Googler 2017/01/06 22:44:36 QQ ... I kinda messed up my emacs init.el, so was
380 // OSX
381 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQBBAIGgcKBWVXGg-"
Nathan Parker 2017/01/05 21:35:32 wat. Proto wire formats vary by platform? Isn't
Scott Hess - ex-Googler 2017/01/05 23:23:12 The proto is portable - but each platform puts a d
382 "pIAEgAyAEIAUgBg==",
383
384 // Linux
385 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQAhAIGgcKBWVXGg-"
386 "pIAEgAyAEIAUgBg==",
387
388 // Windows
389 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQARAIGgcKBWVXGg-"
390 "pIAEgAyAEIAUgBg==",
391 };
392 for (const char* req : kReqs) {
393 const GURL url(
394 base::StringPrintf("https://safebrowsing.googleapis.com/v4/"
395 "fullHashes:find?$req=%s"
396 "&$ct=application/x-protobuf&key=test_key_param",
397 req));
398 factory.SetFakeResponse(url, GetEmptyV4HashResponse(), net::HTTP_OK,
399 net::URLRequestStatus::SUCCESS);
400 }
401
402 const GURL url("http://example.com/a/");
403 const HashPrefix hash_prefix("eW\x1A\xF\xA9");
404
405 StoreAndHashPrefixes store_and_hash_prefixes;
406 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), hash_prefix);
407 ReplaceV4Database(store_and_hash_prefixes);
408
409 // Test that a request flows through to the callback.
410 {
411 TestClient client(SB_THREAT_TYPE_SAFE, url);
412 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client));
413 EXPECT_FALSE(client.result_received_);
414 WaitForTasksOnTaskRunner();
415 EXPECT_TRUE(client.result_received_);
416 }
417
418 // Test that cancel prevents the callback from being called.
419 {
420 TestClient client(SB_THREAT_TYPE_SAFE, url);
421 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client));
422 v4_local_database_manager_->CancelCheck(&client);
423 EXPECT_FALSE(client.result_received_);
424 WaitForTasksOnTaskRunner();
425 EXPECT_FALSE(client.result_received_);
426 }
427 }
428
429 // When the database load flushes the queued requests, make sure that
430 // CancelCheck() is not fatal in the client callback.
431 TEST_F(V4LocalDatabaseManagerTest, CancelQueued) {
432 const GURL url("http://example.com/a/");
433
434 TestClient client1(SB_THREAT_TYPE_SAFE, url,
435 v4_local_database_manager_.get());
436 TestClient client2(SB_THREAT_TYPE_SAFE, url);
437 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client1));
438 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client2));
439 EXPECT_EQ(2ul, GetQueuedChecks().size());
440 EXPECT_FALSE(client1.result_received_);
441 EXPECT_FALSE(client2.result_received_);
442 WaitForTasksOnTaskRunner();
443 EXPECT_TRUE(client1.result_received_);
444 EXPECT_TRUE(client2.result_received_);
445 }
446
351 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but 447 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but
352 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is 448 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is
353 // called async. 449 // called async.
354 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) { 450 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) {
355 SetupFakeManager(); 451 SetupFakeManager();
356 net::TestURLFetcherFactory factory; 452 net::TestURLFetcherFactory factory;
357 453
358 StoreAndHashPrefixes store_and_hash_prefixes; 454 StoreAndHashPrefixes store_and_hash_prefixes;
359 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), 455 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(),
360 HashPrefix("eW\x1A\xF\xA9")); 456 HashPrefix("eW\x1A\xF\xA9"));
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled( 615 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
520 v4_local_database_manager_)); 616 v4_local_database_manager_));
521 } 617 }
522 618
523 // TODO(nparker): Add tests for 619 // TODO(nparker): Add tests for
524 // CheckDownloadUrl() 620 // CheckDownloadUrl()
525 // CheckExtensionIDs() 621 // CheckExtensionIDs()
526 // CheckResourceUrl() 622 // CheckResourceUrl()
527 623
528 } // namespace safe_browsing 624 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « components/safe_browsing_db/v4_local_database_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698