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

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, 1 month 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/url_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);
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<net::URLRequestThrottlerEntry> entry(
504 URLFetcherProtectEntry* entry = 507 new net::URLRequestThrottlerEntry(200, 3, 1, 0, 2.0, 0.0, 256));
505 new URLFetcherProtectEntry(200, 3, 11, 1, 2.0, 0, 256); 508 net::URLRequestThrottlerManager::GetInstance()->OverrideEntryForTests(
506 manager->Register(url.host(), entry); 509 url, entry);
507 510
508 CreateFetcher(url); 511 CreateFetcher(url);
509 512
510 MessageLoop::current()->Run(); 513 MessageLoop::current()->Run();
514
515 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
511 } 516 }
512 517
513 TEST_F(URLFetcherProtectTest, ServerUnavailable) { 518 TEST_F(URLFetcherProtectTest, ServerUnavailable) {
514 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 519 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
515 ASSERT_TRUE(test_server.Start()); 520 ASSERT_TRUE(test_server.Start());
516 521
517 GURL url(test_server.GetURL("files/server-unavailable.html")); 522 GURL url(test_server.GetURL("files/server-unavailable.html"));
518 523
519 // Registers an entry for test url. The backoff time is calculated by: 524 // Registers an entry for test url. The backoff time is calculated by:
520 // new_backoff = 2.0 * old_backoff + 0 525 // new_backoff = 2.0 * old_backoff + 0
521 // and maximum backoff time is 256 milliseconds. 526 // and maximum backoff time is 256 milliseconds.
522 // Maximum retries allowed is set to 11. 527 // Maximum retries allowed is set to 11.
523 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 528 scoped_refptr<net::URLRequestThrottlerEntry> entry(
524 URLFetcherProtectEntry* entry = 529 new net::URLRequestThrottlerEntry(200, 3, 1, 0, 2.0, 0.0, 256));
525 new URLFetcherProtectEntry(200, 3, 11, 1, 2.0, 0, 256); 530 net::URLRequestThrottlerManager::GetInstance()->OverrideEntryForTests(
526 manager->Register(url.host(), entry); 531 url, entry);
527 532
528 CreateFetcher(url); 533 CreateFetcher(url);
529 534
530 MessageLoop::current()->Run(); 535 MessageLoop::current()->Run();
536
537 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
531 } 538 }
532 539
533 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) { 540 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) {
534 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 541 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
535 ASSERT_TRUE(test_server.Start()); 542 ASSERT_TRUE(test_server.Start());
536 543
537 GURL url(test_server.GetURL("files/server-unavailable.html")); 544 GURL url(test_server.GetURL("files/server-unavailable.html"));
538 545
539 // Registers an entry for test url. The backoff time is calculated by: 546 // Registers an entry for test url. The backoff time is calculated by:
540 // new_backoff = 2.0 * old_backoff + 0 547 // new_backoff = 2.0 * old_backoff + 0
541 // and maximum backoff time is 256 milliseconds. 548 // and maximum backoff time is 150000 milliseconds.
542 // Maximum retries allowed is set to 11. 549 // Maximum retries allowed is set to 11.
543 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 550 scoped_refptr<net::URLRequestThrottlerEntry> entry(
551 new net::URLRequestThrottlerEntry(200, 3, 100, 0, 2.0, 0.0, 150000));
544 // Total time if *not* for not doing automatic backoff would be 150s. 552 // Total time if *not* for not doing automatic backoff would be 150s.
545 // In reality it should be "as soon as server responds". 553 // In reality it should be "as soon as server responds".
546 URLFetcherProtectEntry* entry = 554 net::URLRequestThrottlerManager::GetInstance()->OverrideEntryForTests(
547 new URLFetcherProtectEntry(200, 3, 11, 100, 2.0, 0, 150000); 555 url, entry);
548 manager->Register(url.host(), entry);
549 556
550 CreateFetcher(url); 557 CreateFetcher(url);
551 558
552 MessageLoop::current()->Run(); 559 MessageLoop::current()->Run();
560
561 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
553 } 562 }
554 563
555
556 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { 564 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) {
557 net::TestServer::HTTPSOptions https_options( 565 net::TestServer::HTTPSOptions https_options(
558 net::TestServer::HTTPSOptions::CERT_EXPIRED); 566 net::TestServer::HTTPSOptions::CERT_EXPIRED);
559 net::TestServer test_server(https_options, FilePath(kDocRoot)); 567 net::TestServer test_server(https_options, FilePath(kDocRoot));
560 ASSERT_TRUE(test_server.Start()); 568 ASSERT_TRUE(test_server.Start());
561 569
562 CreateFetcher(test_server.GetURL("defaultresponse")); 570 CreateFetcher(test_server.GetURL("defaultresponse"));
563 MessageLoop::current()->Run(); 571 MessageLoop::current()->Run();
564 } 572 }
565 573
566 TEST_F(URLFetcherCancelTest, ReleasesContext) { 574 TEST_F(URLFetcherCancelTest, ReleasesContext) {
567 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 575 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
568 ASSERT_TRUE(test_server.Start()); 576 ASSERT_TRUE(test_server.Start());
569 577
570 GURL url(test_server.GetURL("files/server-unavailable.html")); 578 GURL url(test_server.GetURL("files/server-unavailable.html"));
571 579
572 // Registers an entry for test url. The backoff time is calculated by: 580 // Registers an entry for test url. The backoff time is calculated by:
573 // new_backoff = 2.0 * old_backoff + 0 581 // new_backoff = 2.0 * old_backoff + 0
574 // The initial backoff is 2 seconds and maximum backoff is 4 seconds. 582 // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
575 // Maximum retries allowed is set to 2. 583 // Maximum retries allowed is set to 2.
576 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 584 scoped_refptr<net::URLRequestThrottlerEntry> entry(
577 URLFetcherProtectEntry* entry = 585 new net::URLRequestThrottlerEntry(200, 3, 2000, 0, 2.0, 0.0, 4000));
578 new URLFetcherProtectEntry(200, 3, 2, 2000, 2.0, 0, 4000); 586 net::URLRequestThrottlerManager::GetInstance()->OverrideEntryForTests(
579 manager->Register(url.host(), entry); 587 url, entry);
580 588
581 // Create a separate thread that will create the URLFetcher. The current 589 // 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 590 // (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 591 // 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 592 // message loop will be shut down automatically as the thread goes out of
585 // scope. 593 // scope.
586 base::Thread t("URLFetcher test thread"); 594 base::Thread t("URLFetcher test thread");
587 ASSERT_TRUE(t.Start()); 595 ASSERT_TRUE(t.Start());
588 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); 596 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
589 597
590 MessageLoop::current()->Run(); 598 MessageLoop::current()->Run();
599
600 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
591 } 601 }
592 602
593 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) { 603 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) {
594 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot)); 604 net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
595 ASSERT_TRUE(test_server.Start()); 605 ASSERT_TRUE(test_server.Start());
596 606
597 GURL url(test_server.GetURL("files/server-unavailable.html")); 607 GURL url(test_server.GetURL("files/server-unavailable.html"));
598 608
599 // Register an entry for test url. 609 // Register an entry for test url.
600 // 610 // 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. 611 // run we expect to have a 4 second delay when posting the Start task.
610 URLFetcherProtectManager* manager = URLFetcherProtectManager::GetInstance(); 612 scoped_refptr<net::URLRequestThrottlerEntry> entry(
611 URLFetcherProtectEntry* entry = 613 new net::URLRequestThrottlerEntry(4000, 1, 2000, 0, 2.0, 0.0, 4000));
612 new URLFetcherProtectEntry(2000, 1, 2, 2000, 2.0, 0, 4000); 614 net::URLRequestThrottlerManager::GetInstance()->OverrideEntryForTests(
613 EXPECT_EQ(0, entry->UpdateBackoff(URLFetcherProtectEntry::SEND)); 615 url, entry);
614 entry->UpdateBackoff(URLFetcherProtectEntry::SEND); // Returns about 2000. 616 // Fake that a request has just started.
615 manager->Register(url.host(), entry); 617 entry->ReserveSendingTimeForNextRequest(base::TimeTicks());
616 618
617 // The next request we try to send will be delayed by ~4 seconds. 619 // 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 620 // The slower the test runs, the less the delay will be (since it takes the
619 // time difference from now). 621 // time difference from now).
620 622
621 base::Thread t("URLFetcher test thread"); 623 base::Thread t("URLFetcher test thread");
622 ASSERT_TRUE(t.Start()); 624 ASSERT_TRUE(t.Start());
623 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url)); 625 t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
624 626
625 MessageLoop::current()->Run(); 627 MessageLoop::current()->Run();
628
629 net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
626 } 630 }
627 631
628 } // namespace. 632 } // namespace.
OLDNEW
« no previous file with comments | « chrome/common/net/url_fetcher_protect.cc ('k') | chrome/service/cloud_print/cloud_print_consts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698