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/monitor.h"
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/test/test_simple_task_runner.h"
15 #include "components/domain_reliability/baked_in_configs.h"
16 #include "components/domain_reliability/beacon.h"
17 #include "components/domain_reliability/config.h"
18 #include "components/domain_reliability/test_util.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/load_flags.h"
21 #include "net/http/http_response_headers.h"
22 #include "net/http/http_util.h"
23 #include "net/url_request/url_request_context_getter.h"
24 #include "net/url_request/url_request_status.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 namespace domain_reliability
{
32 typedef std::vector
<DomainReliabilityBeacon
> BeaconVector
;
34 static const size_t kAlwaysReportIndex
= 0u;
35 static const size_t kNeverReportIndex
= 1u;
37 scoped_refptr
<net::HttpResponseHeaders
> MakeHttpResponseHeaders(
38 const std::string
& headers
) {
39 return scoped_refptr
<net::HttpResponseHeaders
>(
40 new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
41 headers
.c_str(), headers
.length())));
46 class DomainReliabilityMonitorTest
: public testing::Test
{
48 typedef DomainReliabilityMonitor::RequestInfo RequestInfo
;
50 DomainReliabilityMonitorTest()
51 : network_task_runner_(new base::TestSimpleTaskRunner()),
52 url_request_context_getter_(
53 new net::TestURLRequestContextGetter(network_task_runner_
)),
54 time_(new MockTime()),
55 monitor_("test-reporter", scoped_ptr
<MockableTime
>(time_
)),
57 monitor_
.Init(url_request_context_getter_
);
58 context_
= monitor_
.AddContextForTesting(MakeTestConfig());
61 static RequestInfo
MakeRequestInfo() {
63 request
.status
= net::URLRequestStatus();
64 request
.status
.set_status(net::URLRequestStatus::SUCCESS
);
65 request
.status
.set_error(net::OK
);
66 request
.response_info
.socket_address
=
67 net::HostPortPair::FromString("12.34.56.78:80");
68 request
.response_info
.headers
= MakeHttpResponseHeaders(
69 "HTTP/1.1 200 OK\n\n");
70 request
.response_info
.network_accessed
= true;
71 request
.response_info
.was_fetched_via_proxy
= false;
72 request
.load_flags
= 0;
73 request
.is_upload
= false;
77 void OnRequestLegComplete(const RequestInfo
& info
) {
78 monitor_
.OnRequestLegComplete(info
);
81 size_t CountPendingBeacons() {
83 context_
->GetQueuedBeaconsForTesting(&beacons
);
84 return beacons
.size();
87 bool CheckRequestCounts(size_t index
,
88 uint32 expected_successful
,
89 uint32 expected_failed
) {
90 uint32 successful
, failed
;
91 context_
->GetRequestCountsForTesting(index
, &successful
, &failed
);
92 EXPECT_EQ(expected_successful
, successful
);
93 EXPECT_EQ(expected_failed
, failed
);
94 return expected_successful
== successful
&& expected_failed
== failed
;
97 scoped_refptr
<base::TestSimpleTaskRunner
> network_task_runner_
;
98 scoped_refptr
<net::URLRequestContextGetter
> url_request_context_getter_
;
100 DomainReliabilityMonitor monitor_
;
101 DomainReliabilityContext
* context_
;
102 DomainReliabilityMonitor::RequestInfo request_
;
107 TEST_F(DomainReliabilityMonitorTest
, Create
) {
108 EXPECT_EQ(0u, CountPendingBeacons());
109 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
110 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 0u, 0u));
113 TEST_F(DomainReliabilityMonitorTest
, NoContext
) {
114 RequestInfo request
= MakeRequestInfo();
115 request
.url
= GURL("http://no-context/");
116 OnRequestLegComplete(request
);
118 EXPECT_EQ(0u, CountPendingBeacons());
119 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
120 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 0u, 0u));
123 TEST_F(DomainReliabilityMonitorTest
, NotReported
) {
124 RequestInfo request
= MakeRequestInfo();
125 request
.url
= GURL("http://example/never_report");
126 OnRequestLegComplete(request
);
128 EXPECT_EQ(0u, CountPendingBeacons());
129 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 1u, 0u));
132 TEST_F(DomainReliabilityMonitorTest
, NetworkFailure
) {
133 RequestInfo request
= MakeRequestInfo();
134 request
.url
= GURL("http://example/always_report");
135 request
.status
.set_status(net::URLRequestStatus::FAILED
);
136 request
.status
.set_error(net::ERR_CONNECTION_RESET
);
137 request
.response_info
.headers
= NULL
;
138 OnRequestLegComplete(request
);
140 EXPECT_EQ(1u, CountPendingBeacons());
141 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 1u));
144 TEST_F(DomainReliabilityMonitorTest
, ServerFailure
) {
145 RequestInfo request
= MakeRequestInfo();
146 request
.url
= GURL("http://example/always_report");
147 request
.response_info
.headers
=
148 MakeHttpResponseHeaders("HTTP/1.1 500 :(\n\n");
149 OnRequestLegComplete(request
);
151 EXPECT_EQ(1u, CountPendingBeacons());
152 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 1u));
155 TEST_F(DomainReliabilityMonitorTest
, NotReportedFailure
) {
156 RequestInfo request
= MakeRequestInfo();
157 request
.url
= GURL("http://example/never_report");
158 request
.status
.set_status(net::URLRequestStatus::FAILED
);
159 request
.status
.set_error(net::ERR_CONNECTION_RESET
);
160 OnRequestLegComplete(request
);
162 EXPECT_EQ(0u, CountPendingBeacons());
163 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 0u, 1u));
166 TEST_F(DomainReliabilityMonitorTest
, Request
) {
167 RequestInfo request
= MakeRequestInfo();
168 request
.url
= GURL("http://example/always_report");
169 OnRequestLegComplete(request
);
171 EXPECT_EQ(1u, CountPendingBeacons());
172 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 1u, 0u));
175 // Make sure the monitor does not log requests that did not access the network.
176 TEST_F(DomainReliabilityMonitorTest
, DidNotAccessNetwork
) {
177 RequestInfo request
= MakeRequestInfo();
178 request
.url
= GURL("http://example/always_report");
179 request
.response_info
.network_accessed
= false;
180 OnRequestLegComplete(request
);
182 EXPECT_EQ(0u, CountPendingBeacons());
183 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
186 // Make sure the monitor does not log requests that don't send cookies.
187 TEST_F(DomainReliabilityMonitorTest
, DoNotSendCookies
) {
188 RequestInfo request
= MakeRequestInfo();
189 request
.url
= GURL("http://example/always_report");
190 request
.load_flags
= net::LOAD_DO_NOT_SEND_COOKIES
;
191 OnRequestLegComplete(request
);
193 EXPECT_EQ(0u, CountPendingBeacons());
194 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
197 // Make sure the monitor does not log upload requests.
198 TEST_F(DomainReliabilityMonitorTest
, IsUpload
) {
199 RequestInfo request
= MakeRequestInfo();
200 request
.url
= GURL("http://example/always_report");
201 request
.is_upload
= true;
202 OnRequestLegComplete(request
);
204 EXPECT_EQ(0u, CountPendingBeacons());
205 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
208 // Make sure the monitor does not log a network-local error.
209 TEST_F(DomainReliabilityMonitorTest
, LocalError
) {
210 RequestInfo request
= MakeRequestInfo();
211 request
.url
= GURL("http://example/always_report");
212 request
.status
.set_status(net::URLRequestStatus::FAILED
);
213 request
.status
.set_error(net::ERR_PROXY_CONNECTION_FAILED
);
214 OnRequestLegComplete(request
);
216 EXPECT_EQ(0u, CountPendingBeacons());
217 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
220 // Make sure the monitor does not log the proxy's IP if one was used.
221 TEST_F(DomainReliabilityMonitorTest
, WasFetchedViaProxy
) {
222 RequestInfo request
= MakeRequestInfo();
223 request
.url
= GURL("http://example/always_report");
224 request
.response_info
.socket_address
=
225 net::HostPortPair::FromString("127.0.0.1:3128");
226 request
.response_info
.was_fetched_via_proxy
= true;
227 OnRequestLegComplete(request
);
229 BeaconVector beacons
;
230 context_
->GetQueuedBeaconsForTesting(&beacons
);
231 EXPECT_EQ(1u, beacons
.size());
232 EXPECT_TRUE(beacons
[0].server_ip
.empty());
234 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 1u, 0u));
237 // Will fail when baked-in configs expire, as a reminder to update them.
238 // (Contact ttuttle@chromium.org if this starts failing.)
239 TEST_F(DomainReliabilityMonitorTest
, AddBakedInConfigs
) {
240 // AddBakedInConfigs DCHECKs that the baked-in configs parse correctly, so
241 // this unittest will fail if someone tries to add an invalid config to the
243 monitor_
.AddBakedInConfigs();
245 // Count the number of baked-in configs.
246 size_t num_baked_in_configs
= 0;
247 for (const char* const* p
= kBakedInJsonConfigs
; *p
; ++p
)
248 ++num_baked_in_configs
;
250 // The monitor should have contexts for all of the baked-in configs, plus the
251 // test one added in the test constructor.
252 EXPECT_EQ(num_baked_in_configs
+ 1, monitor_
.contexts_size_for_testing());
255 TEST_F(DomainReliabilityMonitorTest
, ClearBeacons
) {
256 // Initially the monitor should have just the test context, with no beacons.
257 EXPECT_EQ(1u, monitor_
.contexts_size_for_testing());
258 EXPECT_EQ(0u, CountPendingBeacons());
259 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
260 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 0u, 0u));
263 RequestInfo request
= MakeRequestInfo();
264 request
.url
= GURL("http://example/always_report");
265 OnRequestLegComplete(request
);
267 // Make sure it was added.
268 EXPECT_EQ(1u, CountPendingBeacons());
269 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 1u, 0u));
271 monitor_
.ClearBrowsingData(CLEAR_BEACONS
);
273 // Make sure the beacon was cleared, but not the contexts.
274 EXPECT_EQ(1u, monitor_
.contexts_size_for_testing());
275 EXPECT_EQ(0u, CountPendingBeacons());
276 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 0u, 0u));
277 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex
, 0u, 0u));
280 TEST_F(DomainReliabilityMonitorTest
, ClearContexts
) {
281 // Initially the monitor should have just the test context.
282 EXPECT_EQ(1u, monitor_
.contexts_size_for_testing());
284 monitor_
.ClearBrowsingData(CLEAR_CONTEXTS
);
286 // Clearing contexts should leave the monitor with none.
287 EXPECT_EQ(0u, monitor_
.contexts_size_for_testing());
290 TEST_F(DomainReliabilityMonitorTest
, IgnoreSuccessError
) {
291 RequestInfo request
= MakeRequestInfo();
292 request
.url
= GURL("http://example/always_report");
293 request
.status
.set_error(net::ERR_QUIC_PROTOCOL_ERROR
);
294 OnRequestLegComplete(request
);
296 BeaconVector beacons
;
297 context_
->GetQueuedBeaconsForTesting(&beacons
);
298 EXPECT_EQ(1u, beacons
.size());
299 EXPECT_EQ(net::OK
, beacons
[0].chrome_error
);
301 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex
, 1u, 0u));
306 } // namespace domain_reliability