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_samples.h" | 8 #include "base/metrics/histogram_samples.h" |
9 #include "base/pickle.h" | 9 #include "base/pickle.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 const char kRequestThrottledHistogramName[] = "Throttling.RequestThrottled"; | 32 const char kRequestThrottledHistogramName[] = "Throttling.RequestThrottled"; |
33 | 33 |
34 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { | 34 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { |
35 public: | 35 public: |
36 explicit MockURLRequestThrottlerEntry( | 36 explicit MockURLRequestThrottlerEntry( |
37 URLRequestThrottlerManager* manager) | 37 URLRequestThrottlerManager* manager) |
38 : URLRequestThrottlerEntry(manager, std::string()), | 38 : URLRequestThrottlerEntry(manager, std::string()), |
39 mock_backoff_entry_(&backoff_policy_) { | 39 backoff_entry_(&backoff_policy_, &fake_clock_) { |
40 InitPolicy(); | 40 InitPolicy(); |
41 } | 41 } |
42 MockURLRequestThrottlerEntry( | 42 MockURLRequestThrottlerEntry( |
43 URLRequestThrottlerManager* manager, | 43 URLRequestThrottlerManager* manager, |
44 const TimeTicks& exponential_backoff_release_time, | 44 const TimeTicks& exponential_backoff_release_time, |
45 const TimeTicks& sliding_window_release_time, | 45 const TimeTicks& sliding_window_release_time, |
46 const TimeTicks& fake_now) | 46 const TimeTicks& fake_now) |
47 : URLRequestThrottlerEntry(manager, std::string()), | 47 : URLRequestThrottlerEntry(manager, std::string()), |
48 fake_time_now_(fake_now), | 48 fake_clock_(fake_now), |
49 mock_backoff_entry_(&backoff_policy_) { | 49 backoff_entry_(&backoff_policy_, &fake_clock_) { |
50 InitPolicy(); | 50 InitPolicy(); |
51 | 51 |
52 mock_backoff_entry_.set_fake_now(fake_now); | |
53 set_exponential_backoff_release_time(exponential_backoff_release_time); | 52 set_exponential_backoff_release_time(exponential_backoff_release_time); |
54 set_sliding_window_release_time(sliding_window_release_time); | 53 set_sliding_window_release_time(sliding_window_release_time); |
55 } | 54 } |
56 | 55 |
57 void InitPolicy() { | 56 void InitPolicy() { |
58 // Some tests become flaky if we have jitter. | 57 // Some tests become flaky if we have jitter. |
59 backoff_policy_.jitter_factor = 0.0; | 58 backoff_policy_.jitter_factor = 0.0; |
60 | 59 |
61 // This lets us avoid having to make multiple failures initially (this | 60 // This lets us avoid having to make multiple failures initially (this |
62 // logic is already tested in the BackoffEntry unit tests). | 61 // logic is already tested in the BackoffEntry unit tests). |
63 backoff_policy_.num_errors_to_ignore = 0; | 62 backoff_policy_.num_errors_to_ignore = 0; |
64 } | 63 } |
65 | 64 |
66 const BackoffEntry* GetBackoffEntry() const override { | 65 const BackoffEntry* GetBackoffEntry() const override { |
67 return &mock_backoff_entry_; | 66 return &backoff_entry_; |
68 } | 67 } |
69 | 68 |
70 BackoffEntry* GetBackoffEntry() override { return &mock_backoff_entry_; } | 69 BackoffEntry* GetBackoffEntry() override { return &backoff_entry_; } |
71 | 70 |
72 static bool ExplicitUserRequest(int load_flags) { | 71 static bool ExplicitUserRequest(int load_flags) { |
73 return URLRequestThrottlerEntry::ExplicitUserRequest(load_flags); | 72 return URLRequestThrottlerEntry::ExplicitUserRequest(load_flags); |
74 } | 73 } |
75 | 74 |
76 void ResetToBlank(const TimeTicks& time_now) { | 75 void ResetToBlank(const TimeTicks& time_now) { |
77 fake_time_now_ = time_now; | 76 fake_clock_.set_now(time_now); |
78 mock_backoff_entry_.set_fake_now(time_now); | |
79 | 77 |
80 GetBackoffEntry()->Reset(); | 78 GetBackoffEntry()->Reset(); |
81 GetBackoffEntry()->SetCustomReleaseTime(time_now); | |
82 set_sliding_window_release_time(time_now); | 79 set_sliding_window_release_time(time_now); |
83 } | 80 } |
84 | 81 |
85 // Overridden for tests. | 82 // Overridden for tests. |
86 TimeTicks ImplGetTimeNow() const override { return fake_time_now_; } | 83 TimeTicks ImplGetTimeNow() const override { return fake_clock_.NowTicks(); } |
87 | 84 |
88 void set_exponential_backoff_release_time( | 85 void set_fake_now(const TimeTicks& now) { fake_clock_.set_now(now); } |
89 const base::TimeTicks& release_time) { | 86 |
| 87 void set_exponential_backoff_release_time(const TimeTicks& release_time) { |
90 GetBackoffEntry()->SetCustomReleaseTime(release_time); | 88 GetBackoffEntry()->SetCustomReleaseTime(release_time); |
91 } | 89 } |
92 | 90 |
93 base::TimeTicks sliding_window_release_time() const { | 91 TimeTicks sliding_window_release_time() const { |
94 return URLRequestThrottlerEntry::sliding_window_release_time(); | 92 return URLRequestThrottlerEntry::sliding_window_release_time(); |
95 } | 93 } |
96 | 94 |
97 void set_sliding_window_release_time( | 95 void set_sliding_window_release_time(const TimeTicks& release_time) { |
98 const base::TimeTicks& release_time) { | 96 URLRequestThrottlerEntry::set_sliding_window_release_time(release_time); |
99 URLRequestThrottlerEntry::set_sliding_window_release_time( | |
100 release_time); | |
101 } | 97 } |
102 | 98 |
103 TimeTicks fake_time_now_; | |
104 MockBackoffEntry mock_backoff_entry_; | |
105 | |
106 protected: | 99 protected: |
107 ~MockURLRequestThrottlerEntry() override {} | 100 ~MockURLRequestThrottlerEntry() override {} |
| 101 |
| 102 private: |
| 103 mutable TestTickClock fake_clock_; |
| 104 BackoffEntry backoff_entry_; |
108 }; | 105 }; |
109 | 106 |
110 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { | 107 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { |
111 public: | 108 public: |
112 MockURLRequestThrottlerManager() : create_entry_index_(0) {} | 109 MockURLRequestThrottlerManager() : create_entry_index_(0) {} |
113 | 110 |
114 // Method to process the URL using URLRequestThrottlerManager protected | 111 // Method to process the URL using URLRequestThrottlerManager protected |
115 // method. | 112 // method. |
116 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } | 113 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } |
117 | 114 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } | 187 } |
191 | 188 |
192 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { | 189 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { |
193 return out << time.ToInternalValue(); | 190 return out << time.ToInternalValue(); |
194 } | 191 } |
195 | 192 |
196 TEST_F(URLRequestThrottlerEntryTest, CanThrottleRequest) { | 193 TEST_F(URLRequestThrottlerEntryTest, CanThrottleRequest) { |
197 TestNetworkDelegate d; | 194 TestNetworkDelegate d; |
198 context_.set_network_delegate(&d); | 195 context_.set_network_delegate(&d); |
199 entry_->set_exponential_backoff_release_time( | 196 entry_->set_exponential_backoff_release_time( |
200 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); | 197 entry_->ImplGetTimeNow() + TimeDelta::FromMilliseconds(1)); |
201 | 198 |
202 d.set_can_throttle_requests(false); | 199 d.set_can_throttle_requests(false); |
203 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | 200 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, |
204 context_.network_delegate())); | 201 context_.network_delegate())); |
205 d.set_can_throttle_requests(true); | 202 d.set_can_throttle_requests(true); |
206 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, | 203 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, |
207 context_.network_delegate())); | 204 context_.network_delegate())); |
208 } | 205 } |
209 | 206 |
210 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { | 207 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { |
211 base::HistogramTester histogram_tester; | 208 base::HistogramTester histogram_tester; |
212 entry_->set_exponential_backoff_release_time( | 209 entry_->set_exponential_backoff_release_time( |
213 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); | 210 entry_->ImplGetTimeNow() + TimeDelta::FromMilliseconds(1)); |
214 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, | 211 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, |
215 context_.network_delegate())); | 212 context_.network_delegate())); |
216 | 213 |
217 // Also end-to-end test the load flags exceptions. | 214 // Also end-to-end test the load flags exceptions. |
218 request_->SetLoadFlags(LOAD_MAYBE_USER_GESTURE); | 215 request_->SetLoadFlags(LOAD_MAYBE_USER_GESTURE); |
219 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | 216 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, |
220 context_.network_delegate())); | 217 context_.network_delegate())); |
221 | 218 |
222 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 1); | 219 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 1); |
223 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 1); | 220 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 1); |
224 } | 221 } |
225 | 222 |
226 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { | 223 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { |
227 base::HistogramTester histogram_tester; | 224 base::HistogramTester histogram_tester; |
228 entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); | 225 entry_->set_exponential_backoff_release_time(entry_->ImplGetTimeNow()); |
229 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | 226 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, |
230 context_.network_delegate())); | 227 context_.network_delegate())); |
231 entry_->set_exponential_backoff_release_time( | 228 entry_->set_exponential_backoff_release_time( |
232 entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); | 229 entry_->ImplGetTimeNow() - TimeDelta::FromMilliseconds(1)); |
233 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | 230 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, |
234 context_.network_delegate())); | 231 context_.network_delegate())); |
235 | 232 |
236 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 2); | 233 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 2); |
237 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 0); | 234 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 0); |
238 } | 235 } |
239 | 236 |
240 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { | 237 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { |
241 MockURLRequestThrottlerHeaderAdapter failure_response(503); | 238 MockURLRequestThrottlerHeaderAdapter failure_response(503); |
242 entry_->UpdateWithResponse(std::string(), &failure_response); | 239 entry_->UpdateWithResponse(std::string(), &failure_response); |
243 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 240 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), |
| 241 entry_->ImplGetTimeNow()) |
244 << "A failure should increase the release_time"; | 242 << "A failure should increase the release_time"; |
245 } | 243 } |
246 | 244 |
247 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { | 245 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { |
248 MockURLRequestThrottlerHeaderAdapter success_response(200); | 246 MockURLRequestThrottlerHeaderAdapter success_response(200); |
249 entry_->UpdateWithResponse(std::string(), &success_response); | 247 entry_->UpdateWithResponse(std::string(), &success_response); |
250 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 248 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), |
| 249 entry_->ImplGetTimeNow()) |
251 << "A success should not add any delay"; | 250 << "A success should not add any delay"; |
252 } | 251 } |
253 | 252 |
254 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { | 253 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { |
255 MockURLRequestThrottlerHeaderAdapter failure_response(503); | 254 MockURLRequestThrottlerHeaderAdapter failure_response(503); |
256 MockURLRequestThrottlerHeaderAdapter success_response(200); | 255 MockURLRequestThrottlerHeaderAdapter success_response(200); |
257 entry_->UpdateWithResponse(std::string(), &success_response); | 256 entry_->UpdateWithResponse(std::string(), &success_response); |
258 entry_->UpdateWithResponse(std::string(), &failure_response); | 257 entry_->UpdateWithResponse(std::string(), &failure_response); |
259 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | 258 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), |
| 259 entry_->ImplGetTimeNow()) |
260 << "This scenario should add delay"; | 260 << "This scenario should add delay"; |
261 entry_->UpdateWithResponse(std::string(), &success_response); | 261 entry_->UpdateWithResponse(std::string(), &success_response); |
262 } | 262 } |
263 | 263 |
264 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { | 264 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { |
265 TimeDelta lifetime = TimeDelta::FromMilliseconds( | 265 TimeDelta lifetime = TimeDelta::FromMilliseconds( |
266 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); | 266 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); |
267 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); | 267 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); |
268 | 268 |
269 TimeAndBool test_values[] = { | 269 TimeAndBool test_values[] = { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 MockURLRequestThrottlerHeaderAdapter success_adapter(200); | 308 MockURLRequestThrottlerHeaderAdapter success_adapter(200); |
309 entry_->UpdateWithResponse(std::string(), &success_adapter); | 309 entry_->UpdateWithResponse(std::string(), &success_adapter); |
310 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), release_after_failures); | 310 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), release_after_failures); |
311 } | 311 } |
312 | 312 |
313 TEST_F(URLRequestThrottlerEntryTest, SlidingWindow) { | 313 TEST_F(URLRequestThrottlerEntryTest, SlidingWindow) { |
314 int max_send = URLRequestThrottlerEntry::kDefaultMaxSendThreshold; | 314 int max_send = URLRequestThrottlerEntry::kDefaultMaxSendThreshold; |
315 int sliding_window = | 315 int sliding_window = |
316 URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs; | 316 URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs; |
317 | 317 |
318 TimeTicks time_1 = entry_->fake_time_now_ + | 318 TimeTicks time_1 = entry_->ImplGetTimeNow() + |
319 TimeDelta::FromMilliseconds(sliding_window / 3); | 319 TimeDelta::FromMilliseconds(sliding_window / 3); |
320 TimeTicks time_2 = entry_->fake_time_now_ + | 320 TimeTicks time_2 = entry_->ImplGetTimeNow() + |
321 TimeDelta::FromMilliseconds(2 * sliding_window / 3); | 321 TimeDelta::FromMilliseconds(2 * sliding_window / 3); |
322 TimeTicks time_3 = entry_->fake_time_now_ + | 322 TimeTicks time_3 = entry_->ImplGetTimeNow() + |
323 TimeDelta::FromMilliseconds(sliding_window); | 323 TimeDelta::FromMilliseconds(sliding_window); |
324 TimeTicks time_4 = entry_->fake_time_now_ + | 324 TimeTicks time_4 = entry_->ImplGetTimeNow() + |
325 TimeDelta::FromMilliseconds(sliding_window + 2 * sliding_window / 3); | 325 TimeDelta::FromMilliseconds(sliding_window + 2 * sliding_window / 3); |
326 | 326 |
327 entry_->set_exponential_backoff_release_time(time_1); | 327 entry_->set_exponential_backoff_release_time(time_1); |
328 | 328 |
329 for (int i = 0; i < max_send / 2; ++i) { | 329 for (int i = 0; i < max_send / 2; ++i) { |
330 EXPECT_EQ(2 * sliding_window / 3, | 330 EXPECT_EQ(2 * sliding_window / 3, |
331 entry_->ReserveSendingTimeForNextRequest(time_2)); | 331 entry_->ReserveSendingTimeForNextRequest(time_2)); |
332 } | 332 } |
333 EXPECT_EQ(time_2, entry_->sliding_window_release_time()); | 333 EXPECT_EQ(time_2, entry_->sliding_window_release_time()); |
334 | 334 |
335 entry_->fake_time_now_ = time_3; | 335 entry_->set_fake_now(time_3); |
336 | 336 |
337 for (int i = 0; i < (max_send + 1) / 2; ++i) | 337 for (int i = 0; i < (max_send + 1) / 2; ++i) |
338 EXPECT_EQ(0, entry_->ReserveSendingTimeForNextRequest(TimeTicks())); | 338 EXPECT_EQ(0, entry_->ReserveSendingTimeForNextRequest(TimeTicks())); |
339 | 339 |
340 EXPECT_EQ(time_4, entry_->sliding_window_release_time()); | 340 EXPECT_EQ(time_4, entry_->sliding_window_release_time()); |
341 } | 341 } |
342 | 342 |
343 TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) { | 343 TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) { |
344 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(0)); | 344 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(0)); |
345 ASSERT_TRUE(MockURLRequestThrottlerEntry::ExplicitUserRequest( | 345 ASSERT_TRUE(MockURLRequestThrottlerEntry::ExplicitUserRequest( |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 } | 517 } |
518 | 518 |
519 scoped_refptr<URLRequestThrottlerEntryInterface> entry_after = | 519 scoped_refptr<URLRequestThrottlerEntryInterface> entry_after = |
520 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | 520 manager.RegisterRequestUrl(GURL("http://www.example.com/")); |
521 EXPECT_FALSE(entry_after->ShouldRejectRequest( | 521 EXPECT_FALSE(entry_after->ShouldRejectRequest( |
522 *request_, context_.network_delegate())); | 522 *request_, context_.network_delegate())); |
523 } | 523 } |
524 } | 524 } |
525 | 525 |
526 } // namespace net | 526 } // namespace net |
OLD | NEW |