monitor_unittest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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() { 82 BeaconVector beacons; 83 context_->GetQueuedBeaconsForTesting(&beacons); 84 return beacons.size(); 85 } 86 87 bool CheckRequestCounts(size_t index, 88 uint32 expected_successful, 89 uint32 expected_failed) { 90 return CheckRequestCounts(context_, 91 index, 92 expected_successful, 93 expected_failed); 94 } 95 96 bool CheckRequestCounts(DomainReliabilityContext* context, 97 size_t index, 98 uint32 expected_successful, 99 uint32 expected_failed) { 100 uint32 successful, failed; 101 context->GetRequestCountsForTesting(index, &successful, &failed); 102 EXPECT_EQ(expected_successful, successful); 103 EXPECT_EQ(expected_failed, failed); 104 return expected_successful == successful && expected_failed == failed; 105 } 106 107 DomainReliabilityContext* CreateAndAddContext(const std::string& domain) { 108 return monitor_.AddContextForTesting(MakeTestConfigWithDomain(domain)); 109 } 110 111 scoped_refptr<base::TestSimpleTaskRunner> network_task_runner_; 112 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 113 MockTime* time_; 114 DomainReliabilityMonitor monitor_; 115 DomainReliabilityContext* context_; 116 DomainReliabilityMonitor::RequestInfo request_; 117}; 118 119namespace { 120 121TEST_F(DomainReliabilityMonitorTest, Create) { 122 EXPECT_EQ(0u, CountPendingBeacons()); 123 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 124 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 125} 126 127TEST_F(DomainReliabilityMonitorTest, NoContext) { 128 RequestInfo request = MakeRequestInfo(); 129 request.url = GURL("http://no-context/"); 130 OnRequestLegComplete(request); 131 132 EXPECT_EQ(0u, CountPendingBeacons()); 133 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 134 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 135} 136 137TEST_F(DomainReliabilityMonitorTest, NotReported) { 138 RequestInfo request = MakeRequestInfo(); 139 request.url = GURL("http://example/never_report"); 140 OnRequestLegComplete(request); 141 142 EXPECT_EQ(0u, CountPendingBeacons()); 143 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 1u, 0u)); 144} 145 146TEST_F(DomainReliabilityMonitorTest, NetworkFailure) { 147 RequestInfo request = MakeRequestInfo(); 148 request.url = GURL("http://example/always_report"); 149 request.status.set_status(net::URLRequestStatus::FAILED); 150 request.status.set_error(net::ERR_CONNECTION_RESET); 151 request.response_info.headers = NULL; 152 OnRequestLegComplete(request); 153 154 EXPECT_EQ(1u, CountPendingBeacons()); 155 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 1u)); 156} 157 158TEST_F(DomainReliabilityMonitorTest, ServerFailure) { 159 RequestInfo request = MakeRequestInfo(); 160 request.url = GURL("http://example/always_report"); 161 request.response_info.headers = 162 MakeHttpResponseHeaders("HTTP/1.1 500 :(\n\n"); 163 OnRequestLegComplete(request); 164 165 EXPECT_EQ(1u, CountPendingBeacons()); 166 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 1u)); 167} 168 169TEST_F(DomainReliabilityMonitorTest, NotReportedFailure) { 170 RequestInfo request = MakeRequestInfo(); 171 request.url = GURL("http://example/never_report"); 172 request.status.set_status(net::URLRequestStatus::FAILED); 173 request.status.set_error(net::ERR_CONNECTION_RESET); 174 OnRequestLegComplete(request); 175 176 EXPECT_EQ(0u, CountPendingBeacons()); 177 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 1u)); 178} 179 180TEST_F(DomainReliabilityMonitorTest, Request) { 181 RequestInfo request = MakeRequestInfo(); 182 request.url = GURL("http://example/always_report"); 183 OnRequestLegComplete(request); 184 185 EXPECT_EQ(1u, CountPendingBeacons()); 186 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 187} 188 189// Make sure the monitor does not log requests that did not access the network. 190TEST_F(DomainReliabilityMonitorTest, DidNotAccessNetwork) { 191 RequestInfo request = MakeRequestInfo(); 192 request.url = GURL("http://example/always_report"); 193 request.response_info.network_accessed = false; 194 OnRequestLegComplete(request); 195 196 EXPECT_EQ(0u, CountPendingBeacons()); 197 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 198} 199 200// Make sure the monitor does not log requests that don't send cookies. 201TEST_F(DomainReliabilityMonitorTest, DoNotSendCookies) { 202 RequestInfo request = MakeRequestInfo(); 203 request.url = GURL("http://example/always_report"); 204 request.load_flags = net::LOAD_DO_NOT_SEND_COOKIES; 205 OnRequestLegComplete(request); 206 207 EXPECT_EQ(0u, CountPendingBeacons()); 208 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 209} 210 211// Make sure the monitor does not log upload requests. 212TEST_F(DomainReliabilityMonitorTest, IsUpload) { 213 RequestInfo request = MakeRequestInfo(); 214 request.url = GURL("http://example/always_report"); 215 request.is_upload = true; 216 OnRequestLegComplete(request); 217 218 EXPECT_EQ(0u, CountPendingBeacons()); 219 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 220} 221 222// Make sure the monitor does not log a network-local error. 223TEST_F(DomainReliabilityMonitorTest, LocalError) { 224 RequestInfo request = MakeRequestInfo(); 225 request.url = GURL("http://example/always_report"); 226 request.status.set_status(net::URLRequestStatus::FAILED); 227 request.status.set_error(net::ERR_PROXY_CONNECTION_FAILED); 228 OnRequestLegComplete(request); 229 230 EXPECT_EQ(0u, CountPendingBeacons()); 231 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 232} 233 234// Make sure the monitor does not log the proxy's IP if one was used. 235TEST_F(DomainReliabilityMonitorTest, WasFetchedViaProxy) { 236 RequestInfo request = MakeRequestInfo(); 237 request.url = GURL("http://example/always_report"); 238 request.response_info.socket_address = 239 net::HostPortPair::FromString("127.0.0.1:3128"); 240 request.response_info.was_fetched_via_proxy = true; 241 OnRequestLegComplete(request); 242 243 BeaconVector beacons; 244 context_->GetQueuedBeaconsForTesting(&beacons); 245 EXPECT_EQ(1u, beacons.size()); 246 EXPECT_TRUE(beacons[0].server_ip.empty()); 247 248 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 249} 250 251// Will fail when baked-in configs expire, as a reminder to update them. 252// (Contact ttuttle@chromium.org if this starts failing.) 253TEST_F(DomainReliabilityMonitorTest, AddBakedInConfigs) { 254 // AddBakedInConfigs DCHECKs that the baked-in configs parse correctly, so 255 // this unittest will fail if someone tries to add an invalid config to the 256 // source tree. 257 monitor_.AddBakedInConfigs(); 258 259 // Count the number of baked-in configs. 260 size_t num_baked_in_configs = 0; 261 for (const char* const* p = kBakedInJsonConfigs; *p; ++p) 262 ++num_baked_in_configs; 263 264 // The monitor should have contexts for all of the baked-in configs, plus the 265 // test one added in the test constructor. 266 EXPECT_EQ(num_baked_in_configs + 1, monitor_.contexts_size_for_testing()); 267} 268 269TEST_F(DomainReliabilityMonitorTest, ClearBeacons) { 270 // Initially the monitor should have just the test context, with no beacons. 271 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 272 EXPECT_EQ(0u, CountPendingBeacons()); 273 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 274 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 275 276 // Add a beacon. 277 RequestInfo request = MakeRequestInfo(); 278 request.url = GURL("http://example/always_report"); 279 OnRequestLegComplete(request); 280 281 // Make sure it was added. 282 EXPECT_EQ(1u, CountPendingBeacons()); 283 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 284 285 monitor_.ClearBrowsingData(CLEAR_BEACONS); 286 287 // Make sure the beacon was cleared, but not the contexts. 288 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 289 EXPECT_EQ(0u, CountPendingBeacons()); 290 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 0u, 0u)); 291 EXPECT_TRUE(CheckRequestCounts(kNeverReportIndex, 0u, 0u)); 292} 293 294TEST_F(DomainReliabilityMonitorTest, ClearContexts) { 295 // Initially the monitor should have just the test context. 296 EXPECT_EQ(1u, monitor_.contexts_size_for_testing()); 297 298 monitor_.ClearBrowsingData(CLEAR_CONTEXTS); 299 300 // Clearing contexts should leave the monitor with none. 301 EXPECT_EQ(0u, monitor_.contexts_size_for_testing()); 302} 303 304TEST_F(DomainReliabilityMonitorTest, IgnoreSuccessError) { 305 RequestInfo request = MakeRequestInfo(); 306 request.url = GURL("http://example/always_report"); 307 request.status.set_error(net::ERR_QUIC_PROTOCOL_ERROR); 308 OnRequestLegComplete(request); 309 310 BeaconVector beacons; 311 context_->GetQueuedBeaconsForTesting(&beacons); 312 EXPECT_EQ(1u, beacons.size()); 313 EXPECT_EQ(net::OK, beacons[0].chrome_error); 314 315 EXPECT_TRUE(CheckRequestCounts(kAlwaysReportIndex, 1u, 0u)); 316} 317 318TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSelf) { 319 DomainReliabilityContext* context = CreateAndAddContext("*.wildcard"); 320 321 RequestInfo request = MakeRequestInfo(); 322 request.url = GURL("http://wildcard/always_report"); 323 OnRequestLegComplete(request); 324 EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 1u, 0u)); 325} 326 327TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSubdomain) { 328 DomainReliabilityContext* context = CreateAndAddContext("*.wildcard"); 329 330 RequestInfo request = MakeRequestInfo(); 331 request.url = GURL("http://test.wildcard/always_report"); 332 OnRequestLegComplete(request); 333 EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 1u, 0u)); 334} 335 336TEST_F(DomainReliabilityMonitorTest, WildcardDoesntMatchSubsubdomain) { 337 DomainReliabilityContext* context = CreateAndAddContext("*.wildcard"); 338 339 RequestInfo request = MakeRequestInfo(); 340 request.url = GURL("http://test.test.wildcard/always_report"); 341 OnRequestLegComplete(request); 342 EXPECT_TRUE(CheckRequestCounts(context, kAlwaysReportIndex, 0u, 0u)); 343} 344 345TEST_F(DomainReliabilityMonitorTest, WildcardPrefersSelfToSelfWildcard) { 346 DomainReliabilityContext* context1 = CreateAndAddContext("wildcard"); 347 DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard"); 348 349 RequestInfo request = MakeRequestInfo(); 350 request.url = GURL("http://wildcard/always_report"); 351 OnRequestLegComplete(request); 352 353 EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u)); 354 EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u)); 355} 356 357TEST_F(DomainReliabilityMonitorTest, WildcardPrefersSelfToParentWildcard) { 358 DomainReliabilityContext* context1 = CreateAndAddContext("test.wildcard"); 359 DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard"); 360 361 RequestInfo request = MakeRequestInfo(); 362 request.url = GURL("http://test.wildcard/always_report"); 363 OnRequestLegComplete(request); 364 365 EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u)); 366 EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u)); 367} 368 369TEST_F(DomainReliabilityMonitorTest, 370 WildcardPrefersSelfWildcardToParentWildcard) { 371 DomainReliabilityContext* context1 = CreateAndAddContext("*.test.wildcard"); 372 DomainReliabilityContext* context2 = CreateAndAddContext("*.wildcard"); 373 374 RequestInfo request = MakeRequestInfo(); 375 request.url = GURL("http://test.wildcard/always_report"); 376 OnRequestLegComplete(request); 377 378 EXPECT_TRUE(CheckRequestCounts(context1, kAlwaysReportIndex, 1u, 0u)); 379 EXPECT_TRUE(CheckRequestCounts(context2, kAlwaysReportIndex, 0u, 0u)); 380} 381 382} // namespace 383 384} // namespace domain_reliability 385