1 // Copyright 2014 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 "components/domain_reliability/context.h" 6 7 #include <map> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/message_loop/message_loop_proxy.h" 13 #include "components/domain_reliability/beacon.h" 14 #include "components/domain_reliability/dispatcher.h" 15 #include "components/domain_reliability/scheduler.h" 16 #include "components/domain_reliability/test_util.h" 17 #include "net/base/net_errors.h" 18 #include "net/url_request/url_request_test_util.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace domain_reliability { 22 namespace { 23 24 typedef std::vector<DomainReliabilityBeacon> BeaconVector; 25 26 DomainReliabilityBeacon MakeBeacon(MockableTime* time) { 27 DomainReliabilityBeacon beacon; 28 beacon.domain = "localhost"; 29 beacon.status = "ok"; 30 beacon.chrome_error = net::OK; 31 beacon.server_ip = "127.0.0.1"; 32 beacon.protocol = "HTTP"; 33 beacon.http_response_code = 200; 34 beacon.elapsed = base::TimeDelta::FromMilliseconds(250); 35 beacon.start_time = time->NowTicks() - beacon.elapsed; 36 return beacon; 37 } 38 39 class DomainReliabilityContextTest : public testing::Test { 40 protected: 41 DomainReliabilityContextTest() 42 : dispatcher_(&time_), 43 params_(MakeTestSchedulerParams()), 44 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest, 45 base::Unretained(this))), 46 upload_reporter_string_("test-reporter"), 47 context_(&time_, 48 params_, 49 upload_reporter_string_, 50 &dispatcher_, 51 &uploader_, 52 MakeTestConfig().Pass()), 53 upload_pending_(false) {} 54 55 TimeDelta min_delay() const { return params_.minimum_upload_delay; } 56 TimeDelta max_delay() const { return params_.maximum_upload_delay; } 57 TimeDelta retry_interval() const { return params_.upload_retry_interval; } 58 TimeDelta zero_delta() const { return TimeDelta::FromMicroseconds(0); } 59 60 bool upload_pending() { return upload_pending_; } 61 62 const std::string& upload_report() { 63 DCHECK(upload_pending_); 64 return upload_report_; 65 } 66 67 const GURL& upload_url() { 68 DCHECK(upload_pending_); 69 return upload_url_; 70 } 71 72 void CallUploadCallback(bool success) { 73 DCHECK(upload_pending_); 74 upload_callback_.Run(success); 75 upload_pending_ = false; 76 } 77 78 bool CheckNoBeacons() { 79 BeaconVector beacons; 80 context_.GetQueuedBeaconsForTesting(&beacons); 81 return beacons.empty(); 82 } 83 84 bool CheckCounts(size_t index, 85 unsigned expected_successful, 86 unsigned expected_failed) { 87 unsigned successful, failed; 88 context_.GetRequestCountsForTesting(index, &successful, &failed); 89 return successful == expected_successful && failed == expected_failed; 90 } 91 92 MockTime time_; 93 DomainReliabilityDispatcher dispatcher_; 94 DomainReliabilityScheduler::Params params_; 95 MockUploader uploader_; 96 std::string upload_reporter_string_; 97 DomainReliabilityContext context_; 98 99 private: 100 void OnUploadRequest( 101 const std::string& report_json, 102 const GURL& upload_url, 103 const DomainReliabilityUploader::UploadCallback& callback) { 104 DCHECK(!upload_pending_); 105 upload_report_ = report_json; 106 upload_url_ = upload_url; 107 upload_callback_ = callback; 108 upload_pending_ = true; 109 } 110 111 bool upload_pending_; 112 std::string upload_report_; 113 GURL upload_url_; 114 DomainReliabilityUploader::UploadCallback upload_callback_; 115 }; 116 117 TEST_F(DomainReliabilityContextTest, Create) { 118 EXPECT_TRUE(CheckNoBeacons()); 119 EXPECT_TRUE(CheckCounts(0, 0, 0)); 120 EXPECT_TRUE(CheckCounts(1, 0, 0)); 121 } 122 123 TEST_F(DomainReliabilityContextTest, NoResource) { 124 GURL url("http://example/no_resource"); 125 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 126 context_.OnBeacon(url, beacon); 127 128 EXPECT_TRUE(CheckNoBeacons()); 129 EXPECT_TRUE(CheckCounts(0, 0, 0)); 130 EXPECT_TRUE(CheckCounts(1, 0, 0)); 131 } 132 133 TEST_F(DomainReliabilityContextTest, NeverReport) { 134 GURL url("http://example/never_report"); 135 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 136 context_.OnBeacon(url, beacon); 137 138 EXPECT_TRUE(CheckNoBeacons()); 139 EXPECT_TRUE(CheckCounts(0, 0, 0)); 140 EXPECT_TRUE(CheckCounts(1, 1, 0)); 141 } 142 143 TEST_F(DomainReliabilityContextTest, AlwaysReport) { 144 GURL url("http://example/always_report"); 145 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 146 context_.OnBeacon(url, beacon); 147 148 BeaconVector beacons; 149 context_.GetQueuedBeaconsForTesting(&beacons); 150 EXPECT_EQ(1u, beacons.size()); 151 EXPECT_TRUE(CheckCounts(0, 1, 0)); 152 EXPECT_TRUE(CheckCounts(1, 0, 0)); 153 } 154 155 TEST_F(DomainReliabilityContextTest, ReportUpload) { 156 GURL url("http://example/always_report"); 157 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 158 context_.OnBeacon(url, beacon); 159 160 BeaconVector beacons; 161 context_.GetQueuedBeaconsForTesting(&beacons); 162 EXPECT_EQ(1u, beacons.size()); 163 EXPECT_TRUE(CheckCounts(0, 1, 0)); 164 EXPECT_TRUE(CheckCounts(1, 0, 0)); 165 166 // N.B.: Assumes max_delay is 5 minutes. 167 const char* kExpectedReport = "{" 168 "\"config_version\":\"1\"," 169 "\"entries\":[{\"domain\":\"localhost\"," 170 "\"http_response_code\":200,\"protocol\":\"HTTP\"," 171 "\"request_age_ms\":300250,\"request_elapsed_ms\":250," 172 "\"resource\":\"always_report\",\"server_ip\":\"127.0.0.1\"," 173 "\"status\":\"ok\"}]," 174 "\"reporter\":\"test-reporter\"," 175 "\"resources\":[{\"failed_requests\":0,\"name\":\"always_report\"," 176 "\"successful_requests\":1}]}"; 177 178 time_.Advance(max_delay()); 179 EXPECT_TRUE(upload_pending()); 180 EXPECT_EQ(kExpectedReport, upload_report()); 181 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url()); 182 CallUploadCallback(true); 183 184 EXPECT_TRUE(CheckNoBeacons()); 185 EXPECT_TRUE(CheckCounts(0, 0, 0)); 186 EXPECT_TRUE(CheckCounts(1, 0, 0)); 187 } 188 189 } // namespace 190 } // namespace domain_reliability 191