OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 5 |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 #include "base/single_thread_task_runner.h" | 7 #include "base/single_thread_task_runner.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 246 |
247 class MockProtocolDelegate : public SafeBrowsingProtocolManagerDelegate { | 247 class MockProtocolDelegate : public SafeBrowsingProtocolManagerDelegate { |
248 public: | 248 public: |
249 MockProtocolDelegate() {} | 249 MockProtocolDelegate() {} |
250 virtual ~MockProtocolDelegate() {} | 250 virtual ~MockProtocolDelegate() {} |
251 | 251 |
252 MOCK_METHOD0(UpdateStarted, void()); | 252 MOCK_METHOD0(UpdateStarted, void()); |
253 MOCK_METHOD1(UpdateFinished, void(bool)); | 253 MOCK_METHOD1(UpdateFinished, void(bool)); |
254 MOCK_METHOD0(ResetDatabase, void()); | 254 MOCK_METHOD0(ResetDatabase, void()); |
255 MOCK_METHOD1(GetChunks, void(GetChunksCallback)); | 255 MOCK_METHOD1(GetChunks, void(GetChunksCallback)); |
256 MOCK_METHOD2(AddChunks, void(const std::string&, SBChunkList*)); | 256 MOCK_METHOD3(AddChunks, void(const std::string&, SBChunkList*, |
| 257 AddChunksCallback)); |
257 MOCK_METHOD1(DeleteChunks, void(std::vector<SBChunkDelete>*)); | 258 MOCK_METHOD1(DeleteChunks, void(std::vector<SBChunkDelete>*)); |
258 }; | 259 }; |
259 | 260 |
260 // ImmediateSingleThreadTaskRunner will ignore delayed times for tasks. | 261 // ImmediateSingleThreadTaskRunner will ignore delayed times for tasks. |
261 // This is primarily used to run the timer tasks immediately, and prevent | 262 // This is primarily used to run the timer tasks immediately, and prevent |
262 // the need for constructing a MessageLoop. | 263 // the need for constructing a MessageLoop. |
263 class ImmediateSingleThreadTaskRunner : public base::SingleThreadTaskRunner { | 264 class ImmediateSingleThreadTaskRunner : public base::SingleThreadTaskRunner { |
264 public: | 265 public: |
265 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { | 266 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { |
266 return true; | 267 return true; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 // |InvokeGetChunksCallback| is required because GMock's InvokeArgument action | 306 // |InvokeGetChunksCallback| is required because GMock's InvokeArgument action |
306 // expects to use operator(), and a Callback only provides Run(). | 307 // expects to use operator(), and a Callback only provides Run(). |
307 // TODO(cbentzel): Use ACTION or ACTION_TEMPLATE instead? | 308 // TODO(cbentzel): Use ACTION or ACTION_TEMPLATE instead? |
308 void InvokeGetChunksCallback( | 309 void InvokeGetChunksCallback( |
309 const std::vector<SBListChunkRanges>& ranges, | 310 const std::vector<SBListChunkRanges>& ranges, |
310 bool database_error, | 311 bool database_error, |
311 SafeBrowsingProtocolManagerDelegate::GetChunksCallback callback) { | 312 SafeBrowsingProtocolManagerDelegate::GetChunksCallback callback) { |
312 callback.Run(ranges, database_error); | 313 callback.Run(ranges, database_error); |
313 } | 314 } |
314 | 315 |
| 316 // |DeferAddChunksCallback| is used to asynchronously invoke |callback|, |
| 317 // since SafeBrowsingProtocolManager is not re-entrant at that point. This |
| 318 // guarantee is part of the SafeBrowsingProtocolManagerDelegate contract. |
| 319 void DeferAddChunksCallback( |
| 320 SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) { |
| 321 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 322 base::ThreadTaskRunnerHandle::Get()); |
| 323 if (!task_runner) |
| 324 return; |
| 325 task_runner->PostTask(FROM_HERE, callback); |
| 326 } |
| 327 |
315 } // namespace | 328 } // namespace |
316 | 329 |
317 // Tests that the Update protocol will be skipped if there are problems | 330 // Tests that the Update protocol will be skipped if there are problems |
318 // accessing the database. | 331 // accessing the database. |
319 TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) { | 332 TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) { |
320 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 333 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
321 new ImmediateSingleThreadTaskRunner()); | 334 new ImmediateSingleThreadTaskRunner()); |
322 base::ThreadTaskRunnerHandle runner_handler(runner); | 335 base::ThreadTaskRunnerHandle runner_handler(runner); |
323 | 336 |
324 testing::StrictMock<MockProtocolDelegate> test_delegate; | 337 testing::StrictMock<MockProtocolDelegate> test_delegate; |
325 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 338 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
326 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 339 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
327 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 340 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
328 std::vector<SBListChunkRanges>(), | 341 std::vector<SBListChunkRanges>(), |
329 true))); | 342 true))); |
330 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); | 343 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
331 | 344 |
332 scoped_ptr<SafeBrowsingProtocolManager> pm( | 345 scoped_ptr<SafeBrowsingProtocolManager> pm( |
333 CreateProtocolManager(&test_delegate)); | 346 CreateProtocolManager(&test_delegate)); |
334 | 347 |
335 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 348 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
336 runner->RunTasks(); | 349 runner->RunTasks(); |
| 350 |
| 351 EXPECT_TRUE(pm->IsUpdateScheduled()); |
337 } | 352 } |
338 | 353 |
339 // Tests the contents of the POST body when the local database is empty. | 354 // Tests what happens when there is a response with no chunks. |
340 TEST_F(SafeBrowsingProtocolManagerTest, EmptyDatabase) { | 355 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { |
341 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 356 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
342 new ImmediateSingleThreadTaskRunner()); | 357 new ImmediateSingleThreadTaskRunner()); |
343 base::ThreadTaskRunnerHandle runner_handler(runner); | 358 base::ThreadTaskRunnerHandle runner_handler(runner); |
344 net::TestURLFetcherFactory url_fetcher_factory; | 359 net::TestURLFetcherFactory url_fetcher_factory; |
345 | 360 |
346 testing::StrictMock<MockProtocolDelegate> test_delegate; | 361 testing::StrictMock<MockProtocolDelegate> test_delegate; |
347 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 362 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
348 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 363 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
349 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 364 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
350 std::vector<SBListChunkRanges>(), | 365 std::vector<SBListChunkRanges>(), |
351 false))); | 366 false))); |
| 367 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
352 | 368 |
353 scoped_ptr<SafeBrowsingProtocolManager> pm( | 369 scoped_ptr<SafeBrowsingProtocolManager> pm( |
354 CreateProtocolManager(&test_delegate)); | 370 CreateProtocolManager(&test_delegate)); |
355 | 371 |
356 // Kick off initialization. This returns chunks from the DB synchronously. | 372 // Kick off initialization. This returns chunks from the DB synchronously. |
357 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 373 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
358 runner->RunTasks(); | 374 runner->RunTasks(); |
359 | 375 |
360 // We should have an URLFetcher at this point in time. | 376 // We should have an URLFetcher at this point in time. |
361 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 377 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
362 ValidateUpdateFetcherRequest(url_fetcher); | 378 ValidateUpdateFetcherRequest(url_fetcher); |
| 379 |
| 380 // The update response is successful, but an empty body. |
| 381 url_fetcher->set_status(net::URLRequestStatus()); |
| 382 url_fetcher->set_response_code(200); |
| 383 url_fetcher->SetResponseString(""); |
| 384 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 385 |
| 386 EXPECT_TRUE(pm->IsUpdateScheduled()); |
363 } | 387 } |
364 | 388 |
365 // Tests the contents of the POST body when there are contents in the | 389 // Tests the contents of the POST body when there are contents in the |
366 // local database. This is not exhaustive, as the actual list formatting | 390 // local database. This is not exhaustive, as the actual list formatting |
367 // is covered by SafeBrowsingProtocolManagerTest.TestChunkStrings. | 391 // is covered by SafeBrowsingProtocolManagerTest.TestChunkStrings. |
368 TEST_F(SafeBrowsingProtocolManagerTest, ExistingDatabase) { | 392 TEST_F(SafeBrowsingProtocolManagerTest, ExistingDatabase) { |
369 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 393 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
370 new ImmediateSingleThreadTaskRunner()); | 394 new ImmediateSingleThreadTaskRunner()); |
371 base::ThreadTaskRunnerHandle runner_handler(runner); | 395 base::ThreadTaskRunnerHandle runner_handler(runner); |
372 net::TestURLFetcherFactory url_fetcher_factory; | 396 net::TestURLFetcherFactory url_fetcher_factory; |
373 | 397 |
374 std::vector<SBListChunkRanges> ranges; | 398 std::vector<SBListChunkRanges> ranges; |
375 SBListChunkRanges range_phish(safe_browsing_util::kPhishingList); | 399 SBListChunkRanges range_phish(safe_browsing_util::kPhishingList); |
376 range_phish.adds = "adds_phish"; | 400 range_phish.adds = "adds_phish"; |
377 range_phish.subs = "subs_phish"; | 401 range_phish.subs = "subs_phish"; |
378 ranges.push_back(range_phish); | 402 ranges.push_back(range_phish); |
379 | 403 |
380 SBListChunkRanges range_unknown("unknown_list"); | 404 SBListChunkRanges range_unknown("unknown_list"); |
381 range_unknown.adds = "adds_unknown"; | 405 range_unknown.adds = "adds_unknown"; |
382 range_unknown.subs = "subs_unknown"; | 406 range_unknown.subs = "subs_unknown"; |
383 ranges.push_back(range_unknown); | 407 ranges.push_back(range_unknown); |
384 | 408 |
385 testing::StrictMock<MockProtocolDelegate> test_delegate; | 409 testing::StrictMock<MockProtocolDelegate> test_delegate; |
386 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 410 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
387 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 411 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
388 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 412 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
389 ranges, | 413 ranges, |
390 false))); | 414 false))); |
| 415 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
391 | 416 |
392 scoped_ptr<SafeBrowsingProtocolManager> pm( | 417 scoped_ptr<SafeBrowsingProtocolManager> pm( |
393 CreateProtocolManager(&test_delegate)); | 418 CreateProtocolManager(&test_delegate)); |
394 | 419 |
395 // Kick off initialization. This returns chunks from the DB synchronously. | 420 // Kick off initialization. This returns chunks from the DB synchronously. |
396 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 421 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
397 runner->RunTasks(); | 422 runner->RunTasks(); |
398 | 423 |
399 // We should have an URLFetcher at this point in time. | 424 // We should have an URLFetcher at this point in time. |
400 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 425 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
401 ASSERT_TRUE(url_fetcher); | 426 ASSERT_TRUE(url_fetcher); |
402 EXPECT_EQ(net::LOAD_DISABLE_CACHE, url_fetcher->GetLoadFlags()); | 427 EXPECT_EQ(net::LOAD_DISABLE_CACHE, url_fetcher->GetLoadFlags()); |
403 EXPECT_EQ("goog-phish-shavar;a:adds_phish:s:subs_phish\n" | 428 EXPECT_EQ("goog-phish-shavar;a:adds_phish:s:subs_phish\n" |
404 "unknown_list;a:adds_unknown:s:subs_unknown\n" | 429 "unknown_list;a:adds_unknown:s:subs_unknown\n" |
405 "goog-malware-shavar;\n", | 430 "goog-malware-shavar;\n", |
406 url_fetcher->upload_data()); | 431 url_fetcher->upload_data()); |
407 EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0" | 432 EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0" |
408 "&pver=2.2" + key_param_), | 433 "&pver=2.2" + key_param_), |
409 url_fetcher->GetOriginalURL()); | 434 url_fetcher->GetOriginalURL()); |
| 435 url_fetcher->set_status(net::URLRequestStatus()); |
| 436 url_fetcher->set_response_code(200); |
| 437 url_fetcher->SetResponseString(""); |
| 438 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 439 |
| 440 EXPECT_TRUE(pm->IsUpdateScheduled()); |
410 } | 441 } |
411 | 442 |
412 // Tests what happens when there is a response with no chunks. | 443 |
413 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { | 444 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadBody) { |
414 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 445 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
415 new ImmediateSingleThreadTaskRunner()); | 446 new ImmediateSingleThreadTaskRunner()); |
416 base::ThreadTaskRunnerHandle runner_handler(runner); | 447 base::ThreadTaskRunnerHandle runner_handler(runner); |
417 net::TestURLFetcherFactory url_fetcher_factory; | 448 net::TestURLFetcherFactory url_fetcher_factory; |
418 | 449 |
419 testing::StrictMock<MockProtocolDelegate> test_delegate; | 450 testing::StrictMock<MockProtocolDelegate> test_delegate; |
420 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 451 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
421 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 452 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
422 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 453 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
423 std::vector<SBListChunkRanges>(), | 454 std::vector<SBListChunkRanges>(), |
424 false))); | 455 false))); |
425 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); | 456 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
426 | 457 |
427 scoped_ptr<SafeBrowsingProtocolManager> pm( | 458 scoped_ptr<SafeBrowsingProtocolManager> pm( |
428 CreateProtocolManager(&test_delegate)); | 459 CreateProtocolManager(&test_delegate)); |
429 | 460 |
430 // Kick off initialization. This returns chunks from the DB synchronously. | 461 // Kick off initialization. This returns chunks from the DB synchronously. |
431 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 462 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
432 runner->RunTasks(); | 463 runner->RunTasks(); |
433 | 464 |
434 // We should have an URLFetcher at this point in time. | 465 // We should have an URLFetcher at this point in time. |
435 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 466 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
436 ValidateUpdateFetcherRequest(url_fetcher); | 467 ValidateUpdateFetcherRequest(url_fetcher); |
437 | 468 |
438 // The update response is successful, but an empty body. | 469 // The update response is successful, but an invalid body. |
439 url_fetcher->set_status(net::URLRequestStatus()); | 470 url_fetcher->set_status(net::URLRequestStatus()); |
440 url_fetcher->set_response_code(200); | 471 url_fetcher->set_response_code(200); |
441 url_fetcher->SetResponseString(""); | 472 url_fetcher->SetResponseString("THIS_IS_A_BAD_RESPONSE"); |
442 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 473 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 474 |
| 475 EXPECT_TRUE(pm->IsUpdateScheduled()); |
443 } | 476 } |
444 | 477 |
445 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadBody) { | 478 // Tests what happens when there is an error in the update response. |
| 479 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpError) { |
446 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 480 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
447 new ImmediateSingleThreadTaskRunner()); | 481 new ImmediateSingleThreadTaskRunner()); |
448 base::ThreadTaskRunnerHandle runner_handler(runner); | 482 base::ThreadTaskRunnerHandle runner_handler(runner); |
449 net::TestURLFetcherFactory url_fetcher_factory; | 483 net::TestURLFetcherFactory url_fetcher_factory; |
450 | 484 |
451 testing::StrictMock<MockProtocolDelegate> test_delegate; | 485 testing::StrictMock<MockProtocolDelegate> test_delegate; |
452 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 486 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
453 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 487 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
454 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 488 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
455 std::vector<SBListChunkRanges>(), | 489 std::vector<SBListChunkRanges>(), |
456 false))); | 490 false))); |
457 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); | 491 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
458 | 492 |
459 scoped_ptr<SafeBrowsingProtocolManager> pm( | 493 scoped_ptr<SafeBrowsingProtocolManager> pm( |
460 CreateProtocolManager(&test_delegate)); | 494 CreateProtocolManager(&test_delegate)); |
461 | 495 |
462 // Kick off initialization. This returns chunks from the DB synchronously. | 496 // Kick off initialization. This returns chunks from the DB synchronously. |
463 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 497 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
464 runner->RunTasks(); | 498 runner->RunTasks(); |
465 | 499 |
466 // We should have an URLFetcher at this point in time. | 500 // We should have an URLFetcher at this point in time. |
467 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 501 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
468 ValidateUpdateFetcherRequest(url_fetcher); | 502 ValidateUpdateFetcherRequest(url_fetcher); |
469 | 503 |
470 // The update response is successful, but an invalid body. | 504 // Go ahead and respond to it. |
471 url_fetcher->set_status(net::URLRequestStatus()); | 505 url_fetcher->set_status(net::URLRequestStatus()); |
472 url_fetcher->set_response_code(200); | 506 url_fetcher->set_response_code(404); |
473 url_fetcher->SetResponseString("THIS_IS_A_BAD_RESPONSE"); | 507 url_fetcher->SetResponseString(""); |
474 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 508 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 509 |
| 510 EXPECT_TRUE(pm->IsUpdateScheduled()); |
475 } | 511 } |
476 | 512 |
477 // Tests what happens when there is an error in the update response. | 513 // Tests what happens when there is an error with the connection. |
478 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpError) { | 514 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseConnectionError) { |
479 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 515 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
480 new ImmediateSingleThreadTaskRunner()); | 516 new ImmediateSingleThreadTaskRunner()); |
481 base::ThreadTaskRunnerHandle runner_handler(runner); | 517 base::ThreadTaskRunnerHandle runner_handler(runner); |
482 net::TestURLFetcherFactory url_fetcher_factory; | 518 net::TestURLFetcherFactory url_fetcher_factory; |
483 | 519 |
484 testing::StrictMock<MockProtocolDelegate> test_delegate; | 520 testing::StrictMock<MockProtocolDelegate> test_delegate; |
485 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 521 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
486 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 522 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
487 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 523 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
488 std::vector<SBListChunkRanges>(), | 524 std::vector<SBListChunkRanges>(), |
489 false))); | 525 false))); |
490 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); | 526 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
491 | 527 |
492 scoped_ptr<SafeBrowsingProtocolManager> pm( | 528 scoped_ptr<SafeBrowsingProtocolManager> pm( |
493 CreateProtocolManager(&test_delegate)); | 529 CreateProtocolManager(&test_delegate)); |
494 | 530 |
495 // Kick off initialization. This returns chunks from the DB synchronously. | 531 // Kick off initialization. This returns chunks from the DB synchronously. |
496 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 532 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
497 runner->RunTasks(); | 533 runner->RunTasks(); |
498 | 534 |
499 // We should have an URLFetcher at this point in time. | 535 // We should have an URLFetcher at this point in time. |
500 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 536 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
501 ValidateUpdateFetcherRequest(url_fetcher); | 537 ValidateUpdateFetcherRequest(url_fetcher); |
502 | 538 |
503 // Go ahead and respond to it. | 539 // Go ahead and respond to it. |
504 url_fetcher->set_status(net::URLRequestStatus()); | 540 url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
505 url_fetcher->set_response_code(404); | 541 net::ERR_CONNECTION_RESET)); |
506 url_fetcher->SetResponseString(""); | |
507 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 542 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 543 |
| 544 EXPECT_TRUE(pm->IsUpdateScheduled()); |
508 } | 545 } |
509 | 546 |
510 // Tests what happens when there is an error with the connection. | 547 // Tests what happens when there is a timeout before an update response. |
511 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseConnectionError) { | 548 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeout) { |
512 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 549 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
513 new ImmediateSingleThreadTaskRunner()); | 550 new ImmediateSingleThreadTaskRunner()); |
514 base::ThreadTaskRunnerHandle runner_handler(runner); | 551 base::ThreadTaskRunnerHandle runner_handler(runner); |
515 net::TestURLFetcherFactory url_fetcher_factory; | 552 net::TestURLFetcherFactory url_fetcher_factory; |
516 | 553 |
517 testing::StrictMock<MockProtocolDelegate> test_delegate; | 554 testing::StrictMock<MockProtocolDelegate> test_delegate; |
518 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 555 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
519 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 556 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
520 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 557 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
521 std::vector<SBListChunkRanges>(), | 558 std::vector<SBListChunkRanges>(), |
522 false))); | 559 false))); |
523 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); | 560 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
524 | 561 |
525 scoped_ptr<SafeBrowsingProtocolManager> pm( | 562 scoped_ptr<SafeBrowsingProtocolManager> pm( |
526 CreateProtocolManager(&test_delegate)); | 563 CreateProtocolManager(&test_delegate)); |
527 | 564 |
528 // Kick off initialization. This returns chunks from the DB synchronously. | 565 // Kick off initialization. This returns chunks from the DB synchronously. |
529 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 566 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
530 runner->RunTasks(); | 567 runner->RunTasks(); |
531 | 568 |
532 // We should have an URLFetcher at this point in time. | 569 // We should have an URLFetcher at this point in time. |
533 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 570 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
534 ValidateUpdateFetcherRequest(url_fetcher); | 571 ValidateUpdateFetcherRequest(url_fetcher); |
535 | 572 |
536 // Go ahead and respond to it. | 573 // The first time RunTasks is called above, the update timeout timer is not |
537 url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, | 574 // handled. This call of RunTasks will handle the update. |
538 net::ERR_CONNECTION_RESET)); | 575 runner->RunTasks(); |
539 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 576 |
| 577 EXPECT_TRUE(pm->IsUpdateScheduled()); |
540 } | 578 } |
541 | 579 |
542 // Tests what happens when there is a timeout before an update response. | 580 // Tests what happens when there is a reset command in the response. |
543 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeout) { | 581 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { |
544 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 582 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
545 new ImmediateSingleThreadTaskRunner()); | 583 new ImmediateSingleThreadTaskRunner()); |
546 base::ThreadTaskRunnerHandle runner_handler(runner); | 584 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 585 net::TestURLFetcherFactory url_fetcher_factory; |
| 586 |
| 587 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 588 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 589 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 590 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 591 std::vector<SBListChunkRanges>(), |
| 592 false))); |
| 593 EXPECT_CALL(test_delegate, ResetDatabase()).Times(1); |
| 594 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 595 |
| 596 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 597 CreateProtocolManager(&test_delegate)); |
| 598 |
| 599 // Kick off initialization. This returns chunks from the DB synchronously. |
| 600 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 601 runner->RunTasks(); |
| 602 |
| 603 // We should have an URLFetcher at this point in time. |
| 604 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 605 ValidateUpdateFetcherRequest(url_fetcher); |
| 606 |
| 607 // The update response is successful, and has a reset command. |
| 608 url_fetcher->set_status(net::URLRequestStatus()); |
| 609 url_fetcher->set_response_code(200); |
| 610 url_fetcher->SetResponseString("r:pleasereset\n"); |
| 611 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 612 |
| 613 EXPECT_TRUE(pm->IsUpdateScheduled()); |
| 614 } |
| 615 |
| 616 // Tests a single valid update response, followed by a single redirect response |
| 617 // that has an valid, but empty body. |
| 618 TEST_F(SafeBrowsingProtocolManagerTest, EmptyRedirectResponse) { |
| 619 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 620 new ImmediateSingleThreadTaskRunner()); |
| 621 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 622 net::TestURLFetcherFactory url_fetcher_factory; |
| 623 |
| 624 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 625 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 626 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 627 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 628 std::vector<SBListChunkRanges>(), |
| 629 false))); |
| 630 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 631 |
| 632 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 633 CreateProtocolManager(&test_delegate)); |
| 634 |
| 635 // Kick off initialization. This returns chunks from the DB synchronously. |
| 636 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 637 runner->RunTasks(); |
| 638 |
| 639 // We should have an URLFetcher at this point in time. |
| 640 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 641 ValidateUpdateFetcherRequest(url_fetcher); |
| 642 |
| 643 // The update response is successful, and has a reset command. |
| 644 url_fetcher->set_status(net::URLRequestStatus()); |
| 645 url_fetcher->set_response_code(200); |
| 646 url_fetcher->SetResponseString( |
| 647 "i:goog-phish-shavar\n" |
| 648 "u:redirect-server.example.com/path\n"); |
| 649 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 650 |
| 651 // We should have another request. |
| 652 net::TestURLFetcher* chunk_url_fetcher = |
| 653 url_fetcher_factory.GetFetcherByID(1); |
| 654 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 655 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 656 chunk_url_fetcher->set_response_code(200); |
| 657 chunk_url_fetcher->SetResponseString(""); |
| 658 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 659 |
| 660 EXPECT_TRUE(pm->IsUpdateScheduled()); |
| 661 } |
| 662 |
| 663 // Tests a single valid update response, followed by a single redirect response |
| 664 // that has an invalid body. |
| 665 TEST_F(SafeBrowsingProtocolManagerTest, InvalidRedirectResponse) { |
| 666 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 667 new ImmediateSingleThreadTaskRunner()); |
| 668 base::ThreadTaskRunnerHandle runner_handler(runner); |
547 net::TestURLFetcherFactory url_fetcher_factory; | 669 net::TestURLFetcherFactory url_fetcher_factory; |
548 | 670 |
549 testing::StrictMock<MockProtocolDelegate> test_delegate; | 671 testing::StrictMock<MockProtocolDelegate> test_delegate; |
550 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 672 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
551 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 673 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
552 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 674 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
553 std::vector<SBListChunkRanges>(), | 675 std::vector<SBListChunkRanges>(), |
554 false))); | 676 false))); |
555 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); | 677 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
556 | 678 |
557 scoped_ptr<SafeBrowsingProtocolManager> pm( | 679 scoped_ptr<SafeBrowsingProtocolManager> pm( |
558 CreateProtocolManager(&test_delegate)); | 680 CreateProtocolManager(&test_delegate)); |
559 | 681 |
560 // Kick off initialization. This returns chunks from the DB synchronously. | 682 // Kick off initialization. This returns chunks from the DB synchronously. |
561 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 683 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
562 runner->RunTasks(); | 684 runner->RunTasks(); |
563 | 685 |
564 // We should have an URLFetcher at this point in time. | 686 // We should have an URLFetcher at this point in time. |
565 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 687 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
566 ValidateUpdateFetcherRequest(url_fetcher); | 688 ValidateUpdateFetcherRequest(url_fetcher); |
567 | 689 |
568 // The first time RunTasks is called above, the update timeout timer is not | 690 // The update response is successful, and has a reset command. |
569 // handled. This call of RunTasks will handle the update. | 691 url_fetcher->set_status(net::URLRequestStatus()); |
570 runner->RunTasks(); | 692 url_fetcher->set_response_code(200); |
| 693 url_fetcher->SetResponseString( |
| 694 "i:goog-phish-shavar\n" |
| 695 "u:redirect-server.example.com/path\n"); |
| 696 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 697 |
| 698 // We should have another request. |
| 699 net::TestURLFetcher* chunk_url_fetcher = |
| 700 url_fetcher_factory.GetFetcherByID(1); |
| 701 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 702 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 703 chunk_url_fetcher->set_response_code(200); |
| 704 chunk_url_fetcher->SetResponseString("THIS IS AN INVALID RESPONSE"); |
| 705 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 706 |
| 707 EXPECT_TRUE(pm->IsUpdateScheduled()); |
571 } | 708 } |
572 | 709 |
573 // Tests what happens when there is a reset command in the response. | 710 // Tests a single valid update response, followed by a single redirect response |
574 TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { | 711 // containing chunks. |
| 712 TEST_F(SafeBrowsingProtocolManagerTest, SingleRedirectResponseWithChunks) { |
575 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 713 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
576 new ImmediateSingleThreadTaskRunner()); | 714 new ImmediateSingleThreadTaskRunner()); |
577 base::ThreadTaskRunnerHandle runner_handler(runner); | 715 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 716 net::TestURLFetcherFactory url_fetcher_factory; |
| 717 |
| 718 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 719 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 720 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 721 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 722 std::vector<SBListChunkRanges>(), |
| 723 false))); |
| 724 EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)).WillOnce( |
| 725 testing::WithArgs<2>( |
| 726 Invoke(DeferAddChunksCallback))); |
| 727 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 728 |
| 729 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 730 CreateProtocolManager(&test_delegate)); |
| 731 |
| 732 // Kick off initialization. This returns chunks from the DB synchronously. |
| 733 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 734 runner->RunTasks(); |
| 735 |
| 736 // We should have an URLFetcher at this point in time. |
| 737 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 738 ValidateUpdateFetcherRequest(url_fetcher); |
| 739 |
| 740 // The update response is successful, and has a reset command. |
| 741 url_fetcher->set_status(net::URLRequestStatus()); |
| 742 url_fetcher->set_response_code(200); |
| 743 url_fetcher->SetResponseString( |
| 744 "i:goog-phish-shavar\n" |
| 745 "u:redirect-server.example.com/path\n"); |
| 746 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 747 |
| 748 // We should have another request. |
| 749 net::TestURLFetcher* chunk_url_fetcher = |
| 750 url_fetcher_factory.GetFetcherByID(1); |
| 751 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 752 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 753 chunk_url_fetcher->set_response_code(200); |
| 754 chunk_url_fetcher->SetResponseString( |
| 755 "a:4:4:9\n" |
| 756 "host\1fdaf"); |
| 757 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 758 |
| 759 // The AddChunksCallback needs to be invoked |
| 760 runner->RunTasks(); |
| 761 |
| 762 EXPECT_TRUE(pm->IsUpdateScheduled()); |
| 763 } |
| 764 |
| 765 // Tests a single valid update response, followed by multiple redirect responses |
| 766 // containing chunks. |
| 767 TEST_F(SafeBrowsingProtocolManagerTest, MultipleRedirectResponsesWithChunks) { |
| 768 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 769 new ImmediateSingleThreadTaskRunner()); |
| 770 base::ThreadTaskRunnerHandle runner_handler(runner); |
578 net::TestURLFetcherFactory url_fetcher_factory; | 771 net::TestURLFetcherFactory url_fetcher_factory; |
579 | 772 |
580 testing::StrictMock<MockProtocolDelegate> test_delegate; | 773 testing::StrictMock<MockProtocolDelegate> test_delegate; |
581 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); | 774 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
582 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( | 775 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
583 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, | 776 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
584 std::vector<SBListChunkRanges>(), | 777 std::vector<SBListChunkRanges>(), |
585 false))); | 778 false))); |
586 EXPECT_CALL(test_delegate, ResetDatabase()).Times(1); | 779 EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)). |
| 780 WillRepeatedly(testing::WithArgs<2>( |
| 781 Invoke(DeferAddChunksCallback))); |
587 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); | 782 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
588 | 783 |
589 scoped_ptr<SafeBrowsingProtocolManager> pm( | 784 scoped_ptr<SafeBrowsingProtocolManager> pm( |
590 CreateProtocolManager(&test_delegate)); | 785 CreateProtocolManager(&test_delegate)); |
591 | 786 |
592 // Kick off initialization. This returns chunks from the DB synchronously. | 787 // Kick off initialization. This returns chunks from the DB synchronously. |
593 pm->ForceScheduleNextUpdate(base::TimeDelta()); | 788 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
594 runner->RunTasks(); | 789 runner->RunTasks(); |
595 | 790 |
596 // We should have an URLFetcher at this point in time. | 791 // We should have an URLFetcher at this point in time. |
597 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 792 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
598 ValidateUpdateFetcherRequest(url_fetcher); | 793 ValidateUpdateFetcherRequest(url_fetcher); |
599 | 794 |
600 // The update response is successful, and has a reset command. | 795 // The update response is successful, and has a reset command. |
601 url_fetcher->set_status(net::URLRequestStatus()); | 796 url_fetcher->set_status(net::URLRequestStatus()); |
602 url_fetcher->set_response_code(200); | 797 url_fetcher->set_response_code(200); |
603 url_fetcher->SetResponseString("r:pleasereset\n"); | 798 url_fetcher->SetResponseString( |
| 799 "i:goog-phish-shavar\n" |
| 800 "u:redirect-server.example.com/one\n" |
| 801 "u:redirect-server.example.com/two\n"); |
604 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 802 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 803 |
| 804 // First redirect request. |
| 805 net::TestURLFetcher* first_chunk_url_fetcher = |
| 806 url_fetcher_factory.GetFetcherByID(1); |
| 807 ASSERT_TRUE(first_chunk_url_fetcher != NULL); |
| 808 first_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 809 first_chunk_url_fetcher->set_response_code(200); |
| 810 first_chunk_url_fetcher->SetResponseString( |
| 811 "a:4:4:9\n" |
| 812 "host\1aaaa"); |
| 813 first_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| 814 first_chunk_url_fetcher); |
| 815 |
| 816 // Invoke the AddChunksCallback |
| 817 runner->RunTasks(); |
| 818 |
| 819 // Second redirect request. |
| 820 net::TestURLFetcher* second_chunk_url_fetcher = |
| 821 url_fetcher_factory.GetFetcherByID(2); |
| 822 ASSERT_TRUE(second_chunk_url_fetcher != NULL); |
| 823 second_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 824 second_chunk_url_fetcher->set_response_code(200); |
| 825 second_chunk_url_fetcher->SetResponseString( |
| 826 "a:5:4:9\n" |
| 827 "host\1bbbb"); |
| 828 second_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| 829 second_chunk_url_fetcher); |
| 830 |
| 831 // The AddChunksCallback needs to be invoked |
| 832 runner->RunTasks(); |
| 833 |
| 834 EXPECT_TRUE(pm->IsUpdateScheduled()); |
605 } | 835 } |
OLD | NEW |