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

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

Issue 2565283008: Fix race condition with CancelCheck(). (Closed)
Patch Set: Add some tests. Created 4 years 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/test/test_simple_task_runner.h" 9 #include "base/test/test_simple_task_runner.h"
10 #include "components/safe_browsing_db/v4_database.h" 10 #include "components/safe_browsing_db/v4_database.h"
11 #include "components/safe_browsing_db/v4_local_database_manager.h" 11 #include "components/safe_browsing_db/v4_local_database_manager.h"
12 #include "components/safe_browsing_db/v4_test_util.h" 12 #include "components/safe_browsing_db/v4_test_util.h"
13 #include "content/public/test/test_browser_thread_bundle.h" 13 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "net/url_request/test_url_fetcher_factory.h" 14 #include "net/url_request/test_url_fetcher_factory.h"
15 #include "testing/platform_test.h" 15 #include "testing/platform_test.h"
16 16
17 namespace safe_browsing { 17 namespace safe_browsing {
18 18
19 namespace {
20
21 // A fullhash response containing no matches.
22 std::string GetEmptyV4HashResponse() {
23 FindFullHashesResponse res;
24 res.mutable_negative_cache_duration()->set_seconds(600);
25
26 std::string res_data;
27 res.SerializeToString(&res_data);
28 return res_data;
29 }
30
31 } // namespace
32
19 class FakeV4Database : public V4Database { 33 class FakeV4Database : public V4Database {
20 public: 34 public:
21 static void Create( 35 static void Create(
22 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner, 36 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
23 std::unique_ptr<StoreMap> store_map, 37 std::unique_ptr<StoreMap> store_map,
24 const StoreAndHashPrefixes& store_and_hash_prefixes, 38 const StoreAndHashPrefixes& store_and_hash_prefixes,
25 NewDatabaseReadyCallback new_db_callback) { 39 NewDatabaseReadyCallback new_db_callback) {
26 // Mimics V4Database::Create 40 // Mimics V4Database::Create
27 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner = 41 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner =
28 base::MessageLoop::current()->task_runner(); 42 base::MessageLoop::current()->task_runner();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 std::unique_ptr<StoreMap> store_map, 79 std::unique_ptr<StoreMap> store_map,
66 const StoreAndHashPrefixes& store_and_hash_prefixes) 80 const StoreAndHashPrefixes& store_and_hash_prefixes)
67 : V4Database(db_task_runner, std::move(store_map)), 81 : V4Database(db_task_runner, std::move(store_map)),
68 store_and_hash_prefixes_(store_and_hash_prefixes) {} 82 store_and_hash_prefixes_(store_and_hash_prefixes) {}
69 83
70 const StoreAndHashPrefixes store_and_hash_prefixes_; 84 const StoreAndHashPrefixes store_and_hash_prefixes_;
71 }; 85 };
72 86
73 class TestClient : public SafeBrowsingDatabaseManager::Client { 87 class TestClient : public SafeBrowsingDatabaseManager::Client {
74 public: 88 public:
75 TestClient(SBThreatType sb_threat_type, const GURL& url) 89 TestClient(SBThreatType sb_threat_type,
76 : expected_sb_threat_type(sb_threat_type), expected_url(url) {} 90 const GURL& url,
91 V4LocalDatabaseManager* manager_to_cancel = nullptr)
92 : expected_sb_threat_type(sb_threat_type),
93 expected_url(url),
94 result_received_(false),
95 manager_to_cancel_(manager_to_cancel) {}
77 96
78 void OnCheckBrowseUrlResult(const GURL& url, 97 void OnCheckBrowseUrlResult(const GURL& url,
79 SBThreatType threat_type, 98 SBThreatType threat_type,
80 const ThreatMetadata& metadata) override { 99 const ThreatMetadata& metadata) override {
81 DCHECK_EQ(expected_url, url); 100 DCHECK_EQ(expected_url, url);
82 DCHECK_EQ(expected_sb_threat_type, threat_type); 101 DCHECK_EQ(expected_sb_threat_type, threat_type);
102 result_received_ = true;
103 if (manager_to_cancel_) {
104 manager_to_cancel_->CancelCheck(this);
Scott Hess - ex-Googler 2016/12/15 01:14:13 Any CancelCheck() with items in the queue during q
Nathan Parker 2016/12/16 22:37:13 Acknowledged.
105 }
83 } 106 }
84 107
85 SBThreatType expected_sb_threat_type; 108 SBThreatType expected_sb_threat_type;
86 GURL expected_url; 109 GURL expected_url;
110 bool result_received_;
111 V4LocalDatabaseManager* manager_to_cancel_;
87 }; 112 };
88 113
89 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager { 114 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager {
90 public: 115 public:
91 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check, 116 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check,
92 const FullHashToStoreAndHashPrefixesMap& 117 const FullHashToStoreAndHashPrefixesMap&
93 full_hash_to_store_and_hash_prefixes) override { 118 full_hash_to_store_and_hash_prefixes) override {
94 perform_full_hash_check_called_ = true; 119 perform_full_hash_check_called_ = true;
95 } 120 }
96 121
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 328
304 ResetV4Database(); 329 ResetV4Database();
305 v4_local_database_manager_->CheckBrowseUrl(url, &client); 330 v4_local_database_manager_->CheckBrowseUrl(url, &client);
306 // The database is unavailable so the check should get queued. 331 // The database is unavailable so the check should get queued.
307 EXPECT_EQ(1ul, GetQueuedChecks().size()); 332 EXPECT_EQ(1ul, GetQueuedChecks().size());
308 333
309 StopLocalDatabaseManager(); 334 StopLocalDatabaseManager();
310 EXPECT_TRUE(GetQueuedChecks().empty()); 335 EXPECT_TRUE(GetQueuedChecks().empty());
311 } 336 }
312 337
338 // Verify that a window where checks cannot be cancelled is closed.
339 TEST_F(V4LocalDatabaseManagerTest, CancelPending) {
340 WaitForTasksOnTaskRunner();
341 net::FakeURLFetcherFactory factory(NULL);
342 factory.SetFakeResponse(
343 GURL("https://safebrowsing.googleapis.com/v4/"
344 "fullHashes:find?$req="
345 "Cg8KCHVuaXR0ZXN0EgMxLjAaJwgBCAIIAwgGCAcICAgJCAoQBBAIGgcKBWVXGg-"
346 "pIAEgAyAEIAUgBg==&$ct=application/x-protobuf&key=test_key_param"),
Scott Hess - ex-Googler 2016/12/15 01:14:13 I'd love suggestions about this. AFAICT, FakeURLF
Nathan Parker 2016/12/16 22:37:13 Matching a prefix or having default seems like it'
Scott Hess - ex-Googler 2017/01/05 00:02:14 Varun, did you have an opinion on this hard-coded
347 GetEmptyV4HashResponse(), net::HTTP_OK, net::URLRequestStatus::SUCCESS);
348
349 const GURL url("http://example.com/a/");
350 const HashPrefix hash_prefix("eW\x1A\xF\xA9");
351
352 StoreAndHashPrefixes store_and_hash_prefixes;
353 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), hash_prefix);
354 ReplaceV4Database(store_and_hash_prefixes);
355
356 // Test that a request flows through to the callback.
357 {
358 TestClient client(SB_THREAT_TYPE_SAFE, url);
359 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client));
360 EXPECT_FALSE(client.result_received_);
361 WaitForTasksOnTaskRunner();
362 EXPECT_TRUE(client.result_received_);
363 }
364
365 // Test that cancel prevents the callback from being called.
366 {
367 TestClient client(SB_THREAT_TYPE_SAFE, url);
368 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client));
369 v4_local_database_manager_->CancelCheck(&client);
370 EXPECT_FALSE(client.result_received_);
371 WaitForTasksOnTaskRunner();
372 EXPECT_FALSE(client.result_received_);
Scott Hess - ex-Googler 2016/12/15 01:14:13 Pre-patch, this expectation failed.
Nathan Parker 2016/12/16 22:37:13 Wait, that seems to imply that all cancels were br
vakh (use Gerrit instead) 2017/01/03 22:26:01 No, it means that any CancelCheck calls made betwe
373 }
374 }
375
376 // When the database load flushes the queued requests, make sure that
377 // CancelCheck() is not fatal in the client callback.
Scott Hess - ex-Googler 2016/12/15 01:14:13 This does not test the RespondSafeToQueuedChecks()
Nathan Parker 2016/12/16 22:37:13 Probably fine
378 TEST_F(V4LocalDatabaseManagerTest, CancelQueued) {
379 const GURL url("http://example.com/a/");
380
381 TestClient client1(SB_THREAT_TYPE_SAFE, url,
382 v4_local_database_manager_.get());
383 TestClient client2(SB_THREAT_TYPE_SAFE, url);
384 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client1));
385 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(url, &client2));
386 EXPECT_EQ(2ul, GetQueuedChecks().size());
387 EXPECT_FALSE(client1.result_received_);
388 EXPECT_FALSE(client2.result_received_);
389 WaitForTasksOnTaskRunner();
390 EXPECT_TRUE(client1.result_received_);
391 EXPECT_TRUE(client2.result_received_);
392 }
393
313 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but 394 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but
314 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is 395 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is
315 // called async. 396 // called async.
316 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) { 397 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) {
317 // StopLocalDatabaseManager before resetting it because that's what 398 // StopLocalDatabaseManager before resetting it because that's what
318 // ~V4LocalDatabaseManager expects. 399 // ~V4LocalDatabaseManager expects.
319 StopLocalDatabaseManager(); 400 StopLocalDatabaseManager();
320 v4_local_database_manager_ = 401 v4_local_database_manager_ =
321 make_scoped_refptr(new FakeV4LocalDatabaseManager(base_dir_.GetPath())); 402 make_scoped_refptr(new FakeV4LocalDatabaseManager(base_dir_.GetPath()));
322 SetTaskRunnerForTest(); 403 SetTaskRunnerForTest();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled( 482 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
402 v4_local_database_manager_)); 483 v4_local_database_manager_));
403 484
404 // The fake database returns a matched hash prefix. 485 // The fake database returns a matched hash prefix.
405 EXPECT_TRUE(v4_local_database_manager_->MatchMalwareIP("192.168.1.2")); 486 EXPECT_TRUE(v4_local_database_manager_->MatchMalwareIP("192.168.1.2"));
406 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled( 487 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
407 v4_local_database_manager_)); 488 v4_local_database_manager_));
408 } 489 }
409 490
410 } // namespace safe_browsing 491 } // 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