OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/url_request/url_request_throttler_manager.h" | |
6 | |
7 #include "base/memory/scoped_ptr.h" | |
8 #include "base/metrics/histogram_samples.h" | |
9 #include "base/pickle.h" | |
10 #include "base/stl_util.h" | |
11 #include "base/strings/string_number_conversions.h" | |
12 #include "base/strings/stringprintf.h" | |
13 #include "base/test/histogram_tester.h" | |
14 #include "base/time/time.h" | |
15 #include "net/base/load_flags.h" | |
16 #include "net/base/request_priority.h" | |
17 #include "net/base/test_completion_callback.h" | |
18 #include "net/url_request/url_request.h" | |
19 #include "net/url_request/url_request_context.h" | |
20 #include "net/url_request/url_request_test_util.h" | |
21 #include "net/url_request/url_request_throttler_header_interface.h" | |
22 #include "net/url_request/url_request_throttler_test_support.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 | |
25 using base::TimeDelta; | |
26 using base::TimeTicks; | |
27 | |
28 namespace net { | |
29 | |
30 namespace { | |
31 | |
32 const char kRequestThrottledHistogramName[] = "Throttling.RequestThrottled"; | |
33 | |
34 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { | |
35 public: | |
36 explicit MockURLRequestThrottlerEntry( | |
37 URLRequestThrottlerManager* manager) | |
38 : URLRequestThrottlerEntry(manager, std::string()), | |
39 mock_backoff_entry_(&backoff_policy_) { | |
40 InitPolicy(); | |
41 } | |
42 MockURLRequestThrottlerEntry( | |
43 URLRequestThrottlerManager* manager, | |
44 const TimeTicks& exponential_backoff_release_time, | |
45 const TimeTicks& sliding_window_release_time, | |
46 const TimeTicks& fake_now) | |
47 : URLRequestThrottlerEntry(manager, std::string()), | |
48 fake_time_now_(fake_now), | |
49 mock_backoff_entry_(&backoff_policy_) { | |
50 InitPolicy(); | |
51 | |
52 mock_backoff_entry_.set_fake_now(fake_now); | |
53 set_exponential_backoff_release_time(exponential_backoff_release_time); | |
54 set_sliding_window_release_time(sliding_window_release_time); | |
55 } | |
56 | |
57 void InitPolicy() { | |
58 // Some tests become flaky if we have jitter. | |
59 backoff_policy_.jitter_factor = 0.0; | |
60 | |
61 // This lets us avoid having to make multiple failures initially (this | |
62 // logic is already tested in the BackoffEntry unit tests). | |
63 backoff_policy_.num_errors_to_ignore = 0; | |
64 } | |
65 | |
66 const BackoffEntry* GetBackoffEntry() const override { | |
67 return &mock_backoff_entry_; | |
68 } | |
69 | |
70 BackoffEntry* GetBackoffEntry() override { return &mock_backoff_entry_; } | |
71 | |
72 static bool ExplicitUserRequest(int load_flags) { | |
73 return URLRequestThrottlerEntry::ExplicitUserRequest(load_flags); | |
74 } | |
75 | |
76 void ResetToBlank(const TimeTicks& time_now) { | |
77 fake_time_now_ = time_now; | |
78 mock_backoff_entry_.set_fake_now(time_now); | |
79 | |
80 GetBackoffEntry()->Reset(); | |
81 GetBackoffEntry()->SetCustomReleaseTime(time_now); | |
82 set_sliding_window_release_time(time_now); | |
83 } | |
84 | |
85 // Overridden for tests. | |
86 TimeTicks ImplGetTimeNow() const override { return fake_time_now_; } | |
87 | |
88 void set_exponential_backoff_release_time( | |
89 const base::TimeTicks& release_time) { | |
90 GetBackoffEntry()->SetCustomReleaseTime(release_time); | |
91 } | |
92 | |
93 base::TimeTicks sliding_window_release_time() const { | |
94 return URLRequestThrottlerEntry::sliding_window_release_time(); | |
95 } | |
96 | |
97 void set_sliding_window_release_time( | |
98 const base::TimeTicks& release_time) { | |
99 URLRequestThrottlerEntry::set_sliding_window_release_time( | |
100 release_time); | |
101 } | |
102 | |
103 TimeTicks fake_time_now_; | |
104 MockBackoffEntry mock_backoff_entry_; | |
105 | |
106 protected: | |
107 ~MockURLRequestThrottlerEntry() override {} | |
108 }; | |
109 | |
110 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { | |
111 public: | |
112 MockURLRequestThrottlerManager() : create_entry_index_(0) {} | |
113 | |
114 // Method to process the URL using URLRequestThrottlerManager protected | |
115 // method. | |
116 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } | |
117 | |
118 // Method to use the garbage collecting method of URLRequestThrottlerManager. | |
119 void DoGarbageCollectEntries() { GarbageCollectEntries(); } | |
120 | |
121 // Returns the number of entries in the map. | |
122 int GetNumberOfEntries() const { return GetNumberOfEntriesForTests(); } | |
123 | |
124 void CreateEntry(bool is_outdated) { | |
125 TimeTicks time = TimeTicks::Now(); | |
126 if (is_outdated) { | |
127 time -= TimeDelta::FromMilliseconds( | |
128 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs + 1000); | |
129 } | |
130 std::string fake_url_string("http://www.fakeurl.com/"); | |
131 fake_url_string.append(base::IntToString(create_entry_index_++)); | |
132 GURL fake_url(fake_url_string); | |
133 OverrideEntryForTests( | |
134 fake_url, | |
135 new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(), | |
136 TimeTicks::Now())); | |
137 } | |
138 | |
139 private: | |
140 int create_entry_index_; | |
141 }; | |
142 | |
143 struct TimeAndBool { | |
144 TimeAndBool(const TimeTicks& time_value, bool expected, int line_num) { | |
145 time = time_value; | |
146 result = expected; | |
147 line = line_num; | |
148 } | |
149 TimeTicks time; | |
150 bool result; | |
151 int line; | |
152 }; | |
153 | |
154 struct GurlAndString { | |
155 GurlAndString(const GURL& url_value, | |
156 const std::string& expected, | |
157 int line_num) { | |
158 url = url_value; | |
159 result = expected; | |
160 line = line_num; | |
161 } | |
162 GURL url; | |
163 std::string result; | |
164 int line; | |
165 }; | |
166 | |
167 } // namespace | |
168 | |
169 class URLRequestThrottlerEntryTest : public testing::Test { | |
170 protected: | |
171 URLRequestThrottlerEntryTest() | |
172 : request_(context_.CreateRequest(GURL(), DEFAULT_PRIORITY, NULL, NULL)) { | |
173 } | |
174 | |
175 void SetUp() override; | |
176 | |
177 TimeTicks now_; | |
178 MockURLRequestThrottlerManager manager_; // Dummy object, not used. | |
179 scoped_refptr<MockURLRequestThrottlerEntry> entry_; | |
180 | |
181 TestURLRequestContext context_; | |
182 scoped_ptr<URLRequest> request_; | |
183 }; | |
184 | |
185 void URLRequestThrottlerEntryTest::SetUp() { | |
186 request_->SetLoadFlags(0); | |
187 | |
188 now_ = TimeTicks::Now(); | |
189 entry_ = new MockURLRequestThrottlerEntry(&manager_); | |
190 entry_->ResetToBlank(now_); | |
191 } | |
192 | |
193 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { | |
194 return out << time.ToInternalValue(); | |
195 } | |
196 | |
197 TEST_F(URLRequestThrottlerEntryTest, CanThrottleRequest) { | |
198 TestNetworkDelegate d; | |
199 context_.set_network_delegate(&d); | |
200 entry_->set_exponential_backoff_release_time( | |
201 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); | |
202 | |
203 d.set_can_throttle_requests(false); | |
204 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | |
205 context_.network_delegate())); | |
206 d.set_can_throttle_requests(true); | |
207 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, | |
208 context_.network_delegate())); | |
209 } | |
210 | |
211 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { | |
212 base::HistogramTester histogram_tester; | |
213 entry_->set_exponential_backoff_release_time( | |
214 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); | |
215 EXPECT_TRUE(entry_->ShouldRejectRequest(*request_, | |
216 context_.network_delegate())); | |
217 | |
218 // Also end-to-end test the load flags exceptions. | |
219 request_->SetLoadFlags(LOAD_MAYBE_USER_GESTURE); | |
220 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | |
221 context_.network_delegate())); | |
222 | |
223 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 1); | |
224 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 1); | |
225 } | |
226 | |
227 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { | |
228 base::HistogramTester histogram_tester; | |
229 entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); | |
230 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | |
231 context_.network_delegate())); | |
232 entry_->set_exponential_backoff_release_time( | |
233 entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); | |
234 EXPECT_FALSE(entry_->ShouldRejectRequest(*request_, | |
235 context_.network_delegate())); | |
236 | |
237 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 0, 2); | |
238 histogram_tester.ExpectBucketCount(kRequestThrottledHistogramName, 1, 0); | |
239 } | |
240 | |
241 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { | |
242 MockURLRequestThrottlerHeaderAdapter failure_response(503); | |
243 entry_->UpdateWithResponse(std::string(), &failure_response); | |
244 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | |
245 << "A failure should increase the release_time"; | |
246 } | |
247 | |
248 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { | |
249 MockURLRequestThrottlerHeaderAdapter success_response(200); | |
250 entry_->UpdateWithResponse(std::string(), &success_response); | |
251 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | |
252 << "A success should not add any delay"; | |
253 } | |
254 | |
255 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { | |
256 MockURLRequestThrottlerHeaderAdapter failure_response(503); | |
257 MockURLRequestThrottlerHeaderAdapter success_response(200); | |
258 entry_->UpdateWithResponse(std::string(), &success_response); | |
259 entry_->UpdateWithResponse(std::string(), &failure_response); | |
260 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) | |
261 << "This scenario should add delay"; | |
262 entry_->UpdateWithResponse(std::string(), &success_response); | |
263 } | |
264 | |
265 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { | |
266 TimeDelta lifetime = TimeDelta::FromMilliseconds( | |
267 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); | |
268 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); | |
269 | |
270 TimeAndBool test_values[] = { | |
271 TimeAndBool(now_, false, __LINE__), | |
272 TimeAndBool(now_ - kFiveMs, false, __LINE__), | |
273 TimeAndBool(now_ + kFiveMs, false, __LINE__), | |
274 TimeAndBool(now_ - (lifetime - kFiveMs), false, __LINE__), | |
275 TimeAndBool(now_ - lifetime, true, __LINE__), | |
276 TimeAndBool(now_ - (lifetime + kFiveMs), true, __LINE__)}; | |
277 | |
278 for (unsigned int i = 0; i < arraysize(test_values); ++i) { | |
279 entry_->set_exponential_backoff_release_time(test_values[i].time); | |
280 EXPECT_EQ(entry_->IsEntryOutdated(), test_values[i].result) << | |
281 "Test case #" << i << " line " << test_values[i].line << " failed"; | |
282 } | |
283 } | |
284 | |
285 TEST_F(URLRequestThrottlerEntryTest, MaxAllowedBackoff) { | |
286 for (int i = 0; i < 30; ++i) { | |
287 MockURLRequestThrottlerHeaderAdapter response_adapter(503); | |
288 entry_->UpdateWithResponse(std::string(), &response_adapter); | |
289 } | |
290 | |
291 TimeDelta delay = entry_->GetExponentialBackoffReleaseTime() - now_; | |
292 EXPECT_EQ(delay.InMilliseconds(), | |
293 MockURLRequestThrottlerEntry::kDefaultMaximumBackoffMs); | |
294 } | |
295 | |
296 TEST_F(URLRequestThrottlerEntryTest, MalformedContent) { | |
297 MockURLRequestThrottlerHeaderAdapter response_adapter(503); | |
298 for (int i = 0; i < 5; ++i) | |
299 entry_->UpdateWithResponse(std::string(), &response_adapter); | |
300 | |
301 TimeTicks release_after_failures = entry_->GetExponentialBackoffReleaseTime(); | |
302 | |
303 // Inform the entry that a response body was malformed, which is supposed to | |
304 // increase the back-off time. Note that we also submit a successful | |
305 // UpdateWithResponse to pair with ReceivedContentWasMalformed() since that | |
306 // is what happens in practice (if a body is received, then a non-500 | |
307 // response must also have been received). | |
308 entry_->ReceivedContentWasMalformed(200); | |
309 MockURLRequestThrottlerHeaderAdapter success_adapter(200); | |
310 entry_->UpdateWithResponse(std::string(), &success_adapter); | |
311 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), release_after_failures); | |
312 } | |
313 | |
314 TEST_F(URLRequestThrottlerEntryTest, SlidingWindow) { | |
315 int max_send = URLRequestThrottlerEntry::kDefaultMaxSendThreshold; | |
316 int sliding_window = | |
317 URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs; | |
318 | |
319 TimeTicks time_1 = entry_->fake_time_now_ + | |
320 TimeDelta::FromMilliseconds(sliding_window / 3); | |
321 TimeTicks time_2 = entry_->fake_time_now_ + | |
322 TimeDelta::FromMilliseconds(2 * sliding_window / 3); | |
323 TimeTicks time_3 = entry_->fake_time_now_ + | |
324 TimeDelta::FromMilliseconds(sliding_window); | |
325 TimeTicks time_4 = entry_->fake_time_now_ + | |
326 TimeDelta::FromMilliseconds(sliding_window + 2 * sliding_window / 3); | |
327 | |
328 entry_->set_exponential_backoff_release_time(time_1); | |
329 | |
330 for (int i = 0; i < max_send / 2; ++i) { | |
331 EXPECT_EQ(2 * sliding_window / 3, | |
332 entry_->ReserveSendingTimeForNextRequest(time_2)); | |
333 } | |
334 EXPECT_EQ(time_2, entry_->sliding_window_release_time()); | |
335 | |
336 entry_->fake_time_now_ = time_3; | |
337 | |
338 for (int i = 0; i < (max_send + 1) / 2; ++i) | |
339 EXPECT_EQ(0, entry_->ReserveSendingTimeForNextRequest(TimeTicks())); | |
340 | |
341 EXPECT_EQ(time_4, entry_->sliding_window_release_time()); | |
342 } | |
343 | |
344 TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) { | |
345 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(0)); | |
346 ASSERT_TRUE(MockURLRequestThrottlerEntry::ExplicitUserRequest( | |
347 LOAD_MAYBE_USER_GESTURE)); | |
348 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest( | |
349 ~LOAD_MAYBE_USER_GESTURE)); | |
350 } | |
351 | |
352 class URLRequestThrottlerManagerTest : public testing::Test { | |
353 protected: | |
354 URLRequestThrottlerManagerTest() | |
355 : request_(context_.CreateRequest(GURL(), DEFAULT_PRIORITY, NULL, NULL)) { | |
356 } | |
357 | |
358 void SetUp() override { request_->SetLoadFlags(0); } | |
359 | |
360 void ExpectEntryAllowsAllOnErrorIfOptedOut( | |
361 URLRequestThrottlerEntryInterface* entry, | |
362 bool opted_out, | |
363 const URLRequest& request) { | |
364 EXPECT_FALSE(entry->ShouldRejectRequest(request, | |
365 context_.network_delegate())); | |
366 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); | |
367 for (int i = 0; i < 10; ++i) { | |
368 // Host doesn't really matter in this scenario so we skip it. | |
369 entry->UpdateWithResponse(std::string(), &failure_adapter); | |
370 } | |
371 EXPECT_NE(opted_out, entry->ShouldRejectRequest( | |
372 request, context_.network_delegate())); | |
373 | |
374 if (opted_out) { | |
375 // We're not mocking out GetTimeNow() in this scenario | |
376 // so add a 100 ms buffer to avoid flakiness (that should always | |
377 // give enough time to get from the TimeTicks::Now() call here | |
378 // to the TimeTicks::Now() call in the entry class). | |
379 EXPECT_GT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), | |
380 entry->GetExponentialBackoffReleaseTime()); | |
381 } else { | |
382 // As above, add 100 ms. | |
383 EXPECT_LT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), | |
384 entry->GetExponentialBackoffReleaseTime()); | |
385 } | |
386 } | |
387 | |
388 // context_ must be declared before request_. | |
389 TestURLRequestContext context_; | |
390 scoped_ptr<URLRequest> request_; | |
391 }; | |
392 | |
393 TEST_F(URLRequestThrottlerManagerTest, IsUrlStandardised) { | |
394 MockURLRequestThrottlerManager manager; | |
395 GurlAndString test_values[] = { | |
396 GurlAndString(GURL("http://www.example.com"), | |
397 std::string("http://www.example.com/"), | |
398 __LINE__), | |
399 GurlAndString(GURL("http://www.Example.com"), | |
400 std::string("http://www.example.com/"), | |
401 __LINE__), | |
402 GurlAndString(GURL("http://www.ex4mple.com/Pr4c71c41"), | |
403 std::string("http://www.ex4mple.com/pr4c71c41"), | |
404 __LINE__), | |
405 GurlAndString(GURL("http://www.example.com/0/token/false"), | |
406 std::string("http://www.example.com/0/token/false"), | |
407 __LINE__), | |
408 GurlAndString(GURL("http://www.example.com/index.php?code=javascript"), | |
409 std::string("http://www.example.com/index.php"), | |
410 __LINE__), | |
411 GurlAndString(GURL("http://www.example.com/index.php?code=1#superEntry"), | |
412 std::string("http://www.example.com/index.php"), | |
413 __LINE__), | |
414 GurlAndString(GURL("http://www.example.com/index.php#superEntry"), | |
415 std::string("http://www.example.com/index.php"), | |
416 __LINE__), | |
417 GurlAndString(GURL("http://www.example.com:1234/"), | |
418 std::string("http://www.example.com:1234/"), | |
419 __LINE__)}; | |
420 | |
421 for (unsigned int i = 0; i < arraysize(test_values); ++i) { | |
422 std::string temp = manager.DoGetUrlIdFromUrl(test_values[i].url); | |
423 EXPECT_EQ(temp, test_values[i].result) << | |
424 "Test case #" << i << " line " << test_values[i].line << " failed"; | |
425 } | |
426 } | |
427 | |
428 TEST_F(URLRequestThrottlerManagerTest, AreEntriesBeingCollected) { | |
429 MockURLRequestThrottlerManager manager; | |
430 | |
431 manager.CreateEntry(true); // true = Entry is outdated. | |
432 manager.CreateEntry(true); | |
433 manager.CreateEntry(true); | |
434 manager.DoGarbageCollectEntries(); | |
435 EXPECT_EQ(0, manager.GetNumberOfEntries()); | |
436 | |
437 manager.CreateEntry(false); | |
438 manager.CreateEntry(false); | |
439 manager.CreateEntry(false); | |
440 manager.CreateEntry(true); | |
441 manager.DoGarbageCollectEntries(); | |
442 EXPECT_EQ(3, manager.GetNumberOfEntries()); | |
443 } | |
444 | |
445 TEST_F(URLRequestThrottlerManagerTest, IsHostBeingRegistered) { | |
446 MockURLRequestThrottlerManager manager; | |
447 | |
448 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | |
449 manager.RegisterRequestUrl(GURL("http://www.google.com/")); | |
450 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0")); | |
451 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0?code=1")); | |
452 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0#lolsaure")); | |
453 | |
454 EXPECT_EQ(3, manager.GetNumberOfEntries()); | |
455 } | |
456 | |
457 TEST_F(URLRequestThrottlerManagerTest, OptOutHeader) { | |
458 MockURLRequestThrottlerManager manager; | |
459 scoped_refptr<URLRequestThrottlerEntryInterface> entry = | |
460 manager.RegisterRequestUrl(GURL("http://www.google.com/yodude")); | |
461 | |
462 // Fake a response with the opt-out header. | |
463 MockURLRequestThrottlerHeaderAdapter response_adapter( | |
464 std::string(), | |
465 MockURLRequestThrottlerEntry::kExponentialThrottlingDisableValue, | |
466 200); | |
467 entry->UpdateWithResponse("www.google.com", &response_adapter); | |
468 | |
469 // Ensure that the same entry on error always allows everything. | |
470 ExpectEntryAllowsAllOnErrorIfOptedOut(entry.get(), true, *request_); | |
471 | |
472 // Ensure that a freshly created entry (for a different URL on an | |
473 // already opted-out host) also gets "always allow" behavior. | |
474 scoped_refptr<URLRequestThrottlerEntryInterface> other_entry = | |
475 manager.RegisterRequestUrl(GURL("http://www.google.com/bingobob")); | |
476 ExpectEntryAllowsAllOnErrorIfOptedOut(other_entry.get(), true, *request_); | |
477 | |
478 // Fake a response with the opt-out header incorrectly specified. | |
479 scoped_refptr<URLRequestThrottlerEntryInterface> no_opt_out_entry = | |
480 manager.RegisterRequestUrl(GURL("http://www.nike.com/justdoit")); | |
481 MockURLRequestThrottlerHeaderAdapter wrong_adapter( | |
482 std::string(), "yesplease", 200); | |
483 no_opt_out_entry->UpdateWithResponse("www.nike.com", &wrong_adapter); | |
484 ExpectEntryAllowsAllOnErrorIfOptedOut( | |
485 no_opt_out_entry.get(), false, *request_); | |
486 | |
487 // A localhost entry should always be opted out. | |
488 scoped_refptr<URLRequestThrottlerEntryInterface> localhost_entry = | |
489 manager.RegisterRequestUrl(GURL("http://localhost/hello")); | |
490 ExpectEntryAllowsAllOnErrorIfOptedOut(localhost_entry.get(), true, *request_); | |
491 } | |
492 | |
493 TEST_F(URLRequestThrottlerManagerTest, ClearOnNetworkChange) { | |
494 for (int i = 0; i < 3; ++i) { | |
495 MockURLRequestThrottlerManager manager; | |
496 scoped_refptr<URLRequestThrottlerEntryInterface> entry_before = | |
497 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | |
498 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); | |
499 for (int j = 0; j < 10; ++j) { | |
500 // Host doesn't really matter in this scenario so we skip it. | |
501 entry_before->UpdateWithResponse(std::string(), &failure_adapter); | |
502 } | |
503 EXPECT_TRUE(entry_before->ShouldRejectRequest(*request_, | |
504 context_.network_delegate())); | |
505 | |
506 switch (i) { | |
507 case 0: | |
508 manager.OnIPAddressChanged(); | |
509 break; | |
510 case 1: | |
511 manager.OnConnectionTypeChanged( | |
512 NetworkChangeNotifier::CONNECTION_UNKNOWN); | |
513 break; | |
514 case 2: | |
515 manager.OnConnectionTypeChanged(NetworkChangeNotifier::CONNECTION_NONE); | |
516 break; | |
517 default: | |
518 FAIL(); | |
519 } | |
520 | |
521 scoped_refptr<URLRequestThrottlerEntryInterface> entry_after = | |
522 manager.RegisterRequestUrl(GURL("http://www.example.com/")); | |
523 EXPECT_FALSE(entry_after->ShouldRejectRequest( | |
524 *request_, context_.network_delegate())); | |
525 } | |
526 } | |
527 | |
528 } // namespace net | |
OLD | NEW |