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

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

Issue 2503243003: Wire up CertificateReportingService to handle report uploads (Closed)
Patch Set: Rebase Created 4 years 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_unittest.cc
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
index 07de07b85dbeaa828a7b46a72acd5a6258657e33..8ef06293dfdb0372268a7cf9763e1cc964ee36f4 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
@@ -10,11 +10,15 @@
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/test/thread_test_helper.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
+#include "chrome/browser/safe_browsing/test_safe_browsing_service.h"
+#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -25,16 +29,66 @@
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+using certificate_reporting_test_utils::CertificateReportingServiceTestHelper;
+using certificate_reporting_test_utils::ReportExpectation;
+
namespace {
// Maximum number of reports kept in the certificate reporting service's retry
// queue.
const size_t kMaxReportCountInQueue = 3;
+const char* kFailedReportHistogram = "SSL.CertificateErrorReportFailure";
+
void ClearURLHandlers() {
net::URLRequestFilter::GetInstance()->ClearHandlers();
}
+// A network delegate used to observe URL request destructions. The tests check
+// that no outstanding URL request is present during tear down.
+class TestNetworkDelegate : public net::NetworkDelegateImpl {
+ public:
+ TestNetworkDelegate(
+ const base::Callback<void()>& url_request_destroyed_callback)
+ : url_request_destroyed_callback_(url_request_destroyed_callback) {}
+
+ ~TestNetworkDelegate() override {}
+
+ // net::NetworkDelegate method:
+ void OnURLRequestDestroyed(net::URLRequest* request) override {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ url_request_destroyed_callback_);
+ }
+
+ private:
+ base::Callback<void()> url_request_destroyed_callback_;
+};
+
+// Base class for histogram testing. The failed report histogram is checked once
+// after teardown to ensure all in flight requests have completed.
+class ReportHistogramTestHelper {
+ public:
+ // Sets the expected histogram value to be checked during teardown.
+ void SetExpectedFailedReportCount(unsigned int num_expected_failed_report) {
+ num_expected_failed_report_ = num_expected_failed_report;
+ }
+
+ void CheckHistogram() {
+ if (num_expected_failed_report_ != 0) {
+ histogram_tester_.ExpectUniqueSample(kFailedReportHistogram,
+ -net::ERR_SSL_PROTOCOL_ERROR,
+ num_expected_failed_report_);
+ } else {
+ histogram_tester_.ExpectTotalCount(kFailedReportHistogram, 0);
+ }
+ }
+
+ private:
+ unsigned int num_expected_failed_report_ = 0;
+ base::HistogramTester histogram_tester_;
+};
+
} // namespace
TEST(CertificateReportingServiceReportListTest, BoundedReportList) {
@@ -89,22 +143,34 @@ class CertificateReportingServiceReporterOnIOThreadTest
net::URLRequestMockDataJob::AddUrlHandler();
}
- void TearDown() override { ClearURLHandlers(); }
+ void TearDown() override {
+ ClearURLHandlers();
+ // Check the histogram as the last thing. This makes sure no in-flight
+ // report is missed.
+ histogram_test_helper_.CheckHistogram();
+ }
protected:
net::URLRequestContextGetter* url_request_context_getter() {
return url_request_context_getter_.get();
}
+ void SetExpectedFailedReportCountOnTearDown(unsigned int count) {
+ histogram_test_helper_.SetExpectedFailedReportCount(count);
+ }
+
private:
std::unique_ptr<base::MessageLoopForIO> message_loop_;
std::unique_ptr<content::TestBrowserThread> io_thread_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
+ ReportHistogramTestHelper histogram_test_helper_;
};
TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
Reporter_RetriesEnabled) {
+ SetExpectedFailedReportCountOnTearDown(6);
+
std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
base::Time reference_time = base::Time::Now();
clock->SetNow(reference_time);
@@ -202,6 +268,8 @@ TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
// Same as above, but retries are disabled.
TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
Reporter_RetriesDisabled) {
+ SetExpectedFailedReportCountOnTearDown(2);
+
std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
base::Time reference_time = base::Time::Now();
clock->SetNow(reference_time);
@@ -247,21 +315,17 @@ TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
ASSERT_EQ(0u, list->items().size());
}
-class CertificateReportingServiceTest
- : public ::testing::Test,
- public certificate_reporting_test_utils::
- CertificateReportingServiceTestBase {
+class CertificateReportingServiceTest : public ::testing::Test {
public:
CertificateReportingServiceTest()
- : CertificateReportingServiceTestBase(),
- thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
+ : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
io_task_runner_(content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::IO)) {}
~CertificateReportingServiceTest() override {}
void SetUp() override {
- SetUpInterceptor();
+ test_helper_.SetUpInterceptor();
WaitForIOThread();
content::BrowserThread::PostTask(
@@ -271,43 +335,55 @@ class CertificateReportingServiceTest
base::Unretained(this)));
WaitForIOThread();
- clock_ = new base::SimpleTestClock();
+ safe_browsing::SafeBrowsingService::RegisterFactory(&sb_service_factory);
+ sb_service_ = sb_service_factory.CreateSafeBrowsingService();
+
+ clock_.reset(new base::SimpleTestClock());
service_.reset(new CertificateReportingService(
- url_request_context_getter(), server_public_key(),
- server_public_key_version(), kMaxReportCountInQueue,
- base::TimeDelta::FromHours(24), std::unique_ptr<base::Clock>(clock_)));
+ sb_service_.get(), url_request_context_getter(), &profile_,
+ test_helper_.server_public_key(),
+ test_helper_.server_public_key_version(), kMaxReportCountInQueue,
+ base::TimeDelta::FromHours(24), clock_.get()));
// Wait for service reset.
WaitForIOThread();
}
- void SetUpURLRequestContextOnIOThread() {
- std::unique_ptr<net::TestURLRequestContext> url_request_context(
- new net::TestURLRequestContext(true));
- url_request_context->set_network_delegate(network_delegate());
- url_request_context->Init();
- url_request_context_getter_ = new net::TestURLRequestContextGetter(
- io_task_runner_, std::move(url_request_context));
- }
-
void TearDown() override {
WaitForIOThread();
- EXPECT_TRUE(interceptor()->successful_reports().empty());
- EXPECT_TRUE(interceptor()->failed_reports().empty());
- EXPECT_TRUE(interceptor()->delayed_reports().empty());
+ EXPECT_TRUE(test_helper_.interceptor()->successful_reports().empty());
+ EXPECT_TRUE(test_helper_.interceptor()->failed_reports().empty());
+ EXPECT_TRUE(test_helper_.interceptor()->delayed_reports().empty());
EXPECT_EQ(0u, service()
->GetReporterForTesting()
->inflight_report_count_for_testing());
service_->Shutdown();
WaitForIOThread();
-
service_.reset(nullptr);
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&CertificateReportingServiceTest::TearDownOnIOThread,
+ base::Unretained(this)));
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
base::Bind(&ClearURLHandlers));
- TearDownInterceptor();
+ WaitForIOThread();
+
+ histogram_test_helper_.CheckHistogram();
}
protected:
+ void WaitForRequestsDestroyed(const ReportExpectation& expectation) {
+ wait_helper_.Wait(expectation.num_reports());
+ EXPECT_EQ(expectation.successful_reports,
+ test_helper_.interceptor()->successful_reports());
+ EXPECT_EQ(expectation.failed_reports,
+ test_helper_.interceptor()->failed_reports());
+ EXPECT_EQ(expectation.delayed_reports,
+ test_helper_.interceptor()->delayed_reports());
+ test_helper_.interceptor()->ClearObservedReports();
+ }
+
net::URLRequestContextGetter* url_request_context_getter() {
return url_request_context_getter_.get();
}
@@ -318,6 +394,8 @@ class CertificateReportingServiceTest
ASSERT_TRUE(io_helper->Run());
}
+ CertificateReportingService* service() { return service_.get(); }
+
// Sets service enabled state and waits for a reset event.
void SetServiceEnabledAndWait(bool enabled) {
service()->SetEnabled(enabled);
@@ -327,33 +405,72 @@ class CertificateReportingServiceTest
void AdvanceClock(base::TimeDelta delta) {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
- base::Bind(&base::SimpleTestClock::Advance, base::Unretained(clock_),
- delta));
+ base::Bind(&base::SimpleTestClock::Advance,
+ base::Unretained(clock_.get()), delta));
}
void SetNow(base::Time now) {
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&base::SimpleTestClock::SetNow,
- base::Unretained(clock_), now));
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&base::SimpleTestClock::SetNow,
+ base::Unretained(clock_.get()), now));
}
- CertificateReportingService* service() { return service_.get(); }
+ void SetExpectedFailedReportCountOnTearDown(unsigned int count) {
+ histogram_test_helper_.SetExpectedFailedReportCount(count);
+ }
+
+ CertificateReportingServiceTestHelper* test_helper() { return &test_helper_; }
private:
+ void SetUpURLRequestContextOnIOThread() {
+ network_delegate_.reset(new TestNetworkDelegate(
+ base::Bind(&CertificateReportingServiceTest::OnURLRequestDestroyed,
+ base::Unretained(this))));
+
+ std::unique_ptr<net::TestURLRequestContext> url_request_context(
+ new net::TestURLRequestContext(true));
+ url_request_context->set_network_delegate(network_delegate_.get());
+ url_request_context->Init();
+ url_request_context_getter_ = new net::TestURLRequestContextGetter(
+ io_task_runner_, std::move(url_request_context));
+ }
+
+ void TearDownOnIOThread() {
+ url_request_context_getter_ = nullptr;
+ network_delegate_.reset(nullptr);
+ }
+
+ void OnURLRequestDestroyed() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ wait_helper_.OnEvent();
+ }
+
// Must be initialized before url_request_context_getter_
content::TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<TestNetworkDelegate> network_delegate_;
+ certificate_reporting_test_utils::ReportWaitHelper wait_helper_;
+
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
std::unique_ptr<CertificateReportingService> service_;
- base::SimpleTestClock* clock_;
+ std::unique_ptr<base::SimpleTestClock> clock_;
+
+ scoped_refptr<safe_browsing::SafeBrowsingService> sb_service_;
+ safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory;
+ TestingProfile profile_;
+
+ CertificateReportingServiceTestHelper test_helper_;
+ ReportHistogramTestHelper histogram_test_helper_;
};
TEST_F(CertificateReportingServiceTest, Send) {
- WaitForIOThread();
+ SetExpectedFailedReportCountOnTearDown(4);
+
// Let all reports fail.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
// Send two reports. Both should fail and get queued.
@@ -369,8 +486,8 @@ TEST_F(CertificateReportingServiceTest, Send) {
WaitForRequestsDestroyed(ReportExpectation::Failed({"report0", "report1"}));
// Let all reports succeed.
- SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
- REPORTS_SUCCESSFUL);
+ test_helper()->SetFailureMode(certificate_reporting_test_utils::
+ ReportSendingResult::REPORTS_SUCCESSFUL);
// Send a third report. This should not be queued.
service()->Send("report2");
@@ -384,9 +501,11 @@ TEST_F(CertificateReportingServiceTest, Send) {
}
TEST_F(CertificateReportingServiceTest, Disabled_ShouldNotSend) {
+ SetExpectedFailedReportCountOnTearDown(0);
+
// Let all reports succeed.
- SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
- REPORTS_SUCCESSFUL);
+ test_helper()->SetFailureMode(certificate_reporting_test_utils::
+ ReportSendingResult::REPORTS_SUCCESSFUL);
// Disable the service.
SetServiceEnabledAndWait(false);
@@ -395,7 +514,7 @@ TEST_F(CertificateReportingServiceTest, Disabled_ShouldNotSend) {
// should be observed.
service()->Send("report0");
- // Enable the service and send a report again.
+ // Enable the service and send a report again. It should be sent successfully.
SetServiceEnabledAndWait(true);
service()->Send("report1");
@@ -403,8 +522,10 @@ TEST_F(CertificateReportingServiceTest, Disabled_ShouldNotSend) {
}
TEST_F(CertificateReportingServiceTest, Disabled_ShouldClearPendingReports) {
+ SetExpectedFailedReportCountOnTearDown(1);
+
// Let all reports fail.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
service()->Send("report0");
@@ -413,7 +534,7 @@ TEST_F(CertificateReportingServiceTest, Disabled_ShouldClearPendingReports) {
// Disable the service.
SetServiceEnabledAndWait(false);
- // Sending has no effect while disabled, wait for a single cancelled event.
+ // Sending has no effect while disabled.
service()->SendPending();
// Re-enable the service and send pending reports. Pending reports should have
@@ -425,9 +546,11 @@ TEST_F(CertificateReportingServiceTest, Disabled_ShouldClearPendingReports) {
}
TEST_F(CertificateReportingServiceTest, DontSendOldReports) {
+ SetExpectedFailedReportCountOnTearDown(5);
+
SetNow(base::Time::Now());
// Let all reports fail.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
// Send a report.
@@ -469,9 +592,11 @@ TEST_F(CertificateReportingServiceTest, DontSendOldReports) {
}
TEST_F(CertificateReportingServiceTest, DiscardOldReports) {
+ SetExpectedFailedReportCountOnTearDown(7);
+
SetNow(base::Time::Now());
// Let all reports fail.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
// Send a failed report.
@@ -502,8 +627,8 @@ TEST_F(CertificateReportingServiceTest, DiscardOldReports) {
ReportExpectation::Failed({"report1", "report2", "report3"}));
// Let all reports succeed.
- SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
- REPORTS_SUCCESSFUL);
+ test_helper()->SetFailureMode(certificate_reporting_test_utils::
+ ReportSendingResult::REPORTS_SUCCESSFUL);
// Advance the clock by 15 hours. Current time is now 30 hours after reference
// time. The ages of reports are now as follows:
@@ -523,8 +648,10 @@ TEST_F(CertificateReportingServiceTest, DiscardOldReports) {
// A delayed report should successfully upload when it's resumed.
TEST_F(CertificateReportingServiceTest, Delayed_Resumed) {
+ SetExpectedFailedReportCountOnTearDown(0);
+
// Let reports hang.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_DELAY);
// Send a report. The report upload hangs, so no error or success callbacks
// should be called.
@@ -532,14 +659,16 @@ TEST_F(CertificateReportingServiceTest, Delayed_Resumed) {
// Resume the report upload and run the callbacks. The report should be
// successfully sent.
- ResumeDelayedRequest();
+ test_helper()->ResumeDelayedRequest(base::Bind(&base::DoNothing));
WaitForRequestsDestroyed(ReportExpectation::Delayed({"report0"}));
}
// Delayed reports should cleaned when the service is reset.
TEST_F(CertificateReportingServiceTest, Delayed_Reset) {
+ SetExpectedFailedReportCountOnTearDown(0);
+
// Let reports hang.
- SetFailureMode(
+ test_helper()->SetFailureMode(
certificate_reporting_test_utils::ReportSendingResult::REPORTS_DELAY);
// Send a report. The report is triggered but hangs, so no error or success
// callbacks should be called.
@@ -552,7 +681,7 @@ TEST_F(CertificateReportingServiceTest, Delayed_Reset) {
// Resume delayed report. No report should be observed since the service
// should have reset and all pending reports should be cleared. If any report
// is observed, the next WaitForRequestsDestroyed() will fail.
- ResumeDelayedRequest();
+ test_helper()->ResumeDelayedRequest(base::Bind(&base::DoNothing));
// Enable the service.
SetServiceEnabledAndWait(true);
@@ -562,7 +691,7 @@ TEST_F(CertificateReportingServiceTest, Delayed_Reset) {
// report queue has been cleared above.
service()->Send("report1");
- // Resume delayed report. The report should be observed.
- ResumeDelayedRequest();
+ // Resume delayed report. Two reports are successfully sent.
+ test_helper()->ResumeDelayedRequest(base::Bind(&base::DoNothing));
WaitForRequestsDestroyed(ReportExpectation::Delayed({"report0", "report1"}));
}
« no previous file with comments | « chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc ('k') | chrome/browser/safe_browsing/ping_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698