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()); |
} |