Chromium Code Reviews| Index: chrome/browser/safe_browsing/protocol_manager_unittest.cc |
| diff --git a/chrome/browser/safe_browsing/protocol_manager_unittest.cc b/chrome/browser/safe_browsing/protocol_manager_unittest.cc |
| index 75f4097b89681bcfa7b62eedd9b55abfabcb2637..96bf6978b14c1a55999bf8bc30144da7bfa98de1 100644 |
| --- a/chrome/browser/safe_browsing/protocol_manager_unittest.cc |
| +++ b/chrome/browser/safe_browsing/protocol_manager_unittest.cc |
| @@ -253,7 +253,8 @@ class MockProtocolDelegate : public SafeBrowsingProtocolManagerDelegate { |
| MOCK_METHOD1(UpdateFinished, void(bool)); |
| MOCK_METHOD0(ResetDatabase, void()); |
| MOCK_METHOD1(GetChunks, void(GetChunksCallback)); |
| - MOCK_METHOD2(AddChunks, void(const std::string&, SBChunkList*)); |
| + MOCK_METHOD3(AddChunks, void(const std::string&, SBChunkList*, |
| + AddChunksCallback)); |
| MOCK_METHOD1(DeleteChunks, void(std::vector<SBChunkDelete>*)); |
| }; |
| @@ -312,6 +313,22 @@ void InvokeGetChunksCallback( |
| callback.Run(ranges, database_error); |
| } |
| +// |HandleAddChunks| deletes the chunks and asynchronously invokes |
| +// |callback| since SafeBrowsingProtocolManager is not re-entrant at the time |
| +// this is called. This guarantee is part of the |
| +// SafeBrowsingProtocolManagerDelegate contract. |
| +void HandleAddChunks( |
| + const std::string& unused_list, |
| + SBChunkList* chunks, |
| + SafeBrowsingProtocolManagerDelegate::AddChunksCallback callback) { |
| + delete chunks; |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| + base::ThreadTaskRunnerHandle::Get()); |
| + if (!task_runner) |
| + return; |
| + task_runner->PostTask(FROM_HERE, callback); |
| +} |
| + |
| } // namespace |
| // Tests that the Update protocol will be skipped if there are problems |
| @@ -334,10 +351,12 @@ TEST_F(SafeBrowsingProtocolManagerTest, ProblemAccessingDatabase) { |
| pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| runner->RunTasks(); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
|
mattm
2012/12/06 00:51:40
Could inserting some EXPECT_FALSE(pm->IsUpdateSche
cbentzel
2012/12/17 11:24:10
I put it in a few locations (such as the multiple
|
| } |
| -// Tests the contents of the POST body when the local database is empty. |
| -TEST_F(SafeBrowsingProtocolManagerTest, EmptyDatabase) { |
| +// Tests what happens when there is a response with no chunks. |
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -349,6 +368,7 @@ TEST_F(SafeBrowsingProtocolManagerTest, EmptyDatabase) { |
| Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| std::vector<SBListChunkRanges>(), |
| false))); |
| + EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| scoped_ptr<SafeBrowsingProtocolManager> pm( |
| CreateProtocolManager(&test_delegate)); |
| @@ -360,6 +380,14 @@ TEST_F(SafeBrowsingProtocolManagerTest, EmptyDatabase) { |
| // We should have an URLFetcher at this point in time. |
| net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| ValidateUpdateFetcherRequest(url_fetcher); |
| + |
| + // The update response is successful, but an empty body. |
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString(""); |
| + url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| // Tests the contents of the POST body when there are contents in the |
| @@ -388,6 +416,7 @@ TEST_F(SafeBrowsingProtocolManagerTest, ExistingDatabase) { |
| Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| ranges, |
| false))); |
| + EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| scoped_ptr<SafeBrowsingProtocolManager> pm( |
| CreateProtocolManager(&test_delegate)); |
| @@ -407,10 +436,16 @@ TEST_F(SafeBrowsingProtocolManagerTest, ExistingDatabase) { |
| EXPECT_EQ(GURL("https://prefix.com/foo/downloads?client=unittest&appver=1.0" |
| "&pver=2.2" + key_param_), |
| url_fetcher->GetOriginalURL()); |
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString(""); |
| + url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -// Tests what happens when there is a response with no chunks. |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { |
| + |
|
mattm
2012/12/05 23:58:10
extra line
cbentzel
2012/12/17 11:24:10
Done.
|
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadyBody) { |
|
mattm
2012/12/05 23:58:10
s/Bady/Bad/
cbentzel
2012/12/17 11:24:10
Done.
|
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -422,7 +457,7 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { |
| Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| std::vector<SBListChunkRanges>(), |
| false))); |
| - EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| + EXPECT_CALL(test_delegate, UpdateFinished(false)).Times(1); |
| scoped_ptr<SafeBrowsingProtocolManager> pm( |
| CreateProtocolManager(&test_delegate)); |
| @@ -435,14 +470,17 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseEmptyBody) { |
| net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| ValidateUpdateFetcherRequest(url_fetcher); |
| - // The update response is successful, but an empty body. |
| + // The update response is successful, but an invalid body. |
| url_fetcher->set_status(net::URLRequestStatus()); |
| url_fetcher->set_response_code(200); |
| - url_fetcher->SetResponseString(""); |
| + url_fetcher->SetResponseString("THIS_IS_A_BAD_RESPONSE"); |
| url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadBody) { |
| +// Tests what happens when there is an error in the update response. |
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpError) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -467,15 +505,17 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseBadBody) { |
| net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| ValidateUpdateFetcherRequest(url_fetcher); |
| - // The update response is successful, but an invalid body. |
| + // Go ahead and respond to it. |
| url_fetcher->set_status(net::URLRequestStatus()); |
| - url_fetcher->set_response_code(200); |
| - url_fetcher->SetResponseString("THIS_IS_A_BAD_RESPONSE"); |
| + url_fetcher->set_response_code(404); |
| + url_fetcher->SetResponseString(""); |
| url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -// Tests what happens when there is an error in the update response. |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpError) { |
| +// Tests what happens when there is an error with the connection. |
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseConnectionError) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -501,14 +541,15 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseHttpError) { |
| ValidateUpdateFetcherRequest(url_fetcher); |
| // Go ahead and respond to it. |
| - url_fetcher->set_status(net::URLRequestStatus()); |
| - url_fetcher->set_response_code(404); |
| - url_fetcher->SetResponseString(""); |
| + url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| + net::ERR_CONNECTION_RESET)); |
| url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -// Tests what happens when there is an error with the connection. |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseConnectionError) { |
| +// Tests what happens when there is a timeout before an update response. |
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeout) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -533,14 +574,99 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseConnectionError) { |
| net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| ValidateUpdateFetcherRequest(url_fetcher); |
| - // Go ahead and respond to it. |
| - url_fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| - net::ERR_CONNECTION_RESET)); |
| + // The first time RunTasks is called above, the update timeout timer is not |
| + // handled. This call of RunTasks will handle the update. |
| + runner->RunTasks(); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| +} |
| + |
| +// Tests what happens when there is a reset command in the response. |
| +TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { |
| + scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| + new ImmediateSingleThreadTaskRunner()); |
| + base::ThreadTaskRunnerHandle runner_handler(runner); |
| + net::TestURLFetcherFactory url_fetcher_factory; |
| + |
| + testing::StrictMock<MockProtocolDelegate> test_delegate; |
| + EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| + EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| + Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| + std::vector<SBListChunkRanges>(), |
| + false))); |
| + EXPECT_CALL(test_delegate, ResetDatabase()).Times(1); |
| + EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| + |
| + scoped_ptr<SafeBrowsingProtocolManager> pm( |
| + CreateProtocolManager(&test_delegate)); |
| + |
| + // Kick off initialization. This returns chunks from the DB synchronously. |
| + pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| + runner->RunTasks(); |
| + |
| + // We should have an URLFetcher at this point in time. |
| + net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| + ValidateUpdateFetcherRequest(url_fetcher); |
| + |
| + // The update response is successful, and has a reset command. |
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString("r:pleasereset\n"); |
| url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -// Tests what happens when there is a timeout before an update response. |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeout) { |
| +// Tests a single valid update response, followed by a single redirect response |
| +// that has an valid, but empty body. |
| +TEST_F(SafeBrowsingProtocolManagerTest, EmptyRedirectResponse) { |
| + scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| + new ImmediateSingleThreadTaskRunner()); |
| + base::ThreadTaskRunnerHandle runner_handler(runner); |
| + net::TestURLFetcherFactory url_fetcher_factory; |
| + |
| + testing::StrictMock<MockProtocolDelegate> test_delegate; |
| + EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| + EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| + Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| + std::vector<SBListChunkRanges>(), |
| + false))); |
| + EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| + |
| + scoped_ptr<SafeBrowsingProtocolManager> pm( |
| + CreateProtocolManager(&test_delegate)); |
| + |
| + // Kick off initialization. This returns chunks from the DB synchronously. |
| + pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| + runner->RunTasks(); |
| + |
| + // We should have an URLFetcher at this point in time. |
| + net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| + ValidateUpdateFetcherRequest(url_fetcher); |
| + |
| + // The update response is successful, and has a reset command. |
|
mattm
2012/12/06 00:51:40
s/reset/redirect/
(in following tests too)
cbentzel
2012/12/17 11:24:10
Done.
|
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString( |
| + "i:goog-phish-shavar\n" |
| + "u:redirect-server.example.com/path\n"); |
| + url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + // We should have another request. |
| + net::TestURLFetcher* chunk_url_fetcher = |
| + url_fetcher_factory.GetFetcherByID(1); |
| + ASSERT_TRUE(chunk_url_fetcher != NULL); |
|
mattm
2012/12/06 00:51:40
Should test the fetched URL value as well, at leas
cbentzel
2012/12/17 11:24:10
Done.
|
| + chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| + chunk_url_fetcher->set_response_code(200); |
| + chunk_url_fetcher->SetResponseString(""); |
| + chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| +} |
| + |
| +// Tests a single valid update response, followed by a single redirect response |
| +// that has an invalid body. |
| +TEST_F(SafeBrowsingProtocolManagerTest, InvalidRedirectResponse) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -565,13 +691,83 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseTimeout) { |
| net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| ValidateUpdateFetcherRequest(url_fetcher); |
| - // The first time RunTasks is called above, the update timeout timer is not |
| - // handled. This call of RunTasks will handle the update. |
| + // The update response is successful, and has a reset command. |
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString( |
| + "i:goog-phish-shavar\n" |
| + "u:redirect-server.example.com/path\n"); |
| + url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + // We should have another request. |
| + net::TestURLFetcher* chunk_url_fetcher = |
| + url_fetcher_factory.GetFetcherByID(1); |
| + ASSERT_TRUE(chunk_url_fetcher != NULL); |
| + chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| + chunk_url_fetcher->set_response_code(200); |
| + chunk_url_fetcher->SetResponseString("THIS IS AN INVALID RESPONSE"); |
| + chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| +} |
| + |
| +// Tests a single valid update response, followed by a single redirect response |
| +// containing chunks. |
| +TEST_F(SafeBrowsingProtocolManagerTest, SingleRedirectResponseWithChunks) { |
| + scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| + new ImmediateSingleThreadTaskRunner()); |
| + base::ThreadTaskRunnerHandle runner_handler(runner); |
| + net::TestURLFetcherFactory url_fetcher_factory; |
| + |
| + testing::StrictMock<MockProtocolDelegate> test_delegate; |
| + EXPECT_CALL(test_delegate, UpdateStarted()).Times(1); |
| + EXPECT_CALL(test_delegate, GetChunks(_)).WillOnce( |
| + Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| + std::vector<SBListChunkRanges>(), |
| + false))); |
| + EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)).WillOnce( |
| + Invoke(HandleAddChunks)); |
| + EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| + |
| + scoped_ptr<SafeBrowsingProtocolManager> pm( |
| + CreateProtocolManager(&test_delegate)); |
| + |
| + // Kick off initialization. This returns chunks from the DB synchronously. |
| + pm->ForceScheduleNextUpdate(base::TimeDelta()); |
| + runner->RunTasks(); |
| + |
| + // We should have an URLFetcher at this point in time. |
| + net::TestURLFetcher* url_fetcher = url_fetcher_factory.GetFetcherByID(0); |
| + ValidateUpdateFetcherRequest(url_fetcher); |
| + |
| + // The update response is successful, and has a reset command. |
| + url_fetcher->set_status(net::URLRequestStatus()); |
| + url_fetcher->set_response_code(200); |
| + url_fetcher->SetResponseString( |
| + "i:goog-phish-shavar\n" |
| + "u:redirect-server.example.com/path\n"); |
| + url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + // We should have another request. |
| + net::TestURLFetcher* chunk_url_fetcher = |
| + url_fetcher_factory.GetFetcherByID(1); |
| + ASSERT_TRUE(chunk_url_fetcher != NULL); |
| + chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| + chunk_url_fetcher->set_response_code(200); |
| + chunk_url_fetcher->SetResponseString( |
| + "a:4:4:9\n" |
| + "host\1fdaf"); |
| + chunk_url_fetcher->delegate()->OnURLFetchComplete(chunk_url_fetcher); |
| + |
| + // The AddChunksCallback needs to be invoked |
| runner->RunTasks(); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |
| -// Tests what happens when there is a reset command in the response. |
| -TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { |
| +// Tests a single valid update response, followed by multiple redirect responses |
| +// containing chunks. |
| +TEST_F(SafeBrowsingProtocolManagerTest, MultipleRedirectResponsesWithChunks) { |
| scoped_refptr<ImmediateSingleThreadTaskRunner> runner( |
| new ImmediateSingleThreadTaskRunner()); |
| base::ThreadTaskRunnerHandle runner_handler(runner); |
| @@ -583,7 +779,8 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { |
| Invoke(testing::CreateFunctor(InvokeGetChunksCallback, |
| std::vector<SBListChunkRanges>(), |
| false))); |
| - EXPECT_CALL(test_delegate, ResetDatabase()).Times(1); |
| + EXPECT_CALL(test_delegate, AddChunks("goog-phish-shavar", _, _)). |
| + WillRepeatedly(Invoke(HandleAddChunks)); |
| EXPECT_CALL(test_delegate, UpdateFinished(true)).Times(1); |
| scoped_ptr<SafeBrowsingProtocolManager> pm( |
| @@ -600,6 +797,41 @@ TEST_F(SafeBrowsingProtocolManagerTest, UpdateResponseReset) { |
| // The update response is successful, and has a reset command. |
| url_fetcher->set_status(net::URLRequestStatus()); |
| url_fetcher->set_response_code(200); |
| - url_fetcher->SetResponseString("r:pleasereset\n"); |
| + url_fetcher->SetResponseString( |
| + "i:goog-phish-shavar\n" |
| + "u:redirect-server.example.com/one\n" |
| + "u:redirect-server.example.com/two\n"); |
| url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); |
| + |
| + // First redirect request. |
| + net::TestURLFetcher* first_chunk_url_fetcher = |
|
mattm
2012/12/06 00:51:40
should probably check the URLs on these requests t
cbentzel
2012/12/17 11:24:10
Done.
|
| + url_fetcher_factory.GetFetcherByID(1); |
| + ASSERT_TRUE(first_chunk_url_fetcher != NULL); |
| + first_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| + first_chunk_url_fetcher->set_response_code(200); |
| + first_chunk_url_fetcher->SetResponseString( |
| + "a:4:4:9\n" |
| + "host\1aaaa"); |
| + first_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| + first_chunk_url_fetcher); |
| + |
| + // Invoke the AddChunksCallback |
| + runner->RunTasks(); |
| + |
| + // Second redirect request. |
| + net::TestURLFetcher* second_chunk_url_fetcher = |
| + url_fetcher_factory.GetFetcherByID(2); |
| + ASSERT_TRUE(second_chunk_url_fetcher != NULL); |
| + second_chunk_url_fetcher->set_status(net::URLRequestStatus()); |
| + second_chunk_url_fetcher->set_response_code(200); |
| + second_chunk_url_fetcher->SetResponseString( |
| + "a:5:4:9\n" |
| + "host\1bbbb"); |
| + second_chunk_url_fetcher->delegate()->OnURLFetchComplete( |
| + second_chunk_url_fetcher); |
| + |
| + // The AddChunksCallback needs to be invoked |
| + runner->RunTasks(); |
| + |
| + EXPECT_TRUE(pm->IsUpdateScheduled()); |
| } |