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.
5 #include "components/domain_reliability/context.h"
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/dispatcher.h"
14 #include "components/domain_reliability/scheduler.h"
15 #include "components/domain_reliability/test_util.h"
16 #include "net/base/net_errors.h"
17 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace domain_reliability {
23 typedef std::vector<DomainReliabilityBeacon> BeaconVector;
25 DomainReliabilityBeacon MakeBeacon(MockableTime* time) {
26 DomainReliabilityBeacon beacon;
28 beacon.chrome_error = net::OK;
29 beacon.server_ip = "127.0.0.1";
30 beacon.http_response_code = 200;
31 beacon.elapsed = base::TimeDelta::FromMilliseconds(250);
32 beacon.start_time = time->NowTicks() - beacon.elapsed;
38 class DomainReliabilityContextTest : public testing::Test {
40 DomainReliabilityContextTest()
41 : dispatcher_(&time_),
42 params_(CreateParams()),
43 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest,
44 base::Unretained(this))),
45 upload_reporter_string_("test-reporter"),
48 upload_reporter_string_,
51 CreateConfig().Pass()),
52 upload_pending_(false) {}
54 TimeDelta min_delay() const { return params_.minimum_upload_delay; }
55 TimeDelta max_delay() const { return params_.maximum_upload_delay; }
56 TimeDelta retry_interval() const { return params_.upload_retry_interval; }
57 TimeDelta zero_delta() const { return TimeDelta::FromMicroseconds(0); }
59 bool upload_pending() { return upload_pending_; }
61 const std::string& upload_report() {
62 DCHECK(upload_pending_);
63 return upload_report_;
66 const GURL& upload_url() {
67 DCHECK(upload_pending_);
71 void CallUploadCallback(bool success) {
72 DCHECK(upload_pending_);
73 upload_callback_.Run(success);
74 upload_pending_ = false;
77 bool CheckNoBeacons(size_t index) {
79 context_.GetQueuedDataForTesting(index, &beacons, NULL, NULL);
80 return beacons.empty();
83 bool CheckCounts(size_t index,
84 unsigned expected_successful,
85 unsigned expected_failed) {
86 unsigned successful, failed;
87 context_.GetQueuedDataForTesting(index, NULL, &successful, &failed);
88 return successful == expected_successful && failed == expected_failed;
92 DomainReliabilityDispatcher dispatcher_;
93 DomainReliabilityScheduler::Params params_;
94 MockUploader uploader_;
95 std::string upload_reporter_string_;
96 DomainReliabilityContext context_;
100 const std::string& report_json,
101 const GURL& upload_url,
102 const DomainReliabilityUploader::UploadCallback& callback) {
103 DCHECK(!upload_pending_);
104 upload_report_ = report_json;
105 upload_url_ = upload_url;
106 upload_callback_ = callback;
107 upload_pending_ = true;
110 static DomainReliabilityScheduler::Params CreateParams() {
111 DomainReliabilityScheduler::Params params;
112 params.minimum_upload_delay = base::TimeDelta::FromSeconds(60);
113 params.maximum_upload_delay = base::TimeDelta::FromSeconds(300);
114 params.upload_retry_interval = base::TimeDelta::FromSeconds(15);
118 static scoped_ptr<const DomainReliabilityConfig> CreateConfig() {
119 DomainReliabilityConfig* config = new DomainReliabilityConfig();
120 DomainReliabilityConfig::Resource* resource;
122 resource = new DomainReliabilityConfig::Resource();
123 resource->name = "always_report";
124 resource->url_patterns.push_back(
125 new std::string("http://example/always_report"));
126 resource->success_sample_rate = 1.0;
127 resource->failure_sample_rate = 1.0;
128 config->resources.push_back(resource);
130 resource = new DomainReliabilityConfig::Resource();
131 resource->name = "never_report";
132 resource->url_patterns.push_back(
133 new std::string("http://example/never_report"));
134 resource->success_sample_rate = 0.0;
135 resource->failure_sample_rate = 0.0;
136 config->resources.push_back(resource);
138 DomainReliabilityConfig::Collector* collector;
139 collector = new DomainReliabilityConfig::Collector();
140 collector->upload_url = GURL("https://example/upload");
141 config->collectors.push_back(collector);
143 return scoped_ptr<const DomainReliabilityConfig>(config);
146 bool upload_pending_;
147 std::string upload_report_;
149 DomainReliabilityUploader::UploadCallback upload_callback_;
152 TEST_F(DomainReliabilityContextTest, Create) {
153 EXPECT_TRUE(CheckNoBeacons(0));
154 EXPECT_TRUE(CheckCounts(0, 0, 0));
155 EXPECT_TRUE(CheckNoBeacons(1));
156 EXPECT_TRUE(CheckCounts(1, 0, 0));
159 TEST_F(DomainReliabilityContextTest, NoResource) {
160 GURL url("http://example/no_resource");
161 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
162 context_.OnBeacon(url, beacon);
164 EXPECT_TRUE(CheckNoBeacons(0));
165 EXPECT_TRUE(CheckCounts(0, 0, 0));
166 EXPECT_TRUE(CheckNoBeacons(1));
167 EXPECT_TRUE(CheckCounts(1, 0, 0));
170 TEST_F(DomainReliabilityContextTest, NeverReport) {
171 GURL url("http://example/never_report");
172 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
173 context_.OnBeacon(url, beacon);
175 EXPECT_TRUE(CheckNoBeacons(0));
176 EXPECT_TRUE(CheckCounts(0, 0, 0));
177 EXPECT_TRUE(CheckNoBeacons(1));
178 EXPECT_TRUE(CheckCounts(1, 1, 0));
181 TEST_F(DomainReliabilityContextTest, AlwaysReport) {
182 GURL url("http://example/always_report");
183 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
184 context_.OnBeacon(url, beacon);
186 BeaconVector beacons;
187 context_.GetQueuedDataForTesting(0, &beacons, NULL, NULL);
188 EXPECT_EQ(1u, beacons.size());
189 EXPECT_TRUE(CheckCounts(0, 1, 0));
190 EXPECT_TRUE(CheckNoBeacons(1));
191 EXPECT_TRUE(CheckCounts(1, 0, 0));
194 TEST_F(DomainReliabilityContextTest, ReportUpload) {
195 GURL url("http://example/always_report");
196 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
197 context_.OnBeacon(url, beacon);
199 const char* kExpectedReport = "{\"reporter\":\"test-reporter\","
200 "\"resource_reports\":[{\"beacons\":[{\"http_response_code\":200,"
201 "\"request_age_ms\":300250,\"request_elapsed_ms\":250,\"server_ip\":"
202 "\"127.0.0.1\",\"status\":\"ok\"}],\"failed_requests\":0,"
203 "\"resource_name\":\"always_report\",\"successful_requests\":1},"
204 "{\"beacons\":[],\"failed_requests\":0,\"resource_name\":"
205 "\"never_report\",\"successful_requests\":0}]}";
207 time_.Advance(max_delay());
208 EXPECT_TRUE(upload_pending());
209 EXPECT_EQ(kExpectedReport, upload_report());
210 EXPECT_EQ(GURL("https://example/upload"), upload_url());
211 CallUploadCallback(true);
214 } // namespace domain_reliability