| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/ssl/certificate_reporting_service.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/run_loop.h" |
| 10 #include "base/test/simple_test_clock.h" |
| 11 #include "base/time/clock.h" |
| 12 #include "base/time/time.h" |
| 13 #include "content/public/test/test_browser_thread.h" |
| 14 #include "net/base/network_delegate_impl.h" |
| 15 #include "net/test/url_request/url_request_failed_job.h" |
| 16 #include "net/test/url_request/url_request_mock_data_job.h" |
| 17 #include "net/url_request/url_request_test_util.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 TEST(CertificateReportingServiceTest, BoundedReportList) { |
| 21 // Create a report list with maximum of 2 items. |
| 22 CertificateReportingService::BoundedReportList list(2 /* max_size */); |
| 23 EXPECT_EQ(0u, list.items().size()); |
| 24 |
| 25 // Add a ten minute old report. |
| 26 list.Add(CertificateReportingService::Report( |
| 27 1, base::Time::Now() - base::TimeDelta::FromMinutes(10), |
| 28 std::string("report1_ten_minutes_old"))); |
| 29 EXPECT_EQ(1u, list.items().size()); |
| 30 EXPECT_EQ("report1_ten_minutes_old", list.items()[0].serialized_report); |
| 31 |
| 32 // Add another report. Items are ordered from newest to oldest report by |
| 33 // creation time. Oldest is at the end. |
| 34 list.Add(CertificateReportingService::Report( |
| 35 2, base::Time::Now() - base::TimeDelta::FromMinutes(5), |
| 36 std::string("report2_five_minutes_old"))); |
| 37 EXPECT_EQ(2u, list.items().size()); |
| 38 EXPECT_EQ("report2_five_minutes_old", list.items()[0].serialized_report); |
| 39 EXPECT_EQ("report1_ten_minutes_old", list.items()[1].serialized_report); |
| 40 |
| 41 // Adding a third report removes the oldest report (report1) from the list. |
| 42 list.Add(CertificateReportingService::Report( |
| 43 3, base::Time::Now(), std::string("report3_zero_minutes_old"))); |
| 44 EXPECT_EQ(2u, list.items().size()); |
| 45 EXPECT_EQ("report3_zero_minutes_old", list.items()[0].serialized_report); |
| 46 EXPECT_EQ("report2_five_minutes_old", list.items()[1].serialized_report); |
| 47 |
| 48 // Adding a report older than the oldest report in the list (report2) is |
| 49 // a no-op. |
| 50 list.Add(CertificateReportingService::Report( |
| 51 0, base::Time::Now() - base::TimeDelta::FromMinutes( |
| 52 10) /* 5 minutes older than report2 */, |
| 53 std::string("report0_ten_minutes_old"))); |
| 54 EXPECT_EQ(2u, list.items().size()); |
| 55 EXPECT_EQ("report3_zero_minutes_old", list.items()[0].serialized_report); |
| 56 EXPECT_EQ("report2_five_minutes_old", list.items()[1].serialized_report); |
| 57 } |
| 58 |
| 59 class TestReportSenderNetworkDelegate : public net::NetworkDelegateImpl { |
| 60 public: |
| 61 TestReportSenderNetworkDelegate() {} |
| 62 }; |
| 63 |
| 64 class CertificateReportingServiceReporterTest : public ::testing::Test { |
| 65 public: |
| 66 CertificateReportingServiceReporterTest() : context_(true) { |
| 67 context_.set_network_delegate(&network_delegate_); |
| 68 context_.Init(); |
| 69 } |
| 70 |
| 71 void SetUp() override { |
| 72 message_loop_.reset(new base::MessageLoopForIO()); |
| 73 io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO, |
| 74 message_loop_.get())); |
| 75 net::URLRequestFailedJob::AddUrlHandler(); |
| 76 net::URLRequestMockDataJob::AddUrlHandler(); |
| 77 } |
| 78 |
| 79 protected: |
| 80 net::URLRequestContext* url_request_context() { return &context_; } |
| 81 |
| 82 private: |
| 83 TestReportSenderNetworkDelegate network_delegate_; |
| 84 |
| 85 std::unique_ptr<base::MessageLoopForIO> message_loop_; |
| 86 std::unique_ptr<content::TestBrowserThread> io_thread_; |
| 87 |
| 88 net::TestURLRequestContext context_; |
| 89 }; |
| 90 |
| 91 TEST_F(CertificateReportingServiceReporterTest, Reporter) { |
| 92 std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock()); |
| 93 base::Time reference_time = base::Time::Now(); |
| 94 clock->SetNow(reference_time); |
| 95 |
| 96 const GURL kFailureURL = |
| 97 net::URLRequestFailedJob::GetMockHttpsUrl(net::ERR_SSL_PROTOCOL_ERROR); |
| 98 certificate_reporting::ErrorReporter* certificate_error_reporter = |
| 99 new certificate_reporting::ErrorReporter( |
| 100 url_request_context(), kFailureURL, |
| 101 net::ReportSender::DO_NOT_SEND_COOKIES); |
| 102 |
| 103 CertificateReportingService::BoundedReportList* list = |
| 104 new CertificateReportingService::BoundedReportList(2); |
| 105 |
| 106 scoped_refptr<CertificateReportingService::Reporter> reporter = |
| 107 new CertificateReportingService::Reporter( |
| 108 std::unique_ptr<certificate_reporting::ErrorReporter>( |
| 109 certificate_error_reporter), |
| 110 std::unique_ptr<CertificateReportingService::BoundedReportList>(list), |
| 111 clock.get(), base::TimeDelta::FromSeconds(100), nullptr); |
| 112 EXPECT_EQ(0u, list->items().size()); |
| 113 EXPECT_EQ(0u, reporter->inflight_report_count_for_testing()); |
| 114 |
| 115 // Sending a failed report will put the report in the retry list. |
| 116 reporter->Send("report1"); |
| 117 EXPECT_EQ(1u, reporter->inflight_report_count_for_testing()); |
| 118 base::RunLoop().RunUntilIdle(); |
| 119 |
| 120 EXPECT_EQ(0u, reporter->inflight_report_count_for_testing()); |
| 121 ASSERT_EQ(1u, list->items().size()); |
| 122 EXPECT_EQ("report1", list->items()[0].serialized_report); |
| 123 EXPECT_EQ(reference_time, list->items()[0].creation_time); |
| 124 |
| 125 // Sending a second failed report will also put it in the retry list. |
| 126 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 127 reporter->Send("report2"); |
| 128 base::RunLoop().RunUntilIdle(); |
| 129 ASSERT_EQ(2u, list->items().size()); |
| 130 EXPECT_EQ("report2", list->items()[0].serialized_report); |
| 131 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 132 list->items()[0].creation_time); |
| 133 EXPECT_EQ("report1", list->items()[1].serialized_report); |
| 134 EXPECT_EQ(reference_time, list->items()[1].creation_time); |
| 135 |
| 136 // Sending a third report should remove the first report from the retry list. |
| 137 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 138 reporter->Send("report3"); |
| 139 base::RunLoop().RunUntilIdle(); |
| 140 ASSERT_EQ(2u, list->items().size()); |
| 141 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 142 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 143 list->items()[0].creation_time); |
| 144 EXPECT_EQ("report2", list->items()[1].serialized_report); |
| 145 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 146 list->items()[1].creation_time); |
| 147 |
| 148 // Retry sending all pending reports. All should fail and get added to the |
| 149 // retry list again. Report creation time doesn't change for retried reports. |
| 150 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 151 reporter->SendPending(); |
| 152 base::RunLoop().RunUntilIdle(); |
| 153 ASSERT_EQ(2u, list->items().size()); |
| 154 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 155 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 156 list->items()[0].creation_time); |
| 157 EXPECT_EQ("report2", list->items()[1].serialized_report); |
| 158 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 159 list->items()[1].creation_time); |
| 160 |
| 161 // Advance the clock to 115 seconds. This makes report3 95 seconds old, and |
| 162 // report2 105 seconds old. report2 should be dropped because it's older than |
| 163 // max age (100 seconds). |
| 164 clock->SetNow(reference_time + base::TimeDelta::FromSeconds(115)); |
| 165 reporter->SendPending(); |
| 166 EXPECT_EQ(1u, reporter->inflight_report_count_for_testing()); |
| 167 base::RunLoop().RunUntilIdle(); |
| 168 ASSERT_EQ(1u, list->items().size()); |
| 169 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 170 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 171 list->items()[0].creation_time); |
| 172 |
| 173 // Retry again, this time successfully. There should be no pending reports |
| 174 // left. |
| 175 const GURL kSuccessURL = |
| 176 net::URLRequestMockDataJob::GetMockHttpsUrl("dummy data", 1); |
| 177 certificate_error_reporter->set_upload_url_for_testing(kSuccessURL); |
| 178 clock->Advance(base::TimeDelta::FromSeconds(1)); |
| 179 reporter->SendPending(); |
| 180 EXPECT_EQ(1u, reporter->inflight_report_count_for_testing()); |
| 181 base::RunLoop().RunUntilIdle(); |
| 182 EXPECT_EQ(0u, list->items().size()); |
| 183 } |
| OLD | NEW |