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