| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/domain_reliability/context.h" | 5 #include "components/domain_reliability/context.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/json/json_reader.h" |
| 11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 12 #include "components/domain_reliability/beacon.h" | 13 #include "components/domain_reliability/beacon.h" |
| 13 #include "components/domain_reliability/dispatcher.h" | 14 #include "components/domain_reliability/dispatcher.h" |
| 14 #include "components/domain_reliability/scheduler.h" | 15 #include "components/domain_reliability/scheduler.h" |
| 15 #include "components/domain_reliability/test_util.h" | 16 #include "components/domain_reliability/test_util.h" |
| 16 #include "components/domain_reliability/uploader.h" | 17 #include "components/domain_reliability/uploader.h" |
| 17 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 18 #include "net/url_request/url_request_test_util.h" | 19 #include "net/url_request/url_request_test_util.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 namespace domain_reliability { | 22 namespace domain_reliability { |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 25 using base::DictionaryValue; |
| 26 using base::ListValue; |
| 27 using base::Value; |
| 28 |
| 24 typedef std::vector<const DomainReliabilityBeacon*> BeaconVector; | 29 typedef std::vector<const DomainReliabilityBeacon*> BeaconVector; |
| 25 | 30 |
| 26 scoped_ptr<DomainReliabilityBeacon> MakeBeacon(MockableTime* time) { | 31 scoped_ptr<DomainReliabilityBeacon> MakeBeacon(MockableTime* time) { |
| 27 scoped_ptr<DomainReliabilityBeacon> beacon(new DomainReliabilityBeacon()); | 32 scoped_ptr<DomainReliabilityBeacon> beacon(new DomainReliabilityBeacon()); |
| 28 beacon->url = GURL("https://localhost/"); | 33 beacon->url = GURL("https://localhost/"); |
| 29 beacon->status = "tcp.connection_reset"; | 34 beacon->status = "tcp.connection_reset"; |
| 30 beacon->chrome_error = net::ERR_CONNECTION_RESET; | 35 beacon->chrome_error = net::ERR_CONNECTION_RESET; |
| 31 beacon->server_ip = "127.0.0.1"; | 36 beacon->server_ip = "127.0.0.1"; |
| 32 beacon->was_proxied = false; | 37 beacon->was_proxied = false; |
| 33 beacon->protocol = "HTTP"; | 38 beacon->protocol = "HTTP"; |
| 34 beacon->details.quic_broken = true; | 39 beacon->details.quic_broken = true; |
| 35 beacon->http_response_code = -1; | 40 beacon->http_response_code = -1; |
| 36 beacon->elapsed = base::TimeDelta::FromMilliseconds(250); | 41 beacon->elapsed = base::TimeDelta::FromMilliseconds(250); |
| 37 beacon->start_time = time->NowTicks() - beacon->elapsed; | 42 beacon->start_time = time->NowTicks() - beacon->elapsed; |
| 38 beacon->upload_depth = 0; | 43 beacon->upload_depth = 0; |
| 39 return beacon.Pass(); | 44 return beacon.Pass(); |
| 40 } | 45 } |
| 41 | 46 |
| 47 template <typename ValueType, |
| 48 bool (DictionaryValue::* GetValueType)(const std::string&, |
| 49 ValueType*) const> |
| 50 struct HasValue { |
| 51 bool operator()(const DictionaryValue& dict, |
| 52 const std::string& key, |
| 53 ValueType expected_value) { |
| 54 ValueType actual_value; |
| 55 bool got_value = (dict.*GetValueType)(key, &actual_value); |
| 56 EXPECT_TRUE(got_value); |
| 57 if (got_value) |
| 58 EXPECT_EQ(expected_value, actual_value); |
| 59 return got_value && (expected_value == actual_value); |
| 60 } |
| 61 }; |
| 62 |
| 63 HasValue<std::string, &DictionaryValue::GetString> HasStringValue; |
| 64 HasValue<int, &DictionaryValue::GetInteger> HasIntegerValue; |
| 65 HasValue<bool, &DictionaryValue::GetBoolean> HasBooleanValue; |
| 66 |
| 67 bool GetEntryFromReport(const Value* report, |
| 68 size_t index, |
| 69 const DictionaryValue** entry_out) { |
| 70 const DictionaryValue* report_dict; |
| 71 const ListValue* entries; |
| 72 |
| 73 return report && |
| 74 report->GetAsDictionary(&report_dict) && |
| 75 report_dict->GetList("entries", &entries) && |
| 76 entries->GetDictionary(index, entry_out); |
| 77 } |
| 78 |
| 42 class DomainReliabilityContextTest : public testing::Test { | 79 class DomainReliabilityContextTest : public testing::Test { |
| 43 protected: | 80 protected: |
| 44 DomainReliabilityContextTest() | 81 DomainReliabilityContextTest() |
| 45 : last_network_change_time_(time_.NowTicks()), | 82 : last_network_change_time_(time_.NowTicks()), |
| 46 dispatcher_(&time_), | 83 dispatcher_(&time_), |
| 47 params_(MakeTestSchedulerParams()), | 84 params_(MakeTestSchedulerParams()), |
| 48 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest, | 85 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest, |
| 49 base::Unretained(this))), | 86 base::Unretained(this))), |
| 50 upload_reporter_string_("test-reporter"), | 87 upload_reporter_string_("test-reporter"), |
| 51 context_(&time_, | 88 context_(&time_, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 EXPECT_TRUE(CheckNoBeacons()); | 238 EXPECT_TRUE(CheckNoBeacons()); |
| 202 } | 239 } |
| 203 | 240 |
| 204 TEST_F(DomainReliabilityContextTest, ReportUpload) { | 241 TEST_F(DomainReliabilityContextTest, ReportUpload) { |
| 205 context_.OnBeacon(MakeBeacon(&time_)); | 242 context_.OnBeacon(MakeBeacon(&time_)); |
| 206 | 243 |
| 207 BeaconVector beacons; | 244 BeaconVector beacons; |
| 208 context_.GetQueuedBeaconsForTesting(&beacons); | 245 context_.GetQueuedBeaconsForTesting(&beacons); |
| 209 EXPECT_EQ(1u, beacons.size()); | 246 EXPECT_EQ(1u, beacons.size()); |
| 210 | 247 |
| 211 // N.B.: Assumes max_delay is 5 minutes. | |
| 212 const char* kExpectedReport = "{" | |
| 213 "\"entries\":[" | |
| 214 "{\"failure_data\":{\"custom_error\":\"net::ERR_CONNECTION_RESET\"}," | |
| 215 "\"network_changed\":false,\"protocol\":\"HTTP\"," | |
| 216 "\"quic_broken\":true,\"request_age_ms\":300250," | |
| 217 "\"request_elapsed_ms\":250," | |
| 218 "\"server_ip\":\"127.0.0.1\",\"status\":\"tcp.connection_reset\"," | |
| 219 "\"url\":\"https://localhost/\"," | |
| 220 "\"was_proxied\":false}],\"reporter\":\"test-reporter\"}"; | |
| 221 | |
| 222 time_.Advance(max_delay()); | 248 time_.Advance(max_delay()); |
| 223 EXPECT_TRUE(upload_pending()); | 249 EXPECT_TRUE(upload_pending()); |
| 224 EXPECT_EQ(kExpectedReport, upload_report()); | |
| 225 EXPECT_EQ(0, upload_max_depth()); | 250 EXPECT_EQ(0, upload_max_depth()); |
| 226 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url()); | 251 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url()); |
| 227 | 252 |
| 253 scoped_ptr<Value> value = base::JSONReader::Read(upload_report()); |
| 254 const DictionaryValue* entry; |
| 255 ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); |
| 256 EXPECT_TRUE(HasStringValue(*entry, "failure_data.custom_error", |
| 257 "net::ERR_CONNECTION_RESET")); |
| 258 EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", false)); |
| 259 EXPECT_TRUE(HasStringValue(*entry, "protocol", "HTTP")); |
| 260 EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true)); |
| 261 // N.B.: Assumes max_delay is 5 minutes. |
| 262 EXPECT_TRUE(HasIntegerValue(*entry, "request_age_ms", 300250)); |
| 263 EXPECT_TRUE(HasIntegerValue(*entry, "request_elapsed_ms", 250)); |
| 264 EXPECT_TRUE(HasStringValue(*entry, "server_ip", "127.0.0.1")); |
| 265 EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset")); |
| 266 EXPECT_TRUE(HasStringValue(*entry, "url", "https://localhost/")); |
| 267 EXPECT_TRUE(HasBooleanValue(*entry, "was_proxied", false)); |
| 268 |
| 228 DomainReliabilityUploader::UploadResult result; | 269 DomainReliabilityUploader::UploadResult result; |
| 229 result.status = DomainReliabilityUploader::UploadResult::SUCCESS; | 270 result.status = DomainReliabilityUploader::UploadResult::SUCCESS; |
| 230 CallUploadCallback(result); | 271 CallUploadCallback(result); |
| 231 | 272 |
| 232 EXPECT_TRUE(CheckNoBeacons()); | 273 EXPECT_TRUE(CheckNoBeacons()); |
| 233 } | 274 } |
| 234 | 275 |
| 235 TEST_F(DomainReliabilityContextTest, Upload_NetworkChanged) { | 276 TEST_F(DomainReliabilityContextTest, NetworkChanged) { |
| 236 context_.OnBeacon(MakeBeacon(&time_)); | 277 context_.OnBeacon(MakeBeacon(&time_)); |
| 237 | 278 |
| 238 BeaconVector beacons; | 279 BeaconVector beacons; |
| 239 context_.GetQueuedBeaconsForTesting(&beacons); | 280 context_.GetQueuedBeaconsForTesting(&beacons); |
| 240 EXPECT_EQ(1u, beacons.size()); | 281 EXPECT_EQ(1u, beacons.size()); |
| 241 | 282 |
| 242 // N.B.: Assumes max_delay is 5 minutes. | |
| 243 const char* kExpectedReport = "{" | |
| 244 "\"entries\":[" | |
| 245 "{\"failure_data\":{\"custom_error\":\"net::ERR_CONNECTION_RESET\"}," | |
| 246 "\"network_changed\":true,\"protocol\":\"HTTP\"," | |
| 247 "\"quic_broken\":true,\"request_age_ms\":300250," | |
| 248 "\"request_elapsed_ms\":250," | |
| 249 "\"server_ip\":\"127.0.0.1\",\"status\":\"tcp.connection_reset\"," | |
| 250 "\"url\":\"https://localhost/\"," | |
| 251 "\"was_proxied\":false}],\"reporter\":\"test-reporter\"}"; | |
| 252 | |
| 253 // Simulate a network change after the request but before the upload. | 283 // Simulate a network change after the request but before the upload. |
| 254 last_network_change_time_ = time_.NowTicks(); | 284 last_network_change_time_ = time_.NowTicks(); |
| 255 time_.Advance(max_delay()); | 285 time_.Advance(max_delay()); |
| 256 EXPECT_TRUE(upload_pending()); | 286 EXPECT_TRUE(upload_pending()); |
| 257 EXPECT_EQ(kExpectedReport, upload_report()); | |
| 258 EXPECT_EQ(0, upload_max_depth()); | 287 EXPECT_EQ(0, upload_max_depth()); |
| 259 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url()); | 288 EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url()); |
| 260 | 289 |
| 290 scoped_ptr<Value> value = base::JSONReader::Read(upload_report()); |
| 291 const DictionaryValue* entry; |
| 292 ASSERT_TRUE(GetEntryFromReport(value.get(), 0, &entry)); |
| 293 EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", true)); |
| 294 |
| 261 DomainReliabilityUploader::UploadResult result; | 295 DomainReliabilityUploader::UploadResult result; |
| 262 result.status = DomainReliabilityUploader::UploadResult::SUCCESS; | 296 result.status = DomainReliabilityUploader::UploadResult::SUCCESS; |
| 263 CallUploadCallback(result); | 297 CallUploadCallback(result); |
| 264 | 298 |
| 265 EXPECT_TRUE(CheckNoBeacons()); | 299 EXPECT_TRUE(CheckNoBeacons()); |
| 266 } | 300 } |
| 267 | 301 |
| 268 // TODO(ttuttle): Add beacon_unittest.cc to test serialization. | 302 // TODO(ttuttle): Add beacon_unittest.cc to test serialization. |
| 269 | 303 |
| 270 } // namespace | 304 } // namespace |
| 271 } // namespace domain_reliability | 305 } // namespace domain_reliability |
| OLD | NEW |