Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: chrome/common/net/url_fetcher_unittest.cc

Issue 4194001: Implement exponential back-off mechanism and enforce it at the URLRequestHttpJob level. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "base/message_loop_proxy.h" 5 #include "base/message_loop_proxy.h"
6 #include "base/thread.h" 6 #include "base/thread.h"
7 #include "base/waitable_event.h" 7 #include "base/waitable_event.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 #include "chrome/common/chrome_plugin_lib.h" 9 #include "chrome/common/chrome_plugin_lib.h"
10 #include "chrome/common/net/url_fetcher.h" 10 #include "chrome/common/net/url_fetcher.h"
11 #include "chrome/common/net/url_fetcher_protect.h"
12 #include "chrome/common/net/url_request_context_getter.h" 11 #include "chrome/common/net/url_request_context_getter.h"
13 #include "net/http/http_response_headers.h" 12 #include "net/http/http_response_headers.h"
13 #include "net/test/test_server.h"
14 #include "net/url_request/request_throttler_manager.h"
14 #include "net/url_request/url_request_unittest.h" 15 #include "net/url_request/url_request_unittest.h"
15 #include "net/test/test_server.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 #if defined(USE_NSS) 18 #if defined(USE_NSS)
19 #include "net/ocsp/nss_ocsp.h" 19 #include "net/ocsp/nss_ocsp.h"
20 #endif 20 #endif
21 21
22 using base::Time; 22 using base::Time;
23 using base::TimeDelta; 23 using base::TimeDelta;
24 24
25 // TODO(eroman): Add a regression test for http://crbug.com/40505. 25 // TODO(eroman): Add a regression test for http://crbug.com/40505.
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 EXPECT_EQ("private", header); 305 EXPECT_EQ("private", header);
306 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, 306 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code,
307 cookies, data); 307 cookies, data);
308 } 308 }
309 309
310 void URLFetcherProtectTest::CreateFetcher(const GURL& url) { 310 void URLFetcherProtectTest::CreateFetcher(const GURL& url) {
311 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); 311 fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
312 fetcher_->set_request_context(new TestURLRequestContextGetter( 312 fetcher_->set_request_context(new TestURLRequestContextGetter(
313 io_message_loop_proxy())); 313 io_message_loop_proxy()));
314 start_time_ = Time::Now(); 314 start_time_ = Time::Now();
315 fetcher_->set_max_retries(11);
willchan no longer on Chromium 2010/11/24 00:23:07 11 is a magic number. Does this have any specific
yzshen 2010/11/24 09:42:08 It is only meaningful for this specific test. I ha
315 fetcher_->Start(); 316 fetcher_->Start();
316 } 317 }
317 318
318 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source, 319 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source,
319 const GURL& url, 320 const GURL& url,
320 const URLRequestStatus& status, 321 const URLRequestStatus& status,
321 int response_code, 322 int response_code,
322 const ResponseCookies& cookies, 323 const ResponseCookies& cookies,
323 const std::string& data) { 324 const std::string& data) {
324 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000); 325 const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
325 if (response_code >= 500) { 326 if (response_code >= 500) {
326 // Now running ServerUnavailable test. 327 // Now running ServerUnavailable test.
327 // It takes more than 1 second to finish all 11 requests. 328 // It takes more than 1 second to finish all 11 requests.
328 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); 329 EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
329 EXPECT_TRUE(status.is_success()); 330 EXPECT_TRUE(status.is_success());
330 EXPECT_FALSE(data.empty()); 331 EXPECT_FALSE(data.empty());
331 delete fetcher_; 332 delete fetcher_;
332 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 333 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
333 } else { 334 } else {
334 // Now running Overload test. 335 // Now running Overload test.
335 static int count = 0; 336 static int count = 0;
336 count++; 337 count++;
337 if (count < 20) { 338 if (count < 20) {
338 fetcher_->Start(); 339 fetcher_->Start();
339 } else { 340 } else {
340 // We have already sent 20 requests continuously. And we expect that 341 // We have already sent 20 requests continuously. And we expect that
341 // it takes more than 1 second due to the overload pretection settings. 342 // it takes more than 1 second due to the overload protection settings.
342 EXPECT_TRUE(Time::Now() - start_time_ >= one_second); 343 EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
343 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code, 344 URLFetcherTest::OnURLFetchComplete(source, url, status, response_code,
344 cookies, data); 345 cookies, data);
345 } 346 }
346 } 347 }
347 } 348 }
348 349
349 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) { 350 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) {
350 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); 351 fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
351 fetcher_->set_request_context(new TestURLRequestContextGetter( 352 fetcher_->set_request_context(new TestURLRequestContextGetter(
352 io_message_loop_proxy())); 353 io_message_loop_proxy()));
353 fetcher_->set_automatically_retry_on_5xx(false); 354 fetcher_->set_automatically_retry_on_5xx(false);
354 start_time_ = Time::Now(); 355 start_time_ = Time::Now();
356 fetcher_->set_max_retries(11);
355 fetcher_->Start(); 357 fetcher_->Start();
356 } 358 }
357 359
358 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete( 360 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete(
359 const URLFetcher* source, 361 const URLFetcher* source,
360 const GURL& url, 362 const GURL& url,
361 const URLRequestStatus& status, 363 const URLRequestStatus& status,
362 int response_code, 364 int response_code,
363 const ResponseCookies& cookies, 365 const ResponseCookies& cookies,
364 const std::string& data) { 366 const std::string& data) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 // The rest is the same as URLFetcherTest::OnURLFetchComplete. 414 // The rest is the same as URLFetcherTest::OnURLFetchComplete.
413 delete fetcher_; 415 delete fetcher_;
414 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 416 io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
415 } 417 }
416 418
417 void URLFetcherCancelTest::CreateFetcher(const GURL& url) { 419 void URLFetcherCancelTest::CreateFetcher(const GURL& url) {
418 fetcher_ = new URLFetcher(url, URLFetcher::GET, this); 420 fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
419 CancelTestURLRequestContextGetter* context_getter = 421 CancelTestURLRequestContextGetter* context_getter =
420 new CancelTestURLRequestContextGetter(io_message_loop_proxy()); 422 new CancelTestURLRequestContextGetter(io_message_loop_proxy());
421 fetcher_->set_request_context(context_getter); 423 fetcher_->set_request_context(context_getter);
424 fetcher_->set_max_retries(2);
422 fetcher_->Start(); 425 fetcher_->Start();
423 // We need to wait for the creation of the URLRequestContext, since we 426 // We need to wait for the creation of the URLRequestContext, since we
424 // rely on it being destroyed as a signal to end the test. 427 // rely on it being destroyed as a signal to end the test.
425 context_getter->WaitForContextCreation(); 428 context_getter->WaitForContextCreation();
426 CancelRequest(); 429 CancelRequest();
427 } 430 }
428 431
429 void URLFetcherCancelTest::OnURLFetchComplete(const URLFetcher* source, 432 void URLFetcherCancelTest::OnURLFetchComplete(const URLFetcher* source,
430 const GURL& url, 433 const GURL& url,
431 const URLRequestStatus& status, 434 const URLRequestStatus& status,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 496 }
494 497
495 TEST_F(URLFetcherProtectTest, Overload) { 498 TEST_F(URLFetcherProtectTest, Overload) {
496 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 499 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
497 ASSERT_TRUE(test_server.Start()); 500 ASSERT_TRUE(test_server.Start());
498 501
499 GURL url(test_server.GetURL("defaultresponse")); 502 GURL url(test_server.GetURL("defaultresponse"));
500 503
501 // Registers an entry for test url. It only allows 3 requests to be sent 504 // Registers an entry for test url. It only allows 3 requests to be sent
502 // in 200 milliseconds. 505 // in 200 milliseconds.
503 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 506 scoped_refptr<RequestThrottlerEntry> entry(new RequestThrottlerEntry(
504 URLFetcherProtectEntry* entry = 507 200, 3, 1, 0, 2.0, 0.0, 256));
505 new URLFetcherProtectEntry(200, 3, 11, 1, 2.0, 0, 256); 508 RequestThrottlerManager::GetInstance()->OverrideEntryForTests(url, entry);
506 manager->Register(url.host(), entry);
507 509
508 CreateFetcher(url); 510 CreateFetcher(url);
509 511
510 MessageLoop::current()->Run(); 512 MessageLoop::current()->Run();
513
514 RequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
511 } 515 }
512 516
513 TEST_F(URLFetcherProtectTest, ServerUnavailable) { 517 TEST_F(URLFetcherProtectTest, ServerUnavailable) {
514 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 518 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
515 ASSERT_TRUE(test_server.Start()); 519 ASSERT_TRUE(test_server.Start());
516 520
517 GURL url(test_server.GetURL("files/server-unavailable.html")); 521 GURL url(test_server.GetURL("files/server-unavailable.html"));
518 522
519 // Registers an entry for test url. The backoff time is calculated by: 523 // Registers an entry for test url. The backoff time is calculated by:
520 // new_backoff = 2.0 * old_backoff + 0 524 // new_backoff = 2.0 * old_backoff + 0
521 // and maximum backoff time is 256 milliseconds. 525 // and maximum backoff time is 256 milliseconds.
522 // Maximum retries allowed is set to 11. 526 // Maximum retries allowed is set to 11.
523 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 527 scoped_refptr<RequestThrottlerEntry> entry(new RequestThrottlerEntry(
524 URLFetcherProtectEntry* entry = 528 200, 3, 1, 0, 2.0, 0.0, 256));
525 new URLFetcherProtectEntry(200, 3, 11, 1, 2.0, 0, 256); 529 RequestThrottlerManager::GetInstance()->OverrideEntryForTests(url, entry);
526 manager->Register(url.host(), entry);
527 530
528 CreateFetcher(url); 531 CreateFetcher(url);
529 532
530 MessageLoop::current()->Run(); 533 MessageLoop::current()->Run();
534
535 RequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
531 } 536 }
532 537
533 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { 538 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) {
534 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 539 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
535 ASSERT_TRUE(test_server.Start()); 540 ASSERT_TRUE(test_server.Start());
536 541
537 GURL url(test_server.GetURL("files/server-unavailable.html")); 542 GURL url(test_server.GetURL("files/server-unavailable.html"));
538 543
539 // Registers an entry for test url. The backoff time is calculated by: 544 // Registers an entry for test url. The backoff time is calculated by:
540 // new_backoff = 2.0 * old_backoff + 0 545 // new_backoff = 2.0 * old_backoff + 0
541 // and maximum backoff time is 256 milliseconds. 546 // and maximum backoff time is 150000 milliseconds.
542 // Maximum retries allowed is set to 11. 547 // Maximum retries allowed is set to 11.
543 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 548 scoped_refptr<RequestThrottlerEntry> entry(new RequestThrottlerEntry(
549 200, 3, 100, 0, 2.0, 0.0, 150000));
544 // Total time if *not* for not doing automatic backoff would be 150s. 550 // Total time if *not* for not doing automatic backoff would be 150s.
545 // In reality it should be "as soon as server responds". 551 // In reality it should be "as soon as server responds".
546 URLFetcherProtectEntry* entry = 552 RequestThrottlerManager::GetInstance()->OverrideEntryForTests(url, entry);
547 new URLFetcherProtectEntry(200, 3, 11, 100, 2.0, 0, 150000);
548 manager->Register(url.host(), entry);
549 553
550 CreateFetcher(url); 554 CreateFetcher(url);
551 555
552 MessageLoop::current()->Run(); 556 MessageLoop::current()->Run();
557
558 RequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
553 } 559 }
554 560
555
556 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { 561 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) {
557 net::TestServer::HTTPSOptions https_options( 562 net::TestServer::HTTPSOptions https_options(
558 net::TestServer::HTTPSOptions::CERT_EXPIRED); 563 net::TestServer::HTTPSOptions::CERT_EXPIRED);
559 net::TestServer test_server(https_options, FilePath(kDocRoot)); 564 net::TestServer test_server(https_options, FilePath(kDocRoot));
560 ASSERT_TRUE(test_server.Start()); 565 ASSERT_TRUE(test_server.Start());
561 566
562 CreateFetcher(test_server.GetURL("defaultresponse")); 567 CreateFetcher(test_server.GetURL("defaultresponse"));
563 MessageLoop::current()->Run(); 568 MessageLoop::current()->Run();
564 } 569 }
565 570
566 TEST_F(URLFetcherCancelTest, ReleasesContext) { 571 TEST_F(URLFetcherCancelTest, ReleasesContext) {
567 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 572 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
568 ASSERT_TRUE(test_server.Start()); 573 ASSERT_TRUE(test_server.Start());
569 574
570 GURL url(test_server.GetURL("files/server-unavailable.html")); 575 GURL url(test_server.GetURL("files/server-unavailable.html"));
571 576
572 // Registers an entry for test url. The backoff time is calculated by: 577 // Registers an entry for test url. The backoff time is calculated by:
573 // new_backoff = 2.0 * old_backoff + 0 578 // new_backoff = 2.0 * old_backoff + 0
574 // The initial backoff is 2 seconds and maximum backoff is 4 seconds. 579 // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
575 // Maximum retries allowed is set to 2. 580 // Maximum retries allowed is set to 2.
576 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 581 scoped_refptr<RequestThrottlerEntry> entry(new RequestThrottlerEntry(
577 URLFetcherProtectEntry* entry = 582 200, 3, 2000, 0, 2.0, 0.0, 4000));
578 new URLFetcherProtectEntry(200, 3, 2, 2000, 2.0, 0, 4000); 583 RequestThrottlerManager::GetInstance()->OverrideEntryForTests(url, entry);
579 manager->Register(url.host(), entry);
580 584
581 // Create a separate thread that will create the URLFetcher. The current 585 // Create a separate thread that will create the URLFetcher. The current
582 // (main) thread will do the IO, and when the fetch is complete it will 586 // (main) thread will do the IO, and when the fetch is complete it will
583 // terminate the main thread's message loop; then the other thread's 587 // terminate the main thread's message loop; then the other thread's
584 // message loop will be shut down automatically as the thread goes out of 588 // message loop will be shut down automatically as the thread goes out of
585 // scope. 589 // scope.
586 base::Thread t("URLFetcher test thread"); 590 base::Thread t("URLFetcher test thread");
587 ASSERT_TRUE(t.Start()); 591 ASSERT_TRUE(t.Start());
588 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); 592 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
589 593
590 MessageLoop::current()->Run(); 594 MessageLoop::current()->Run();
595
596 RequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
591 } 597 }
592 598
593 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { 599 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) {
594 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 600 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
595 ASSERT_TRUE(test_server.Start()); 601 ASSERT_TRUE(test_server.Start());
596 602
597 GURL url(test_server.GetURL("files/server-unavailable.html")); 603 GURL url(test_server.GetURL("files/server-unavailable.html"));
598 604
599 // Register an entry for test url. 605 // Register an entry for test url.
600 // 606 // Using a sliding window of 4 seconds, and max of 1 request, under a fast
601 // Ideally we would mock URLFetcherProtectEntry to return XXX seconds
602 // in response to entry->UpdateBackoff(SEND).
603 //
604 // Unfortunately this function is time sensitive, so we fudge some numbers
605 // to make it at least somewhat likely to have a non-zero deferred
606 // delay when running.
607 //
608 // Using a sliding window of 2 seconds, and max of 1 request, under a fast
609 // run we expect to have a 4 second delay when posting the Start task. 607 // run we expect to have a 4 second delay when posting the Start task.
610 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 608 scoped_refptr<RequestThrottlerEntry> entry(new RequestThrottlerEntry(
611 URLFetcherProtectEntry* entry = 609 4000, 1, 2000, 0, 2.0, 0.0, 4000));
612 new URLFetcherProtectEntry(2000, 1, 2, 2000, 2.0, 0, 4000); 610 RequestThrottlerManager::GetInstance()->OverrideEntryForTests(url, entry);
613 EXPECT_EQ(0, entry->UpdateBackoff(URLFetcherProtectEntry::SEND)); 611 // Fake that a request has just started.
614 entry->UpdateBackoff(URLFetcherProtectEntry::SEND); // Returns about 2000. 612 entry->ReserveSendingTimeForNextRequest(base::TimeTicks());
615 manager->Register(url.host(), entry);
616 613
617 // The next request we try to send will be delayed by ~4 seconds. 614 // The next request we try to send will be delayed by ~4 seconds.
618 // The slower the test runs, the less the delay will be (since it takes the 615 // The slower the test runs, the less the delay will be (since it takes the
619 // time difference from now). 616 // time difference from now).
620 617
621 base::Thread t("URLFetcher test thread"); 618 base::Thread t("URLFetcher test thread");
622 ASSERT_TRUE(t.Start()); 619 ASSERT_TRUE(t.Start());
623 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); 620 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
624 621
625 MessageLoop::current()->Run(); 622 MessageLoop::current()->Run();
623
624 RequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
626 } 625 }
627 626
628 } // namespace. 627 } // namespace.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698