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 void DeferAddChunksCallback( |
| 317 SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) { |
| 318 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 319 base::ThreadTaskRunnerHandle::Get()); |
| 320 if (!task_runner) |
| 321 return; |
| 322 task_runner->PostTask(FROM_HERE, callback); |
| 323 } |
| 324 |
315 } // namespace | 325 } // namespace |
316 | 326 |
317 // Tests that the Update protocol will be skipped if there are problems | 327 // Tests that the Update protocol will be skipped if there are problems |
318 // accessing the database. | 328 // accessing the database. |
319 TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) { | 329 TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) { |
320 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( | 330 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
321 new ImmediateSingleThreadTaskRunner()); | 331 new ImmediateSingleThreadTaskRunner()); |
322 base::ThreadTaskRunnerHandle runner_handler(runner); | 332 base::ThreadTaskRunnerHandle runner_handler(runner); |
323 | 333 |
324 testing::StrictMock<MockProtocolDelegate> test_delegate; | 334 testing::StrictMock<MockProtocolDelegate> test_delegate; |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 // We should have an URLFetcher at this point in time. | 606 // We should have an URLFetcher at this point in time. |
597 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); | 607 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
598 ValidateUpdateFetcherRequest(url_fetcher); | 608 ValidateUpdateFetcherRequest(url_fetcher); |
599 | 609 |
600 // The update response is successful, and has a reset command. | 610 // The update response is successful, and has a reset command. |
601 url_fetcher->set_status(net::URLRequestStatus()); | 611 url_fetcher->set_status(net::URLRequestStatus()); |
602 url_fetcher->set_response_code(200); | 612 url_fetcher->set_response_code(200); |
603 url_fetcher->SetResponseString("r:pleasereset\n"); | 613 url_fetcher->SetResponseString("r:pleasereset\n"); |
604 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); | 614 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
605 } | 615 } |
| 616 |
| 617 // Tests a single valid update response, followed by a single redirect response |
| 618 // that has an valid, but empty body. |
| 619 TEST_F(SafeBrowsingProtocolManagerTest, EmptyRedirectResponse) { |
| 620 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 621 new ImmediateSingleThreadTaskRunner()); |
| 622 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 623 net::TestURLFetcherFactory url_fetcher_factory; |
| 624 |
| 625 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 626 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 627 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 628 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 629 std::vector<SBListChunkRanges>(), |
| 630 false))); |
| 631 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 632 |
| 633 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 634 CreateProtocolManager(&test_delegate)); |
| 635 |
| 636 // Kick off initialization. This returns chunks from the DB synchronously. |
| 637 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 638 runner->RunTasks(); |
| 639 |
| 640 // We should have an URLFetcher at this point in time. |
| 641 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 642 ValidateUpdateFetcherRequest(url_fetcher); |
| 643 |
| 644 // The update response is successful, and has a reset command. |
| 645 url_fetcher->set_status(net::URLRequestStatus()); |
| 646 url_fetcher->set_response_code(200); |
| 647 url_fetcher->SetResponseString( |
| 648 "i:goog-phish-shavar\n" |
| 649 "u:redirect-server.example.com/path\n"); |
| 650 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 651 |
| 652 // We should have another request. |
| 653 net::TestURLFetcher* chunk_url_fetcher = |
| 654 url_fetcher_factory.GetFetcherByID(1); |
| 655 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 656 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 657 chunk_url_fetcher->set_response_code(200); |
| 658 chunk_url_fetcher->SetResponseString(""); |
| 659 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 660 } |
| 661 |
| 662 // Tests a single valid update response, followed by a single redirect response |
| 663 // that has an invalid body. |
| 664 TEST_F(SafeBrowsingProtocolManagerTest, InvalidRedirectResponse) { |
| 665 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 666 new ImmediateSingleThreadTaskRunner()); |
| 667 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 668 net::TestURLFetcherFactory url_fetcher_factory; |
| 669 |
| 670 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 671 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 672 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 673 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 674 std::vector<SBListChunkRanges>(), |
| 675 false))); |
| 676 EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
| 677 |
| 678 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 679 CreateProtocolManager(&test_delegate)); |
| 680 |
| 681 // Kick off initialization. This returns chunks from the DB synchronously. |
| 682 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 683 runner->RunTasks(); |
| 684 |
| 685 // We should have an URLFetcher at this point in time. |
| 686 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 687 ValidateUpdateFetcherRequest(url_fetcher); |
| 688 |
| 689 // The update response is successful, and has a reset command. |
| 690 url_fetcher->set_status(net::URLRequestStatus()); |
| 691 url_fetcher->set_response_code(200); |
| 692 url_fetcher->SetResponseString( |
| 693 "i:goog-phish-shavar\n" |
| 694 "u:redirect-server.example.com/path\n"); |
| 695 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 696 |
| 697 // We should have another request. |
| 698 net::TestURLFetcher* chunk_url_fetcher = |
| 699 url_fetcher_factory.GetFetcherByID(1); |
| 700 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 701 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 702 chunk_url_fetcher->set_response_code(200); |
| 703 chunk_url_fetcher->SetResponseString("THIS IS AN INVALID RESPONSE"); |
| 704 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 705 } |
| 706 |
| 707 // Tests a single valid update response, followed by a single redirect response |
| 708 // containing chunks. |
| 709 TEST_F(SafeBrowsingProtocolManagerTest, ChunksRedirectResponse) { |
| 710 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 711 new ImmediateSingleThreadTaskRunner()); |
| 712 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 713 net::TestURLFetcherFactory url_fetcher_factory; |
| 714 |
| 715 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 716 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 717 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 718 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 719 std::vector<SBListChunkRanges>(), |
| 720 false))); |
| 721 EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)).WillOnce( |
| 722 testing::WithArgs<2>( |
| 723 Invoke(DeferAddChunksCallback))); |
| 724 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 725 |
| 726 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 727 CreateProtocolManager(&test_delegate)); |
| 728 |
| 729 // Kick off initialization. This returns chunks from the DB synchronously. |
| 730 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 731 runner->RunTasks(); |
| 732 |
| 733 // We should have an URLFetcher at this point in time. |
| 734 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 735 ValidateUpdateFetcherRequest(url_fetcher); |
| 736 |
| 737 // The update response is successful, and has a reset command. |
| 738 url_fetcher->set_status(net::URLRequestStatus()); |
| 739 url_fetcher->set_response_code(200); |
| 740 url_fetcher->SetResponseString( |
| 741 "i:goog-phish-shavar\n" |
| 742 "u:redirect-server.example.com/path\n"); |
| 743 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 744 |
| 745 // We should have another request. |
| 746 net::TestURLFetcher* chunk_url_fetcher = |
| 747 url_fetcher_factory.GetFetcherByID(1); |
| 748 ASSERT_TRUE(chunk_url_fetcher != NULL); |
| 749 chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 750 chunk_url_fetcher->set_response_code(200); |
| 751 chunk_url_fetcher->SetResponseString( |
| 752 "a:4:4:9\n" |
| 753 "host\1fdaf"); |
| 754 chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| 755 |
| 756 // The AddChunksCallback needs to be invoked |
| 757 runner->RunTasks(); |
| 758 } |
| 759 |
| 760 // Tests a single valid update response, followed by multiple redirect responses |
| 761 // containing chunks. |
| 762 TEST_F(SafeBrowsingProtocolManagerTest, ChunksMultipleRedirectResponse) { |
| 763 scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| 764 new ImmediateSingleThreadTaskRunner()); |
| 765 base::ThreadTaskRunnerHandle runner_handler(runner); |
| 766 net::TestURLFetcherFactory url_fetcher_factory; |
| 767 |
| 768 testing::StrictMock<MockProtocolDelegate> test_delegate; |
| 769 EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| 770 EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| 771 Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| 772 std::vector<SBListChunkRanges>(), |
| 773 false))); |
| 774 EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)). |
| 775 WillRepeatedly(testing::WithArgs<2>( |
| 776 Invoke(DeferAddChunksCallback))); |
| 777 EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| 778 |
| 779 scoped_ptr<SafeBrowsingProtocolManager> pm( |
| 780 CreateProtocolManager(&test_delegate)); |
| 781 |
| 782 // Kick off initialization. This returns chunks from the DB synchronously. |
| 783 pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| 784 runner->RunTasks(); |
| 785 |
| 786 // We should have an URLFetcher at this point in time. |
| 787 net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| 788 ValidateUpdateFetcherRequest(url_fetcher); |
| 789 |
| 790 // The update response is successful, and has a reset command. |
| 791 url_fetcher->set_status(net::URLRequestStatus()); |
| 792 url_fetcher->set_response_code(200); |
| 793 url_fetcher->SetResponseString( |
| 794 "i:goog-phish-shavar\n" |
| 795 "u:redirect-server.example.com/one\n" |
| 796 "u:redirect-server.example.com/two\n"); |
| 797 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| 798 |
| 799 // First redirect request. |
| 800 net::TestURLFetcher* first_chunk_url_fetcher = |
| 801 url_fetcher_factory.GetFetcherByID(1); |
| 802 ASSERT_TRUE(first_chunk_url_fetcher != NULL); |
| 803 first_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 804 first_chunk_url_fetcher->set_response_code(200); |
| 805 first_chunk_url_fetcher->SetResponseString( |
| 806 "a:4:4:9\n" |
| 807 "host\1aaaa"); |
| 808 first_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| 809 first_chunk_url_fetcher); |
| 810 |
| 811 // Invoke the AddChunksCallback |
| 812 runner->RunTasks(); |
| 813 |
| 814 // Second redirect request. |
| 815 net::TestURLFetcher* second_chunk_url_fetcher = |
| 816 url_fetcher_factory.GetFetcherByID(2); |
| 817 ASSERT_TRUE(second_chunk_url_fetcher != NULL); |
| 818 second_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| 819 second_chunk_url_fetcher->set_response_code(200); |
| 820 second_chunk_url_fetcher->SetResponseString( |
| 821 "a:5:4:9\n" |
| 822 "host\1bbbb"); |
| 823 second_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| 824 second_chunk_url_fetcher); |
| 825 |
| 826 // The AddChunksCallback needs to be invoked |
| 827 runner->RunTasks(); |
| 828 } |
OLD | NEW |