| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/url_request/url_request_throttler_manager.h" | 5 #include "net/url_request/url_request_throttler_manager.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/pickle.h" | 9 #include "base/pickle.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/time.h" | 12 #include "base/time.h" |
| 13 #include "net/base/load_flags.h" | 13 #include "net/base/load_flags.h" |
| 14 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
| 15 #include "net/url_request/url_request_context.h" | 15 #include "net/url_request/url_request_context.h" |
| 16 #include "net/url_request/url_request_test_util.h" |
| 16 #include "net/url_request/url_request_throttler_header_interface.h" | 17 #include "net/url_request/url_request_throttler_header_interface.h" |
| 17 #include "net/url_request/url_request_throttler_test_support.h" | 18 #include "net/url_request/url_request_throttler_test_support.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 20 |
| 20 using base::TimeDelta; | 21 using base::TimeDelta; |
| 21 using base::TimeTicks; | 22 using base::TimeTicks; |
| 22 | 23 |
| 23 namespace net { | 24 namespace net { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 101 |
| 101 TimeTicks fake_time_now_; | 102 TimeTicks fake_time_now_; |
| 102 MockBackoffEntry mock_backoff_entry_; | 103 MockBackoffEntry mock_backoff_entry_; |
| 103 | 104 |
| 104 protected: | 105 protected: |
| 105 virtual ~MockURLRequestThrottlerEntry() {} | 106 virtual ~MockURLRequestThrottlerEntry() {} |
| 106 }; | 107 }; |
| 107 | 108 |
| 108 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { | 109 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { |
| 109 public: | 110 public: |
| 110 MockURLRequestThrottlerManager() : create_entry_index_(0) {} | 111 MockURLRequestThrottlerManager() |
| 112 : URLRequestThrottlerManager(&delegate_), |
| 113 create_entry_index_(0) { |
| 114 } |
| 111 | 115 |
| 112 // Method to process the URL using URLRequestThrottlerManager protected | 116 // Method to process the URL using URLRequestThrottlerManager protected |
| 113 // method. | 117 // method. |
| 114 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } | 118 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } |
| 115 | 119 |
| 116 // Method to use the garbage collecting method of URLRequestThrottlerManager. | 120 // Method to use the garbage collecting method of URLRequestThrottlerManager. |
| 117 void DoGarbageCollectEntries() { GarbageCollectEntries(); } | 121 void DoGarbageCollectEntries() { GarbageCollectEntries(); } |
| 118 | 122 |
| 119 // Returns the number of entries in the map. | 123 // Returns the number of entries in the map. |
| 120 int GetNumberOfEntries() const { return GetNumberOfEntriesForTests(); } | 124 int GetNumberOfEntries() const { return GetNumberOfEntriesForTests(); } |
| 121 | 125 |
| 122 void CreateEntry(bool is_outdated) { | 126 void CreateEntry(bool is_outdated) { |
| 123 TimeTicks time = TimeTicks::Now(); | 127 TimeTicks time = TimeTicks::Now(); |
| 124 if (is_outdated) { | 128 if (is_outdated) { |
| 125 time -= TimeDelta::FromMilliseconds( | 129 time -= TimeDelta::FromMilliseconds( |
| 126 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs + 1000); | 130 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs + 1000); |
| 127 } | 131 } |
| 128 std::string fake_url_string("http://www.fakeurl.com/"); | 132 std::string fake_url_string("http://www.fakeurl.com/"); |
| 129 fake_url_string.append(base::IntToString(create_entry_index_++)); | 133 fake_url_string.append(base::IntToString(create_entry_index_++)); |
| 130 GURL fake_url(fake_url_string); | 134 GURL fake_url(fake_url_string); |
| 131 OverrideEntryForTests( | 135 OverrideEntryForTests( |
| 132 fake_url, | 136 fake_url, |
| 133 new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(), | 137 new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(), |
| 134 TimeTicks::Now())); | 138 TimeTicks::Now())); |
| 135 } | 139 } |
| 136 | 140 |
| 137 private: | 141 private: |
| 138 int create_entry_index_; | 142 int create_entry_index_; |
| 143 TestURLRequestThrottlerManagerDelegate delegate_; |
| 139 }; | 144 }; |
| 140 | 145 |
| 141 struct TimeAndBool { | 146 struct TimeAndBool { |
| 142 TimeAndBool(const TimeTicks& time_value, bool expected, int line_num) { | 147 TimeAndBool(const TimeTicks& time_value, bool expected, int line_num) { |
| 143 time = time_value; | 148 time = time_value; |
| 144 result = expected; | 149 result = expected; |
| 145 line = line_num; | 150 line = line_num; |
| 146 } | 151 } |
| 147 TimeTicks time; | 152 TimeTicks time; |
| 148 bool result; | 153 bool result; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 original_samples_.clear(); | 232 original_samples_.clear(); |
| 228 } | 233 } |
| 229 | 234 |
| 230 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { | 235 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { |
| 231 return out << time.ToInternalValue(); | 236 return out << time.ToInternalValue(); |
| 232 } | 237 } |
| 233 | 238 |
| 234 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { | 239 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { |
| 235 entry_->set_exponential_backoff_release_time( | 240 entry_->set_exponential_backoff_release_time( |
| 236 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); | 241 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); |
| 237 EXPECT_TRUE(entry_->ShouldRejectRequest(0)); | 242 EXPECT_TRUE(entry_->ShouldRejectRequest(NULL, 0)); |
| 238 | 243 |
| 239 // Also end-to-end test the load flags exceptions. | 244 // Also end-to-end test the load flags exceptions. |
| 240 EXPECT_FALSE(entry_->ShouldRejectRequest(LOAD_MAYBE_USER_GESTURE)); | 245 EXPECT_FALSE(entry_->ShouldRejectRequest(NULL, LOAD_MAYBE_USER_GESTURE)); |
| 241 | 246 |
| 242 CalculateHistogramDeltas(); | 247 CalculateHistogramDeltas(); |
| 243 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"].counts(0)); | 248 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"].counts(0)); |
| 244 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"].counts(1)); | 249 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"].counts(1)); |
| 245 } | 250 } |
| 246 | 251 |
| 247 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { | 252 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { |
| 248 entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); | 253 entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); |
| 249 EXPECT_FALSE(entry_->ShouldRejectRequest(0)); | 254 EXPECT_FALSE(entry_->ShouldRejectRequest(NULL, 0)); |
| 250 entry_->set_exponential_backoff_release_time( | 255 entry_->set_exponential_backoff_release_time( |
| 251 entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); | 256 entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); |
| 252 EXPECT_FALSE(entry_->ShouldRejectRequest(0)); | 257 EXPECT_FALSE(entry_->ShouldRejectRequest(NULL, 0)); |
| 253 | 258 |
| 254 CalculateHistogramDeltas(); | 259 CalculateHistogramDeltas(); |
| 255 ASSERT_EQ(2, samples_["Throttling.RequestThrottled"].counts(0)); | 260 ASSERT_EQ(2, samples_["Throttling.RequestThrottled"].counts(0)); |
| 256 ASSERT_EQ(0, samples_["Throttling.RequestThrottled"].counts(1)); | 261 ASSERT_EQ(0, samples_["Throttling.RequestThrottled"].counts(1)); |
| 257 } | 262 } |
| 258 | 263 |
| 259 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { | 264 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { |
| 260 MockURLRequestThrottlerHeaderAdapter failure_response(503); | 265 MockURLRequestThrottlerHeaderAdapter failure_response(503); |
| 261 entry_->UpdateWithResponse("", &failure_response); | 266 entry_->UpdateWithResponse("", &failure_response); |
| 262 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 267 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) |
| 263 << "A failure should increase the release_time"; | 268 << "A failure should increase the release_time"; |
| 264 } | 269 } |
| 265 | 270 |
| 266 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { | 271 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { |
| 267 MockURLRequestThrottlerHeaderAdapter success_response(200); | 272 MockURLRequestThrottlerHeaderAdapter success_response(200); |
| 268 entry_->UpdateWithResponse("", &success_response); | 273 entry_->UpdateWithResponse("", &success_response); |
| 269 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 274 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) |
| 270 << "A success should not add any delay"; | 275 << "A success should not add any delay"; |
| 271 } | 276 } |
| 272 | 277 |
| 273 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { | 278 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { |
| 274 MockURLRequestThrottlerHeaderAdapter failure_response(503); | 279 MockURLRequestThrottlerHeaderAdapter failure_response(503); |
| 275 MockURLRequestThrottlerHeaderAdapter success_response(200); | 280 MockURLRequestThrottlerHeaderAdapter success_response(200); |
| 276 entry_->UpdateWithResponse("", &success_response); | 281 entry_->UpdateWithResponse("", &success_response); |
| 277 entry_->UpdateWithResponse("", &failure_response); | 282 entry_->UpdateWithResponse("", &failure_response); |
| 278 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 283 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) |
| 279 << "This scenario should add delay"; | 284 << "This scenario should add delay"; |
| 280 entry_->UpdateWithResponse("", &success_response); | 285 entry_->UpdateWithResponse("", &success_response); |
| 281 | |
| 282 CalculateHistogramDeltas(); | |
| 283 ASSERT_EQ(1, samples_["Throttling.FailureCountAtSuccess"].counts(1)); | |
| 284 ASSERT_EQ(1, samples_["Throttling.PerceivedDowntime"].TotalCount()); | |
| 285 } | 286 } |
| 286 | 287 |
| 287 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { | 288 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { |
| 288 TimeDelta lifetime = TimeDelta::FromMilliseconds( | 289 TimeDelta lifetime = TimeDelta::FromMilliseconds( |
| 289 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); | 290 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); |
| 290 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); | 291 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); |
| 291 | 292 |
| 292 TimeAndBool test_values[] = { | 293 TimeAndBool test_values[] = { |
| 293 TimeAndBool(now_, false, __LINE__), | 294 TimeAndBool(now_, false, __LINE__), |
| 294 TimeAndBool(now_ - kFiveMs, false, __LINE__), | 295 TimeAndBool(now_ - kFiveMs, false, __LINE__), |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0")); | 432 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0")); |
| 432 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0?code=1")); | 433 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0?code=1")); |
| 433 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0#lolsaure")); | 434 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0#lolsaure")); |
| 434 | 435 |
| 435 EXPECT_EQ(3, manager.GetNumberOfEntries()); | 436 EXPECT_EQ(3, manager.GetNumberOfEntries()); |
| 436 } | 437 } |
| 437 | 438 |
| 438 void ExpectEntryAllowsAllOnErrorIfOptedOut( | 439 void ExpectEntryAllowsAllOnErrorIfOptedOut( |
| 439 net::URLRequestThrottlerEntryInterface* entry, | 440 net::URLRequestThrottlerEntryInterface* entry, |
| 440 bool opted_out) { | 441 bool opted_out) { |
| 441 EXPECT_FALSE(entry->ShouldRejectRequest(0)); | 442 EXPECT_FALSE(entry->ShouldRejectRequest(NULL, 0)); |
| 442 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); | 443 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); |
| 443 for (int i = 0; i < 10; ++i) { | 444 for (int i = 0; i < 10; ++i) { |
| 444 // Host doesn't really matter in this scenario so we skip it. | 445 // Host doesn't really matter in this scenario so we skip it. |
| 445 entry->UpdateWithResponse("", &failure_adapter); | 446 entry->UpdateWithResponse("", &failure_adapter); |
| 446 } | 447 } |
| 447 EXPECT_NE(opted_out, entry->ShouldRejectRequest(0)); | 448 EXPECT_NE(opted_out, entry->ShouldRejectRequest(NULL, 0)); |
| 448 | 449 |
| 449 if (opted_out) { | 450 if (opted_out) { |
| 450 // We're not mocking out GetTimeNow() in this scenario | 451 // We're not mocking out GetTimeNow() in this scenario |
| 451 // so add a 100 ms buffer to avoid flakiness (that should always | 452 // so add a 100 ms buffer to avoid flakiness (that should always |
| 452 // give enough time to get from the TimeTicks::Now() call here | 453 // give enough time to get from the TimeTicks::Now() call here |
| 453 // to the TimeTicks::Now() call in the entry class). | 454 // to the TimeTicks::Now() call in the entry class). |
| 454 EXPECT_GT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), | 455 EXPECT_GT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), |
| 455 entry->GetExponentialBackoffReleaseTime()); | 456 entry->GetExponentialBackoffReleaseTime()); |
| 456 } else { | 457 } else { |
| 457 // As above, add 100 ms. | 458 // As above, add 100 ms. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 TEST(URLRequestThrottlerManager, ClearOnNetworkChange) { | 498 TEST(URLRequestThrottlerManager, ClearOnNetworkChange) { |
| 498 for (int i = 0; i < 3; ++i) { | 499 for (int i = 0; i < 3; ++i) { |
| 499 MockURLRequestThrottlerManager manager; | 500 MockURLRequestThrottlerManager manager; |
| 500 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_before = | 501 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_before = |
| 501 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | 502 manager.RegisterRequestUrl(GURL("http://www.example.com/")); |
| 502 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); | 503 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); |
| 503 for (int j = 0; j < 10; ++j) { | 504 for (int j = 0; j < 10; ++j) { |
| 504 // Host doesn't really matter in this scenario so we skip it. | 505 // Host doesn't really matter in this scenario so we skip it. |
| 505 entry_before->UpdateWithResponse("", &failure_adapter); | 506 entry_before->UpdateWithResponse("", &failure_adapter); |
| 506 } | 507 } |
| 507 EXPECT_TRUE(entry_before->ShouldRejectRequest(0)); | 508 EXPECT_TRUE(entry_before->ShouldRejectRequest(NULL, 0)); |
| 508 | 509 |
| 509 switch (i) { | 510 switch (i) { |
| 510 case 0: | 511 case 0: |
| 511 manager.OnIPAddressChanged(); | 512 manager.OnIPAddressChanged(); |
| 512 break; | 513 break; |
| 513 case 1: | 514 case 1: |
| 514 manager.OnConnectionTypeChanged( | 515 manager.OnConnectionTypeChanged( |
| 515 net::NetworkChangeNotifier::CONNECTION_UNKNOWN); | 516 net::NetworkChangeNotifier::CONNECTION_UNKNOWN); |
| 516 break; | 517 break; |
| 517 case 2: | 518 case 2: |
| 518 manager.OnConnectionTypeChanged( | 519 manager.OnConnectionTypeChanged( |
| 519 net::NetworkChangeNotifier::CONNECTION_NONE); | 520 net::NetworkChangeNotifier::CONNECTION_NONE); |
| 520 break; | 521 break; |
| 521 default: | 522 default: |
| 522 FAIL(); | 523 FAIL(); |
| 523 } | 524 } |
| 524 | 525 |
| 525 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_after = | 526 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_after = |
| 526 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | 527 manager.RegisterRequestUrl(GURL("http://www.example.com/")); |
| 527 EXPECT_FALSE(entry_after->ShouldRejectRequest(0)); | 528 EXPECT_FALSE(entry_after->ShouldRejectRequest(NULL, 0)); |
| 528 } | 529 } |
| 529 } | 530 } |
| 530 | 531 |
| 531 } // namespace net | 532 } // namespace net |
| OLD | NEW |