monitor_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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/monitor.h" 6 7#include <map> 8#include <string> 9#include <vector> 10 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" 27 28namespace domain_reliability { 29 30namespace { 31 32typedef std::vector<DomainReliabilityBeacon> BeaconVector; 33 34static const size_t kAlwaysReportIndex = 0u; 35static const size_t kNeverReportIndex = 1u; 36 37scoped_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()))); 42} 43 44} // namespace 45 46class DomainReliabilityMonitorTest : public testing::Test { 47 protected: 48 typedef DomainReliabilityMonitor::RequestInfo RequestInfo; 49 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_)), 56 context_(NULL) { 57 monitor_.Init(url_request_context_getter_); 58 context_ = monitor_.AddContextForTesting(MakeTestConfig()); 59 } 60 61 static RequestInfo MakeRequestInfo() { 62 RequestInfo request; 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; 74 return request; 75 } 76 77 void OnRequestLegComplete(const RequestInfo& info) { 78 monitor_.OnRequestLegComplete(info); 79 } 80 81 size_t CountPendingBeacons(size_t index) { 82 BeaconVector beacons; 83 context_->GetQueuedDataForTesting(index, &beacons, NULL, NULL); 84 return beacons.size(); 85 } 86 87 bool CheckRequestCounts(size_t index, 88 uint32 expected_successful, 89 uint32 expected_failed) { 90 uint32 successful, failed; 91 context_->GetQueuedDataForTesting(index, NULL, &successful, &failed); 92 EXPECT_EQ(expected_successful, successful); 93 EXPECT_EQ(expected_failed, failed); 94 return expected_successful == successful && expected_failed == failed; 95 } 96 97 scoped_refptr<base::TestSimpleTaskRunner> network_task_runner_; 98 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 99 MockTime* time_; 100 DomainReliabilityMonitor monitor_; 101 DomainReliabilityContext* context_; 102 DomainReliabilityMonitor::RequestInfo request_; 103}; 104 105namespace { 106 107TEST_F(DomainReliabilityMonitorTest, Create) { 108 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 109 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 110 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 111 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 112} 113 114TEST_F(DomainReliabilityMonitorTest, NoContext) { 115 RequestInfo request = MakeRequestInfo(); 116 request.url = GURL("http://no-context/"); 117 OnRequestLegComplete(request); 118 119 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 120 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 121 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 122 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 123} 124 125TEST_F(DomainReliabilityMonitorTest, NotReported) { 126 RequestInfo request = MakeRequestInfo(); 127 request.url = GURL("http://example/never_report"); 128 OnRequestLegComplete(request); 129 130 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 131 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 1u, 0u)); 132} 133 134TEST_F(DomainReliabilityMonitorTest, NetworkFailure) { 135 RequestInfo request = MakeRequestInfo(); 136 request.url = GURL("http://example/always_report"); 137 request.status.set_status(net::URLRequestStatus::FAILED); 138 request.status.set_error(net::ERR_CONNECTION_RESET); 139 request.response_info.headers = NULL; 140 OnRequestLegComplete(request); 141 142 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 143 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 1u)); 144} 145 146TEST_F(DomainReliabilityMonitorTest, ServerFailure) { 147 RequestInfo request = MakeRequestInfo(); 148 request.url = GURL("http://example/always_report"); 149 request.response_info.headers = 150 MakeHttpResponseHeaders("HTTP/1.1 500 :(\n\n"); 151 OnRequestLegComplete(request); 152 153 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 154 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 1u)); 155} 156 157TEST_F(DomainReliabilityMonitorTest, NotReportedFailure) { 158 RequestInfo request = MakeRequestInfo(); 159 request.url = GURL("http://example/never_report"); 160 request.status.set_status(net::URLRequestStatus::FAILED); 161 request.status.set_error(net::ERR_CONNECTION_RESET); 162 OnRequestLegComplete(request); 163 164 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 165 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 1u)); 166} 167 168TEST_F(DomainReliabilityMonitorTest, Request) { 169 RequestInfo request = MakeRequestInfo(); 170 request.url = GURL("http://example/always_report"); 171 OnRequestLegComplete(request); 172 173 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 174 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 175} 176 177// Make sure the monitor does not log requests that did not access the network. 178TEST_F(DomainReliabilityMonitorTest, DidNotAccessNetwork) { 179 RequestInfo request = MakeRequestInfo(); 180 request.url = GURL("http://example/always_report"); 181 request.response_info.network_accessed = false; 182 OnRequestLegComplete(request); 183 184 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 185 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 186} 187 188// Make sure the monitor does not log requests that don't send cookies. 189TEST_F(DomainReliabilityMonitorTest, DoNotSendCookies) { 190 RequestInfo request = MakeRequestInfo(); 191 request.url = GURL("http://example/always_report"); 192 request.load_flags = net::LOAD_DO_NOT_SEND_COOKIES; 193 OnRequestLegComplete(request); 194 195 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 196 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 197} 198 199// Make sure the monitor does not log upload requests. 200TEST_F(DomainReliabilityMonitorTest, IsUpload) { 201 RequestInfo request = MakeRequestInfo(); 202 request.url = GURL("http://example/always_report"); 203 request.is_upload = true; 204 OnRequestLegComplete(request); 205 206 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 207 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 208} 209 210// Make sure the monitor does not log a network-local error. 211TEST_F(DomainReliabilityMonitorTest, LocalError) { 212 RequestInfo request = MakeRequestInfo(); 213 request.url = GURL("http://example/always_report"); 214 request.status.set_status(net::URLRequestStatus::FAILED); 215 request.status.set_error(net::ERR_PROXY_CONNECTION_FAILED); 216 OnRequestLegComplete(request); 217 218 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 219 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 220} 221 222// Make sure the monitor does not log the proxy's IP if one was used. 223TEST_F(DomainReliabilityMonitorTest, WasFetchedViaProxy) { 224 RequestInfo request = MakeRequestInfo(); 225 request.url = GURL("http://example/always_report"); 226 request.response_info.socket_address = 227 net::HostPortPair::FromString("127.0.0.1:3128"); 228 request.response_info.was_fetched_via_proxy = true; 229 OnRequestLegComplete(request); 230 231 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 232 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 233 234 BeaconVector beacons; 235 context_->GetQueuedDataForTesting(kAlwaysReportIndex, &beacons, NULL, NULL); 236 EXPECT_TRUE(beacons[0].server_ip.empty()); 237} 238 239// Will fail when baked-in configs expire, as a reminder to update them. 240// (Contact ttuttle@chromium.org if this starts failing.) 241TEST_F(DomainReliabilityMonitorTest, AddBakedInConfigs) { 242 // AddBakedInConfigs DCHECKs that the baked-in configs parse correctly, so 243 // this unittest will fail if someone tries to add an invalid config to the 244 // source tree. 245 monitor_.AddBakedInConfigs(); 246 247 // Count the number of baked-in configs. 248 size_t num_baked_in_configs = 0; 249 for (const char* const* p = kBakedInJsonConfigs; *p; ++p) 250 ++num_baked_in_configs; 251 252 // The monitor should have contexts for all of the baked-in configs, plus the 253 // test one added in the test constructor. 254 EXPECT_EQ(num_baked_in_configs + 1, monitor_.contexts_size_for_testing()); 255} 256 257TEST_F(DomainReliabilityMonitorTest, ClearBeacons) { 258 // Initially the monitor should have just the test context, with no beacons. 259 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 260 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 261 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 262 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 263 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 264 265 // Add a beacon. 266 RequestInfo request = MakeRequestInfo(); 267 request.url = GURL("http://example/always_report"); 268 OnRequestLegComplete(request); 269 270 // Make sure it was added. 271 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 272 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 273 274 monitor_.ClearBrowsingData(CLEAR_BEACONS); 275 276 // Make sure the beacon was cleared, but not the contexts. 277 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 278 EXPECT_EQ(0u, CountPendingBeacons(kAlwaysReportIndex)); 279 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 280 EXPECT_EQ(0u, CountPendingBeacons(kNeverReportIndex)); 281 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 282} 283 284TEST_F(DomainReliabilityMonitorTest, ClearContexts) { 285 // Initially the monitor should have just the test context. 286 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 287 288 monitor_.ClearBrowsingData(CLEAR_CONTEXTS); 289 290 // Clearing contexts should leave the monitor with none. 291 EXPECT_EQ(0u, monitor_.contexts_size_for_testing()); 292} 293 294TEST_F(DomainReliabilityMonitorTest, IgnoreSuccessError) { 295 RequestInfo request = MakeRequestInfo(); 296 request.url = GURL("http://example/always_report"); 297 request.status.set_error(net::ERR_QUIC_PROTOCOL_ERROR); 298 OnRequestLegComplete(request); 299 300 EXPECT_EQ(1u, CountPendingBeacons(kAlwaysReportIndex)); 301 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 302 303 BeaconVector beacons; 304 context_->GetQueuedDataForTesting(kAlwaysReportIndex, &beacons, NULL, NULL); 305 EXPECT_EQ(net::OK, beacons[0].chrome_error); 306} 307 308} // namespace 309 310} // namespace domain_reliability 311