| 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/safe_browsing/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 CertificateReportingServiceReporterTest : public ::testing::Test { |
| 60 public: |
| 61 void SetUp() override { |
| 62 message_loop_.reset(new base::MessageLoopForIO()); |
| 63 io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO, |
| 64 message_loop_.get())); |
| 65 url_request_context_getter_ = |
| 66 new net::TestURLRequestContextGetter(message_loop_->task_runner()); |
| 67 net::URLRequestFailedJob::AddUrlHandler(); |
| 68 net::URLRequestMockDataJob::AddUrlHandler(); |
| 69 } |
| 70 |
| 71 protected: |
| 72 net::URLRequestContextGetter* url_request_context_getter() { |
| 73 return url_request_context_getter_.get(); |
| 74 } |
| 75 |
| 76 private: |
| 77 std::unique_ptr<base::MessageLoopForIO> message_loop_; |
| 78 std::unique_ptr<content::TestBrowserThread> io_thread_; |
| 79 |
| 80 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; |
| 81 }; |
| 82 |
| 83 TEST_F(CertificateReportingServiceReporterTest, Reporter) { |
| 84 std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock()); |
| 85 base::Time reference_time = base::Time::Now(); |
| 86 clock->SetNow(reference_time); |
| 87 |
| 88 const GURL kFailureURL = |
| 89 net::URLRequestFailedJob::GetMockHttpsUrl(net::ERR_SSL_PROTOCOL_ERROR); |
| 90 certificate_reporting::ErrorReporter* certificate_error_reporter = |
| 91 new certificate_reporting::ErrorReporter( |
| 92 url_request_context_getter()->GetURLRequestContext(), kFailureURL, |
| 93 net::ReportSender::DO_NOT_SEND_COOKIES); |
| 94 |
| 95 CertificateReportingService::BoundedReportList* list = |
| 96 new CertificateReportingService::BoundedReportList(2); |
| 97 |
| 98 CertificateReportingService::Reporter reporter( |
| 99 std::unique_ptr<certificate_reporting::ErrorReporter>( |
| 100 certificate_error_reporter), |
| 101 std::unique_ptr<CertificateReportingService::BoundedReportList>(list), |
| 102 clock.get(), base::TimeDelta::FromSeconds(100)); |
| 103 EXPECT_EQ(0u, list->items().size()); |
| 104 EXPECT_EQ(0u, reporter.inflight_report_count_for_testing()); |
| 105 |
| 106 // Sending a failed report will put the report in the retry list. |
| 107 reporter.Send("report1"); |
| 108 EXPECT_EQ(1u, reporter.inflight_report_count_for_testing()); |
| 109 base::RunLoop().RunUntilIdle(); |
| 110 |
| 111 EXPECT_EQ(0u, reporter.inflight_report_count_for_testing()); |
| 112 ASSERT_EQ(1u, list->items().size()); |
| 113 EXPECT_EQ("report1", list->items()[0].serialized_report); |
| 114 EXPECT_EQ(reference_time, list->items()[0].creation_time); |
| 115 |
| 116 // Sending a second failed report will also put it in the retry list. |
| 117 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 118 reporter.Send("report2"); |
| 119 base::RunLoop().RunUntilIdle(); |
| 120 ASSERT_EQ(2u, list->items().size()); |
| 121 EXPECT_EQ("report2", list->items()[0].serialized_report); |
| 122 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 123 list->items()[0].creation_time); |
| 124 EXPECT_EQ("report1", list->items()[1].serialized_report); |
| 125 EXPECT_EQ(reference_time, list->items()[1].creation_time); |
| 126 |
| 127 // Sending a third report should remove the first report from the retry list. |
| 128 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 129 reporter.Send("report3"); |
| 130 base::RunLoop().RunUntilIdle(); |
| 131 ASSERT_EQ(2u, list->items().size()); |
| 132 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 133 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 134 list->items()[0].creation_time); |
| 135 EXPECT_EQ("report2", list->items()[1].serialized_report); |
| 136 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 137 list->items()[1].creation_time); |
| 138 |
| 139 // Retry sending all pending reports. All should fail and get added to the |
| 140 // retry list again. Report creation time doesn't change for retried reports. |
| 141 clock->Advance(base::TimeDelta::FromSeconds(10)); |
| 142 reporter.SendPending(); |
| 143 base::RunLoop().RunUntilIdle(); |
| 144 ASSERT_EQ(2u, list->items().size()); |
| 145 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 146 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 147 list->items()[0].creation_time); |
| 148 EXPECT_EQ("report2", list->items()[1].serialized_report); |
| 149 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(10), |
| 150 list->items()[1].creation_time); |
| 151 |
| 152 // Advance the clock to 115 seconds. This makes report3 95 seconds old, and |
| 153 // report2 105 seconds old. report2 should be dropped because it's older than |
| 154 // max age (100 seconds). |
| 155 clock->SetNow(reference_time + base::TimeDelta::FromSeconds(115)); |
| 156 reporter.SendPending(); |
| 157 EXPECT_EQ(1u, reporter.inflight_report_count_for_testing()); |
| 158 base::RunLoop().RunUntilIdle(); |
| 159 ASSERT_EQ(1u, list->items().size()); |
| 160 EXPECT_EQ("report3", list->items()[0].serialized_report); |
| 161 EXPECT_EQ(reference_time + base::TimeDelta::FromSeconds(20), |
| 162 list->items()[0].creation_time); |
| 163 |
| 164 // Retry again, this time successfully. There should be no pending reports |
| 165 // left. |
| 166 const GURL kSuccessURL = |
| 167 net::URLRequestMockDataJob::GetMockHttpsUrl("dummy data", 1); |
| 168 certificate_error_reporter->set_upload_url_for_testing(kSuccessURL); |
| 169 clock->Advance(base::TimeDelta::FromSeconds(1)); |
| 170 reporter.SendPending(); |
| 171 EXPECT_EQ(1u, reporter.inflight_report_count_for_testing()); |
| 172 base::RunLoop().RunUntilIdle(); |
| 173 EXPECT_EQ(0u, list->items().size()); |
| 174 } |
| OLD | NEW |