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.status = "ok"; 29 beacon.chrome_error = net::OK; 30 beacon.server_ip = "127.0.0.1"; 31 beacon.http_response_code = 200; 32 beacon.elapsed = base::TimeDelta::FromMilliseconds(250); 33 beacon.start_time = time->NowTicks() - beacon.elapsed; 34 return beacon; 35 } 36 37 class DomainReliabilityContextTest : public testing::Test { 38 protected: 39 DomainReliabilityContextTest() 40 : dispatcher_(&time_), 41 params_(MakeTestSchedulerParams()), 42 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest, 43 base::Unretained(this))), 44 upload_reporter_string_("test-reporter"), 45 context_(&time_, 46 params_, 47 upload_reporter_string_, 48 &dispatcher_, 49 &uploader_, 50 MakeTestConfig().Pass()), 51 upload_pending_(false) {} 52 53 TimeDelta min_delay() const { return params_.minimum_upload_delay; } 54 TimeDelta max_delay() const { return params_.maximum_upload_delay; } 55 TimeDelta retry_interval() const { return params_.upload_retry_interval; } 56 TimeDelta zero_delta() const { return TimeDelta::FromMicroseconds(0); } 57 58 bool upload_pending() { return upload_pending_; } 59 60 const std::string& upload_report() { 61 DCHECK(upload_pending_); 62 return upload_report_; 63 } 64 65 const GURL& upload_url() { 66 DCHECK(upload_pending_); 67 return upload_url_; 68 } 69 70 void CallUploadCallback(bool success) { 71 DCHECK(upload_pending_); 72 upload_callback_.Run(success); 73 upload_pending_ = false; 74 } 75 76 bool CheckNoBeacons(size_t index) { 77 BeaconVector beacons; 78 context_.GetQueuedDataForTesting(index, &beacons, NULL, NULL); 79 return beacons.empty(); 80 } 81 82 bool CheckCounts(size_t index, 83 unsigned expected_successful, 84 unsigned expected_failed) { 85 unsigned successful, failed; 86 context_.GetQueuedDataForTesting(index, NULL, &successful, &failed); 87 return successful == expected_successful && failed == expected_failed; 88 } 89 90 MockTime time_; 91 DomainReliabilityDispatcher dispatcher_; 92 DomainReliabilityScheduler::Params params_; 93 MockUploader uploader_; 94 std::string upload_reporter_string_; 95 DomainReliabilityContext context_; 96 97 private: 98 void OnUploadRequest( 99 const std::string& report_json, 100 const GURL& upload_url, 101 const DomainReliabilityUploader::UploadCallback& callback) { 102 DCHECK(!upload_pending_); 103 upload_report_ = report_json; 104 upload_url_ = upload_url; 105 upload_callback_ = callback; 106 upload_pending_ = true; 107 } 108 109 bool upload_pending_; 110 std::string upload_report_; 111 GURL upload_url_; 112 DomainReliabilityUploader::UploadCallback upload_callback_; 113 }; 114 115 TEST_F(DomainReliabilityContextTest, Create) { 116 EXPECT_TRUE(CheckNoBeacons(0)); 117 EXPECT_TRUE(CheckCounts(0, 0, 0)); 118 EXPECT_TRUE(CheckNoBeacons(1)); 119 EXPECT_TRUE(CheckCounts(1, 0, 0)); 120 } 121 122 TEST_F(DomainReliabilityContextTest, NoResource) { 123 GURL url("http://example/no_resource"); 124 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 125 context_.OnBeacon(url, beacon); 126 127 EXPECT_TRUE(CheckNoBeacons(0)); 128 EXPECT_TRUE(CheckCounts(0, 0, 0)); 129 EXPECT_TRUE(CheckNoBeacons(1)); 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(0)); 139 EXPECT_TRUE(CheckCounts(0, 0, 0)); 140 EXPECT_TRUE(CheckNoBeacons(1)); 141 EXPECT_TRUE(CheckCounts(1, 1, 0)); 142 } 143 144 TEST_F(DomainReliabilityContextTest, AlwaysReport) { 145 GURL url("http://example/always_report"); 146 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 147 context_.OnBeacon(url, beacon); 148 149 BeaconVector beacons; 150 context_.GetQueuedDataForTesting(0, &beacons, NULL, NULL); 151 EXPECT_EQ(1u, beacons.size()); 152 EXPECT_TRUE(CheckCounts(0, 1, 0)); 153 EXPECT_TRUE(CheckNoBeacons(1)); 154 EXPECT_TRUE(CheckCounts(1, 0, 0)); 155 } 156 157 TEST_F(DomainReliabilityContextTest, ReportUpload) { 158 GURL url("http://example/always_report"); 159 DomainReliabilityBeacon beacon = MakeBeacon(&time_); 160 context_.OnBeacon(url, beacon); 161 162 // N.B.: Assumes max_delay is 5 minutes. 163 const char* kExpectedReport = "{\"config_version\":\"1\"," 164 "\"reporter\":\"test-reporter\"," 165 "\"resource_reports\":[{\"beacons\":[{\"http_response_code\":200," 166 "\"request_age_ms\":300250,\"request_elapsed_ms\":250,\"server_ip\":" 167 "\"127.0.0.1\",\"status\":\"ok\"}],\"failed_requests\":0," 168 "\"resource_name\":\"always_report\",\"successful_requests\":1}]}"; 169 170 time_.Advance(max_delay()); 171 EXPECT_TRUE(upload_pending()); 172 EXPECT_EQ(kExpectedReport, upload_report()); 173 EXPECT_EQ(GURL("https://example/upload"), upload_url()); 174 CallUploadCallback(true); 175 } 176 177 } // namespace 178 } // namespace domain_reliability 179