Index: chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc |
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc |
index ccffd4085d028680e706f5c8cda5c015db8391b5..d4993543ad4a289279fc3595147d9b32e8294dd0 100644 |
--- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc |
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc |
@@ -6,13 +6,12 @@ |
#include "base/threading/thread_task_runner_handle.h" |
#include "components/certificate_reporting/encrypted_cert_logger.pb.h" |
+#include "components/certificate_reporting/error_report.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/test/test_utils.h" |
#include "crypto/curve25519.h" |
#include "net/base/upload_bytes_element_reader.h" |
#include "net/base/upload_data_stream.h" |
-#include "net/test/url_request/url_request_failed_job.h" |
-#include "net/test/url_request/url_request_mock_data_job.h" |
#include "net/url_request/url_request_filter.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -55,16 +54,129 @@ std::string GetReportContents(net::URLRequest* request, |
return decrypted_report; |
} |
+// Checks that the serialized reports in |observed_reports| have the same |
+// hostnames as |expected_hostnames|. |
+void CompareHostnames(const std::set<std::string>& expected_hostnames, |
+ const std::set<std::string>& observed_reports, |
+ const std::string& comparison_type) { |
+ std::set<std::string> observed_hostnames; |
+ for (const std::string& serialized_report : observed_reports) { |
+ certificate_reporting::ErrorReport report; |
+ ASSERT_TRUE(report.InitializeFromString(serialized_report)); |
+ observed_hostnames.insert(report.hostname()); |
+ } |
+ EXPECT_EQ(expected_hostnames, observed_hostnames) |
+ << "Comparison failed for " << comparison_type << " reports."; |
+} |
+ |
+void WaitReports( |
+ certificate_reporting_test_utils::RequestObserver* observer, |
+ const certificate_reporting_test_utils::ReportExpectation& expectation) { |
+ observer->Wait(expectation.num_reports()); |
+ CompareHostnames(expectation.successful_reports, |
+ observer->successful_reports(), "successful"); |
+ CompareHostnames(expectation.failed_reports, observer->failed_reports(), |
+ "failed"); |
+ CompareHostnames(expectation.delayed_reports, observer->delayed_reports(), |
+ "delayed"); |
+ observer->ClearObservedReports(); |
+} |
+ |
} // namespace |
namespace certificate_reporting_test_utils { |
+RequestObserver::RequestObserver() |
+ : num_events_to_wait_for_(0), num_received_events_(0) {} |
+RequestObserver::~RequestObserver() {} |
+ |
+void RequestObserver::Wait(int num_events_to_wait_for) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ DCHECK(!run_loop_); |
+ ASSERT_LE(num_received_events_, num_events_to_wait_for) |
+ << "Observed unexpected report"; |
+ |
+ if (num_received_events_ < num_events_to_wait_for) { |
+ num_events_to_wait_for_ = num_events_to_wait_for; |
+ run_loop_.reset(new base::RunLoop()); |
+ run_loop_->Run(); |
+ run_loop_.reset(nullptr); |
+ EXPECT_EQ(0, num_received_events_); |
+ EXPECT_EQ(0, num_events_to_wait_for_); |
+ } else if (num_received_events_ == num_events_to_wait_for) { |
+ num_received_events_ = 0; |
+ num_events_to_wait_for_ = 0; |
+ } |
+} |
+ |
+void RequestObserver::OnRequest(const std::string& serialized_report, |
+ ReportSendingResult report_type) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ switch (report_type) { |
+ case REPORTS_SUCCESSFUL: |
+ successful_reports_.insert(serialized_report); |
+ break; |
+ case REPORTS_FAIL: |
+ failed_reports_.insert(serialized_report); |
+ break; |
+ case REPORTS_DELAY: |
+ delayed_reports_.insert(serialized_report); |
+ break; |
+ } |
+ |
+ num_received_events_++; |
+ if (!run_loop_) { |
+ return; |
+ } |
+ ASSERT_LE(num_received_events_, num_events_to_wait_for_) |
+ << "Observed unexpected report"; |
+ |
+ if (num_received_events_ == num_events_to_wait_for_) { |
+ num_events_to_wait_for_ = 0; |
+ num_received_events_ = 0; |
+ run_loop_->Quit(); |
+ } |
+} |
+ |
+const std::set<std::string>& RequestObserver::successful_reports() const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ return successful_reports_; |
+} |
+ |
+const std::set<std::string>& RequestObserver::failed_reports() const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ return failed_reports_; |
+} |
+ |
+const std::set<std::string>& RequestObserver::delayed_reports() const { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ return delayed_reports_; |
+} |
+ |
+void RequestObserver::ClearObservedReports() { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ successful_reports_.clear(); |
+ failed_reports_.clear(); |
+ delayed_reports_.clear(); |
+} |
+ |
DelayableCertReportURLRequestJob::DelayableCertReportURLRequestJob( |
+ bool delayed, |
+ bool should_fail, |
net::URLRequest* request, |
- net::NetworkDelegate* network_delegate) |
- : net::URLRequestJob(request, network_delegate), weak_factory_(this) {} |
+ net::NetworkDelegate* network_delegate, |
+ const base::Callback<void()>& destruction_callback) |
+ : net::URLRequestJob(request, network_delegate), |
+ delayed_(delayed), |
+ should_fail_(should_fail), |
+ started_(false), |
+ destruction_callback_(destruction_callback), |
+ weak_factory_(this) {} |
-DelayableCertReportURLRequestJob::~DelayableCertReportURLRequestJob() {} |
+DelayableCertReportURLRequestJob::~DelayableCertReportURLRequestJob() { |
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
+ destruction_callback_); |
+} |
base::WeakPtr<DelayableCertReportURLRequestJob> |
DelayableCertReportURLRequestJob::GetWeakPtr() { |
@@ -98,14 +210,17 @@ void DelayableCertReportURLRequestJob::GetResponseInfo( |
void DelayableCertReportURLRequestJob::Resume() { |
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
- DCHECK(delayed_); |
if (!started_) { |
- // If Start() hasn't been called yet, then unset |delayed_| so |
- // that when Start() is called, the request will begin |
- // immediately. |
+ // If Start() hasn't been called yet, then unset |delayed_| so that when |
+ // Start() is called, the request will begin immediately. |
delayed_ = false; |
return; |
} |
+ if (should_fail_) { |
+ NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
+ net::ERR_SSL_PROTOCOL_ERROR)); |
+ return; |
+ } |
// Start reading asynchronously as would a normal network request. |
base::ThreadTaskRunnerHandle::Get()->PostTask( |
FROM_HERE, |
@@ -136,18 +251,29 @@ net::URLRequestJob* CertReportJobInterceptor::MaybeInterceptRequest( |
expected_report_result_)); |
if (expected_report_result_ == REPORTS_FAIL) { |
- return new net::URLRequestFailedJob(request, network_delegate, |
- net::ERR_SSL_PROTOCOL_ERROR); |
+ return new DelayableCertReportURLRequestJob( |
+ false, true, request, network_delegate, |
+ base::Bind(&CertReportJobInterceptor::RequestDestructed, |
+ base::Unretained(this), uploaded_report, |
+ expected_report_result_)); |
+ |
} else if (expected_report_result_ == REPORTS_DELAY) { |
DCHECK(!delayed_request_) << "Supports only one delayed request at a time"; |
DelayableCertReportURLRequestJob* job = |
- new DelayableCertReportURLRequestJob(request, network_delegate); |
+ new DelayableCertReportURLRequestJob( |
+ true, false, request, network_delegate, |
+ base::Bind(&CertReportJobInterceptor::RequestDestructed, |
+ base::Unretained(this), uploaded_report, |
+ expected_report_result_)); |
delayed_request_ = job->GetWeakPtr(); |
return job; |
} |
// Successful url request job. |
- return new net::URLRequestMockDataJob(request, network_delegate, "some data", |
- 1, false); |
+ return new DelayableCertReportURLRequestJob( |
+ false, false, request, network_delegate, |
+ base::Bind(&CertReportJobInterceptor::RequestDestructed, |
+ base::Unretained(this), uploaded_report, |
+ expected_report_result_)); |
} |
void CertReportJobInterceptor::SetFailureMode( |
@@ -159,41 +285,22 @@ void CertReportJobInterceptor::SetFailureMode( |
weak_factory_.GetWeakPtr(), expected_report_result)); |
} |
-void CertReportJobInterceptor::Resume(const base::Callback<void()>& callback) { |
+void CertReportJobInterceptor::Resume() { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- content::BrowserThread::PostTaskAndReply( |
+ content::BrowserThread::PostTask( |
content::BrowserThread::IO, FROM_HERE, |
base::Bind(&CertReportJobInterceptor::ResumeOnIOThread, |
- base::Unretained(this)), |
- callback); |
-} |
- |
-const std::set<std::string>& CertReportJobInterceptor::successful_reports() |
- const { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- return successful_reports_; |
-} |
- |
-const std::set<std::string>& CertReportJobInterceptor::failed_reports() const { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- return failed_reports_; |
+ base::Unretained(this))); |
} |
-const std::set<std::string>& CertReportJobInterceptor::delayed_reports() const { |
+RequestObserver* CertReportJobInterceptor::request_created_observer() const { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- return delayed_reports_; |
+ return &request_created_observer_; |
} |
-void CertReportJobInterceptor::ClearObservedReports() { |
+RequestObserver* CertReportJobInterceptor::request_destroyed_observer() const { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- successful_reports_.clear(); |
- failed_reports_.clear(); |
- delayed_reports_.clear(); |
-} |
- |
-void CertReportJobInterceptor::WaitForReports(int num_reports) { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- wait_helper_.Wait(num_reports); |
+ return &request_destroyed_observer_; |
} |
void CertReportJobInterceptor::SetFailureModeOnIOThread( |
@@ -211,20 +318,15 @@ void CertReportJobInterceptor::ResumeOnIOThread() { |
void CertReportJobInterceptor::RequestCreated( |
const std::string& uploaded_report, |
- ReportSendingResult expected_report_result) { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- switch (expected_report_result) { |
- case REPORTS_SUCCESSFUL: |
- successful_reports_.insert(uploaded_report); |
- break; |
- case REPORTS_FAIL: |
- failed_reports_.insert(uploaded_report); |
- break; |
- case REPORTS_DELAY: |
- delayed_reports_.insert(uploaded_report); |
- break; |
- } |
- wait_helper_.OnEvent(); |
+ ReportSendingResult expected_report_result) const { |
+ request_created_observer_.OnRequest(uploaded_report, expected_report_result); |
+} |
+ |
+void CertReportJobInterceptor::RequestDestructed( |
+ const std::string& uploaded_report, |
+ ReportSendingResult expected_report_result) const { |
+ request_destroyed_observer_.OnRequest(uploaded_report, |
+ expected_report_result); |
} |
ReportExpectation::ReportExpectation() {} |
@@ -262,6 +364,29 @@ int ReportExpectation::num_reports() const { |
delayed_reports.size(); |
} |
+CertificateReportingServiceObserver::CertificateReportingServiceObserver() {} |
+ |
+CertificateReportingServiceObserver::~CertificateReportingServiceObserver() {} |
+ |
+void CertificateReportingServiceObserver::Clear() { |
+ did_reset_ = false; |
+} |
+ |
+void CertificateReportingServiceObserver::WaitForReset() { |
+ DCHECK(!run_loop_); |
+ if (did_reset_) |
+ return; |
+ run_loop_.reset(new base::RunLoop()); |
+ run_loop_->Run(); |
+ run_loop_.reset(); |
+} |
+ |
+void CertificateReportingServiceObserver::OnServiceReset() { |
+ did_reset_ = true; |
+ if (run_loop_) |
+ run_loop_->Quit(); |
+} |
+ |
CertificateReportingServiceTestHelper::CertificateReportingServiceTestHelper() { |
memset(server_private_key_, 1, sizeof(server_private_key_)); |
crypto::curve25519::ScalarBaseMult(server_private_key_, server_public_key_); |
@@ -281,17 +406,15 @@ void CertificateReportingServiceTestHelper::SetUpInterceptor() { |
url_request_interceptor_)))); |
} |
-// Changes the behavior of report uploads to fail or succeed. |
estark
2017/01/05 16:42:29
Did you mean to delete this?
meacer
2017/01/05 20:15:46
Yes, this is already documented in the header.
|
void CertificateReportingServiceTestHelper::SetFailureMode( |
ReportSendingResult expected_report_result) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
url_request_interceptor_->SetFailureMode(expected_report_result); |
} |
-void CertificateReportingServiceTestHelper::ResumeDelayedRequest( |
- const base::Callback<void()>& callback) { |
+void CertificateReportingServiceTestHelper::ResumeDelayedRequest() { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- url_request_interceptor_->Resume(callback); |
+ url_request_interceptor_->Resume(); |
} |
uint8_t* CertificateReportingServiceTestHelper::server_public_key() { |
@@ -303,41 +426,36 @@ uint32_t CertificateReportingServiceTestHelper::server_public_key_version() |
return kServerPublicKeyTestVersion; |
} |
-ReportWaitHelper::ReportWaitHelper() |
- : num_events_to_wait_for_(0), num_received_events_(0) {} |
-ReportWaitHelper::~ReportWaitHelper() {} |
- |
-void ReportWaitHelper::Wait(int num_events_to_wait_for) { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- DCHECK(!run_loop_); |
- ASSERT_LE(num_received_events_, num_events_to_wait_for) |
- << "Observed unexpected report"; |
+void CertificateReportingServiceTestHelper::WaitForRequestsCreated( |
+ const ReportExpectation& expectation) { |
+ WaitReports(interceptor()->request_created_observer(), expectation); |
+} |
- if (num_received_events_ < num_events_to_wait_for) { |
- num_events_to_wait_for_ = num_events_to_wait_for; |
- run_loop_.reset(new base::RunLoop()); |
- run_loop_->Run(); |
- run_loop_.reset(nullptr); |
- EXPECT_EQ(0, num_received_events_); |
- EXPECT_EQ(0, num_events_to_wait_for_); |
- } else if (num_received_events_ == num_events_to_wait_for) { |
- num_received_events_ = 0; |
- num_events_to_wait_for_ = 0; |
- } |
+void CertificateReportingServiceTestHelper::WaitForRequestsDestroyed( |
+ const ReportExpectation& expectation) { |
+ WaitReports(interceptor()->request_destroyed_observer(), expectation); |
} |
-void ReportWaitHelper::OnEvent() { |
+// Checks that there are no remaining successful and failed reports observed |
+// by the interceptor. |
+void CertificateReportingServiceTestHelper::ExpectNoRequests( |
+ CertificateReportingService* service) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- num_received_events_++; |
- if (!run_loop_) { |
- return; |
- } |
- ASSERT_LE(num_received_events_, num_events_to_wait_for_) |
- << "Observed unexpected report"; |
- if (num_received_events_ == num_events_to_wait_for_) { |
- num_events_to_wait_for_ = 0; |
- num_received_events_ = 0; |
- run_loop_->Quit(); |
+ // Check that all requests have been destroyed. |
+ EXPECT_TRUE(interceptor() |
+ ->request_destroyed_observer() |
+ ->successful_reports() |
+ .empty()); |
+ EXPECT_TRUE( |
+ interceptor()->request_destroyed_observer()->failed_reports().empty()); |
+ EXPECT_TRUE( |
+ interceptor()->request_destroyed_observer()->delayed_reports().empty()); |
+ |
+ if (service->GetReporterForTesting()) { |
+ // Reporter can be null if reporting is disabled. |
+ EXPECT_EQ( |
+ 0u, |
+ service->GetReporterForTesting()->inflight_report_count_for_testing()); |
} |
} |