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 "components/domain_reliability/beacon.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 "components/domain_reliability/uploader.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"
21 namespace domain_reliability
{
24 typedef std::vector
<DomainReliabilityBeacon
> BeaconVector
;
26 DomainReliabilityBeacon
MakeBeacon(MockableTime
* time
) {
27 DomainReliabilityBeacon beacon
;
28 beacon
.domain
= "localhost";
30 beacon
.chrome_error
= net::OK
;
31 beacon
.server_ip
= "127.0.0.1";
32 beacon
.was_proxied
= false;
33 beacon
.protocol
= "HTTP";
34 beacon
.http_response_code
= 200;
35 beacon
.elapsed
= base::TimeDelta::FromMilliseconds(250);
36 beacon
.start_time
= time
->NowTicks() - beacon
.elapsed
;
40 class DomainReliabilityContextTest
: public testing::Test
{
42 DomainReliabilityContextTest()
43 : last_network_change_time_(time_
.NowTicks()),
45 params_(MakeTestSchedulerParams()),
46 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest
,
47 base::Unretained(this))),
48 upload_reporter_string_("test-reporter"),
51 upload_reporter_string_
,
52 &last_network_change_time_
,
55 MakeTestConfig().Pass()),
56 upload_pending_(false) {
57 // Make sure that the last network change does not overlap requests
58 // made in test cases, which start 250ms in the past (see |MakeBeacon|).
59 last_network_change_time_
= time_
.NowTicks();
60 time_
.Advance(base::TimeDelta::FromSeconds(1));
63 TimeDelta
min_delay() const { return params_
.minimum_upload_delay
; }
64 TimeDelta
max_delay() const { return params_
.maximum_upload_delay
; }
65 TimeDelta
retry_interval() const { return params_
.upload_retry_interval
; }
66 TimeDelta
zero_delta() const { return TimeDelta::FromMicroseconds(0); }
68 bool upload_pending() { return upload_pending_
; }
70 const std::string
& upload_report() {
71 DCHECK(upload_pending_
);
72 return upload_report_
;
75 const GURL
& upload_url() {
76 DCHECK(upload_pending_
);
80 void CallUploadCallback(DomainReliabilityUploader::UploadResult result
) {
81 DCHECK(upload_pending_
);
82 upload_callback_
.Run(result
);
83 upload_pending_
= false;
86 bool CheckNoBeacons() {
88 context_
.GetQueuedBeaconsForTesting(&beacons
);
89 return beacons
.empty();
92 bool CheckCounts(size_t index
,
93 unsigned expected_successful
,
94 unsigned expected_failed
) {
95 unsigned successful
, failed
;
96 context_
.GetRequestCountsForTesting(index
, &successful
, &failed
);
97 return successful
== expected_successful
&& failed
== expected_failed
;
101 base::TimeTicks last_network_change_time_
;
102 DomainReliabilityDispatcher dispatcher_
;
103 DomainReliabilityScheduler::Params params_
;
104 MockUploader uploader_
;
105 std::string upload_reporter_string_
;
106 DomainReliabilityContext context_
;
109 void OnUploadRequest(
110 const std::string
& report_json
,
111 const GURL
& upload_url
,
112 const DomainReliabilityUploader::UploadCallback
& callback
) {
113 DCHECK(!upload_pending_
);
114 upload_report_
= report_json
;
115 upload_url_
= upload_url
;
116 upload_callback_
= callback
;
117 upload_pending_
= true;
120 bool upload_pending_
;
121 std::string upload_report_
;
123 DomainReliabilityUploader::UploadCallback upload_callback_
;
126 TEST_F(DomainReliabilityContextTest
, Create
) {
127 EXPECT_TRUE(CheckNoBeacons());
128 EXPECT_TRUE(CheckCounts(0, 0, 0));
129 EXPECT_TRUE(CheckCounts(1, 0, 0));
132 TEST_F(DomainReliabilityContextTest
, NoResource
) {
133 GURL
url("http://example/no_resource");
134 DomainReliabilityBeacon beacon
= MakeBeacon(&time_
);
135 context_
.OnBeacon(url
, beacon
);
137 EXPECT_TRUE(CheckNoBeacons());
138 EXPECT_TRUE(CheckCounts(0, 0, 0));
139 EXPECT_TRUE(CheckCounts(1, 0, 0));
142 TEST_F(DomainReliabilityContextTest
, NeverReport
) {
143 GURL
url("http://example/never_report");
144 DomainReliabilityBeacon beacon
= MakeBeacon(&time_
);
145 context_
.OnBeacon(url
, beacon
);
147 EXPECT_TRUE(CheckNoBeacons());
148 EXPECT_TRUE(CheckCounts(0, 0, 0));
149 EXPECT_TRUE(CheckCounts(1, 1, 0));
152 TEST_F(DomainReliabilityContextTest
, AlwaysReport
) {
153 GURL
url("http://example/always_report");
154 DomainReliabilityBeacon beacon
= MakeBeacon(&time_
);
155 context_
.OnBeacon(url
, beacon
);
157 BeaconVector beacons
;
158 context_
.GetQueuedBeaconsForTesting(&beacons
);
159 EXPECT_EQ(1u, beacons
.size());
160 EXPECT_TRUE(CheckCounts(0, 1, 0));
161 EXPECT_TRUE(CheckCounts(1, 0, 0));
164 TEST_F(DomainReliabilityContextTest
, ReportUpload
) {
165 GURL
url("http://example/always_report");
166 DomainReliabilityBeacon beacon
= MakeBeacon(&time_
);
167 context_
.OnBeacon(url
, beacon
);
169 BeaconVector beacons
;
170 context_
.GetQueuedBeaconsForTesting(&beacons
);
171 EXPECT_EQ(1u, beacons
.size());
172 EXPECT_TRUE(CheckCounts(0, 1, 0));
173 EXPECT_TRUE(CheckCounts(1, 0, 0));
175 // N.B.: Assumes max_delay is 5 minutes.
176 const char* kExpectedReport
= "{"
177 "\"config_version\":\"1\","
178 "\"entries\":[{\"domain\":\"localhost\","
179 "\"http_response_code\":200,\"network_changed\":false,"
180 "\"protocol\":\"HTTP\",\"request_age_ms\":300250,"
181 "\"request_elapsed_ms\":250,\"resource\":\"always_report\","
182 "\"server_ip\":\"127.0.0.1\",\"status\":\"ok\","
183 "\"was_proxied\":false}],"
184 "\"reporter\":\"test-reporter\","
185 "\"resources\":[{\"failed_requests\":0,\"name\":\"always_report\","
186 "\"successful_requests\":1}]}";
188 time_
.Advance(max_delay());
189 EXPECT_TRUE(upload_pending());
190 EXPECT_EQ(kExpectedReport
, upload_report());
191 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
193 DomainReliabilityUploader::UploadResult result
;
194 result
.status
= DomainReliabilityUploader::UploadResult::SUCCESS
;
195 CallUploadCallback(result
);
197 EXPECT_TRUE(CheckNoBeacons());
198 EXPECT_TRUE(CheckCounts(0, 0, 0));
199 EXPECT_TRUE(CheckCounts(1, 0, 0));
202 TEST_F(DomainReliabilityContextTest
, ReportUpload_NetworkChanged
) {
203 GURL
url("http://example/always_report");
204 DomainReliabilityBeacon beacon
= MakeBeacon(&time_
);
205 context_
.OnBeacon(url
, beacon
);
207 BeaconVector beacons
;
208 context_
.GetQueuedBeaconsForTesting(&beacons
);
209 EXPECT_EQ(1u, beacons
.size());
210 EXPECT_TRUE(CheckCounts(0, 1, 0));
211 EXPECT_TRUE(CheckCounts(1, 0, 0));
213 // N.B.: Assumes max_delay is 5 minutes.
214 const char* kExpectedReport
= "{"
215 "\"config_version\":\"1\","
216 "\"entries\":[{\"domain\":\"localhost\","
217 "\"http_response_code\":200,\"network_changed\":true,"
218 "\"protocol\":\"HTTP\",\"request_age_ms\":300250,"
219 "\"request_elapsed_ms\":250,\"resource\":\"always_report\","
220 "\"server_ip\":\"127.0.0.1\",\"status\":\"ok\","
221 "\"was_proxied\":false}],"
222 "\"reporter\":\"test-reporter\","
223 "\"resources\":[{\"failed_requests\":0,\"name\":\"always_report\","
224 "\"successful_requests\":1}]}";
226 // Simulate a network change after the request but before the upload.
227 last_network_change_time_
= time_
.NowTicks();
228 time_
.Advance(max_delay());
230 EXPECT_TRUE(upload_pending());
231 EXPECT_EQ(kExpectedReport
, upload_report());
232 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
234 DomainReliabilityUploader::UploadResult result
;
235 result
.status
= DomainReliabilityUploader::UploadResult::SUCCESS
;
236 CallUploadCallback(result
);
238 EXPECT_TRUE(CheckNoBeacons());
239 EXPECT_TRUE(CheckCounts(0, 0, 0));
240 EXPECT_TRUE(CheckCounts(1, 0, 0));
244 } // namespace domain_reliability