Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2825)

Unified Diff: chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc

Issue 2605403002: Fix flaky CertificateReportingService browser tests. (Closed)
Patch Set: Fix broken tests Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());
}
}

Powered by Google App Engine
This is Rietveld 408576698