Index: chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
index 629cbf09ea407bb002948d1d0ea933e34f45389c..34014d3c3c578dd45eb3cdd23320ddec8346f6bf 100644 |
--- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
+++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc |
@@ -86,6 +86,12 @@ ACTION_TEMPLATE(InvokeCallbackArgument, |
::std::tr1::get<k>(args).Run(p0, p1); |
} |
+ACTION_P(InvokeMalwareCallback, verdict) { |
+ scoped_ptr<ClientMalwareRequest> request(::std::tr1::get<1>(args)); |
+ request->CopyFrom(*verdict); |
+ ::std::tr1::get<2>(args).Run(true, request.Pass()); |
+} |
+ |
void EmptyUrlCheckCallback(bool processed) { |
} |
@@ -139,6 +145,7 @@ class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { |
: SafeBrowsingDatabaseManager(service) { } |
MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); |
+ MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address)); |
protected: |
virtual ~MockSafeBrowsingDatabaseManager() {} |
@@ -159,18 +166,19 @@ class MockBrowserFeatureExtractor : public BrowserFeatureExtractor { |
public: |
explicit MockBrowserFeatureExtractor( |
WebContents* tab, |
- ClientSideDetectionService* service) |
- : BrowserFeatureExtractor(tab, service) {} |
+ ClientSideDetectionHost* host) |
+ : BrowserFeatureExtractor(tab, host) {} |
virtual ~MockBrowserFeatureExtractor() {} |
MOCK_METHOD3(ExtractFeatures, |
- void(const BrowseInfo* info, |
+ void(const BrowseInfo*, |
ClientPhishingRequest*, |
const BrowserFeatureExtractor::DoneCallback&)); |
- MOCK_METHOD2(ExtractMalwareFeatures, |
- void(const BrowseInfo* info, |
- ClientMalwareRequest*)); |
+ MOCK_METHOD3(ExtractMalwareFeatures, |
+ void(BrowseInfo*, |
+ ClientMalwareRequest*, |
+ const BrowserFeatureExtractor::MalwareDoneCallback&)); |
}; |
} // namespace |
@@ -330,9 +338,10 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneInvalidVerdict) { |
#endif |
// Case 0: renderer sends an invalid verdict string that we're unable to |
// parse. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0); |
OnPhishingDetectionDone("Invalid Protocol Buffer"); |
@@ -348,9 +357,10 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneNotPhishing) { |
#endif |
// Case 1: client thinks the page is phishing. The server does not agree. |
// No interstitial is shown. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientSideDetectionService::ClientReportPhishingRequestCallback cb; |
@@ -359,15 +369,19 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneNotPhishing) { |
verdict.set_client_score(1.0f); |
verdict.set_is_phishing(true); |
+ ClientMalwareRequest malware_verdict; |
+ malware_verdict.set_url(verdict.url()); |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) |
.WillOnce(DoAll(DeleteArg<1>(), |
InvokeCallbackArgument<2>(true, &verdict))); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportPhishingRequest( |
Pointee(PartiallyEqualVerdict(verdict)), _)) |
.WillOnce(SaveArg<1>(&cb)); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
- EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
ASSERT_FALSE(cb.is_null()); |
// Make sure DoDisplayBlockingPage is not going to be called. |
@@ -385,9 +399,10 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneDisabled) { |
#endif |
// Case 2: client thinks the page is phishing and so does the server but |
// showing the interstitial is disabled => no interstitial is shown. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientSideDetectionService::ClientReportPhishingRequestCallback cb; |
@@ -403,8 +418,16 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneDisabled) { |
SendClientReportPhishingRequest( |
Pointee(PartiallyEqualVerdict(verdict)), _)) |
.WillOnce(SaveArg<1>(&cb)); |
+ |
+ ClientMalwareRequest malware_verdict; |
+ malware_verdict.set_url(verdict.url()); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
+ EXPECT_CALL(*csd_service_, |
+ SendClientReportMalwareRequest(_, _)).Times(0); |
+ |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
- EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
ASSERT_FALSE(cb.is_null()); |
// Make sure DoDisplayBlockingPage is not going to be called. |
@@ -423,9 +446,10 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneShowInterstitial) { |
#endif |
// Case 3: client thinks the page is phishing and so does the server. |
// We show an interstitial. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientSideDetectionService::ClientReportPhishingRequestCallback cb; |
@@ -435,14 +459,20 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneShowInterstitial) { |
verdict.set_client_score(1.0f); |
verdict.set_is_phishing(true); |
+ ClientMalwareRequest malware_verdict; |
+ malware_verdict.set_url(verdict.url()); |
+ |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) |
.WillOnce(DoAll(DeleteArg<1>(), |
InvokeCallbackArgument<2>(true, &verdict))); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportPhishingRequest( |
Pointee(PartiallyEqualVerdict(verdict)), _)) |
.WillOnce(SaveArg<1>(&cb)); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
ASSERT_FALSE(cb.is_null()); |
@@ -482,9 +512,10 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneMultiplePings) { |
// before the server responds with a verdict. After a while the |
// server responds for both requests with a phishing verdict. Only |
// a single interstitial is shown for the second URL. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientSideDetectionService::ClientReportPhishingRequestCallback cb; |
@@ -494,14 +525,20 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneMultiplePings) { |
verdict.set_client_score(1.0f); |
verdict.set_is_phishing(true); |
+ ClientMalwareRequest malware_verdict; |
+ malware_verdict.set_url(verdict.url()); |
+ |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) |
.WillOnce(DoAll(DeleteArg<1>(), |
InvokeCallbackArgument<2>(true, &verdict))); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportPhishingRequest( |
Pointee(PartiallyEqualVerdict(verdict)), _)) |
.WillOnce(SaveArg<1>(&cb)); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
ASSERT_FALSE(cb.is_null()); |
@@ -509,7 +546,7 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneMultiplePings) { |
// NavigateAndCommit() and it's easier to use the real thing than setting up |
// mock expectations. |
SetFeatureExtractor(new BrowserFeatureExtractor(web_contents(), |
- csd_service_.get())); |
+ csd_host_.get())); |
GURL other_phishing_url("http://other_phishing_url.com/bla"); |
ExpectPreClassificationChecks(other_phishing_url, &kFalse, &kFalse, &kFalse, |
&kFalse, &kFalse, &kFalse); |
@@ -532,6 +569,7 @@ TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneMultiplePings) { |
SetRedirectChain(redirect_chain); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
base::MessageLoop::current()->Run(); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
ASSERT_FALSE(cb_other.is_null()); |
@@ -572,9 +610,10 @@ TEST_F(ClientSideDetectionHostTest, |
OnPhishingDetectionDoneVerdictNotPhishing) { |
#endif |
// Case 6: renderer sends a verdict string that isn't phishing. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientPhishingRequest verdict; |
@@ -582,7 +621,12 @@ TEST_F(ClientSideDetectionHostTest, |
verdict.set_client_score(0.1f); |
verdict.set_is_phishing(false); |
+ ClientMalwareRequest malware_verdict; |
+ malware_verdict.set_url(verdict.url()); |
+ |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor)); |
} |
@@ -619,7 +663,7 @@ TEST_F(ClientSideDetectionHostTest, |
SetRedirectChain(redirect_chain); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
base::MessageLoop::current()->Run(); |
- EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
} |
#if defined(OS_WIN) |
@@ -690,9 +734,10 @@ TEST_F(ClientSideDetectionHostTest, |
#endif |
// Case 7: renderer sends a verdict string that isn't phishing and not matches |
// malware bad IP list |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientPhishingRequest verdict; |
@@ -701,10 +746,12 @@ TEST_F(ClientSideDetectionHostTest, |
verdict.set_is_phishing(false); |
ClientMalwareRequest malware_verdict; |
- malware_verdict.set_url("http://not-phishing.com/"); |
+ malware_verdict.set_url(verdict.url()); |
- EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _)) |
- .WillOnce(SetArgumentPointee<1>(malware_verdict)); |
+ // That is a special case. If there were no IP matches or if feature |
+ // extraction failed the callback will delete the malware_verdict. |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportMalwareRequest(_, _)).Times(0); |
EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0); |
@@ -723,9 +770,10 @@ TEST_F(ClientSideDetectionHostTest, |
#endif |
// Case 8: renderer sends a verdict string that isn't phishing but matches |
// malware bad IP list |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientPhishingRequest verdict; |
@@ -734,14 +782,14 @@ TEST_F(ClientSideDetectionHostTest, |
verdict.set_is_phishing(false); |
ClientMalwareRequest malware_verdict; |
- malware_verdict.set_url("http://not-phishing.com/"); |
+ malware_verdict.set_url(verdict.url()); |
ClientMalwareRequest::Feature* feature = malware_verdict.add_feature_map(); |
feature->set_name("malwareip1.2.3.4"); |
feature->set_value(1.0); |
feature->add_metainfo("badip.com"); |
- EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _)) |
- .WillOnce(SetArgumentPointee<1>(malware_verdict)); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportMalwareRequest( |
Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _)) |
@@ -762,9 +810,10 @@ TEST_F(ClientSideDetectionHostTest, |
#endif |
// Case 9: renderer sends a verdict string that is phishing and matches |
// malware bad IP list |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientSideDetectionService::ClientReportPhishingRequestCallback cb; |
@@ -774,14 +823,14 @@ TEST_F(ClientSideDetectionHostTest, |
verdict.set_is_phishing(true); |
ClientMalwareRequest malware_verdict; |
- malware_verdict.set_url("http://not-phishing.com/"); |
+ malware_verdict.set_url(verdict.url()); |
ClientMalwareRequest::Feature* feature = malware_verdict.add_feature_map(); |
feature->set_name("malwareip1.2.3.4"); |
feature->set_value(1.0); |
feature->add_metainfo("badip.com"); |
- EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _)) |
- .WillOnce(SetArgumentPointee<1>(malware_verdict)); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportMalwareRequest( |
Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _)) |
@@ -797,6 +846,7 @@ TEST_F(ClientSideDetectionHostTest, |
.WillOnce(SaveArg<1>(&cb)); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor)); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
ASSERT_FALSE(cb.is_null()); |
} |
@@ -811,9 +861,10 @@ TEST_F(ClientSideDetectionHostTest, |
#endif |
// Case 10: client thinks the page match malware IP and so does the server. |
// We show an sub-resource malware interstitial. |
- MockBrowserFeatureExtractor* mock_extractor = new MockBrowserFeatureExtractor( |
- web_contents(), |
- csd_service_.get()); |
+ MockBrowserFeatureExtractor* mock_extractor = |
+ new StrictMock<MockBrowserFeatureExtractor>( |
+ web_contents(), |
+ csd_host_.get()); |
SetFeatureExtractor(mock_extractor); // The host class takes ownership. |
ClientPhishingRequest verdict; |
@@ -831,14 +882,14 @@ TEST_F(ClientSideDetectionHostTest, |
feature->set_value(1.0); |
feature->add_metainfo("http://badip.com"); |
- EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _)) |
- .WillOnce(SetArgumentPointee<1>(malware_verdict)); |
+ EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _)) |
+ .WillOnce(InvokeMalwareCallback(&malware_verdict)); |
EXPECT_CALL(*csd_service_, |
SendClientReportMalwareRequest( |
Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _)) |
- .WillOnce(DoAll(DeleteArg<0>(), |
- SaveArg<1>(&cb))); |
+ .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb))); |
OnPhishingDetectionDone(verdict.SerializeAsString()); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
ASSERT_FALSE(cb.is_null()); |
@@ -1045,7 +1096,7 @@ TEST_F(ClientSideDetectionHostTest, ShouldClassifyUrl) { |
base::RunLoop().RunUntilIdle(); |
// Now we check that all expected functions were indeed called on the two |
// service objects. |
- EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); |
+ EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); |
EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get())); |
EXPECT_EQ(url, resource.url); |
EXPECT_EQ(url, resource.original_url); |
@@ -1054,5 +1105,4 @@ TEST_F(ClientSideDetectionHostTest, ShouldClassifyUrl) { |
SafeBrowsingMsg_StartPhishingDetection::ID); |
ASSERT_FALSE(msg); |
} |
- |
} // namespace safe_browsing |