Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2011 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 "base/message_loop_proxy.h"
      6 #include "base/synchronization/waitable_event.h"
      7 #include "base/threading/thread.h"
      8 #include "build/build_config.h"
      9 #include "chrome/common/net/url_fetcher.h"
     10 #include "net/http/http_response_headers.h"
     11 #include "net/test/test_server.h"
     12 #include "net/url_request/url_request_context_getter.h"
     13 #include "net/url_request/url_request_test_util.h"
     14 #include "net/url_request/url_request_throttler_manager.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 #if defined(USE_NSS)
     18 #include "net/ocsp/nss_ocsp.h"
     19 #endif
     20 
     21 using base::Time;
     22 using base::TimeDelta;
     23 
     24 // TODO(eroman): Add a regression test for http://crbug.com/40505.
     25 
     26 namespace {
     27 
     28 const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");
     29 
     30 class CurriedTask : public Task {
     31  public:
     32   CurriedTask(Task* task, MessageLoop* target_loop)
     33       : task_(task),
     34         target_loop_(target_loop) {}
     35 
     36   virtual void Run() {
     37     target_loop_->PostTask(FROM_HERE, task_);
     38   }
     39 
     40  private:
     41   Task* const task_;
     42   MessageLoop* const target_loop_;
     43 
     44   DISALLOW_COPY_AND_ASSIGN(CurriedTask);
     45 };
     46 
     47 class TestURLRequestContextGetter : public net::URLRequestContextGetter {
     48  public:
     49   explicit TestURLRequestContextGetter(
     50       base::MessageLoopProxy* io_message_loop_proxy)
     51           : io_message_loop_proxy_(io_message_loop_proxy) {
     52   }
     53   virtual net::URLRequestContext* GetURLRequestContext() {
     54     if (!context_)
     55       context_ = new TestURLRequestContext();
     56     return context_;
     57   }
     58   virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const {
     59     return io_message_loop_proxy_;
     60   }
     61 
     62  protected:
     63   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
     64 
     65  private:
     66   ~TestURLRequestContextGetter() {}
     67 
     68   scoped_refptr<net::URLRequestContext> context_;
     69 };
     70 
     71 }  // namespace
     72 
     73 class URLFetcherTest : public testing::Test, public URLFetcher::Delegate {
     74  public:
     75   URLFetcherTest() : fetcher_(NULL) { }
     76 
     77   // Creates a URLFetcher, using the program's main thread to do IO.
     78   virtual void CreateFetcher(const GURL& url);
     79 
     80   // URLFetcher::Delegate
     81   virtual void OnURLFetchComplete(const URLFetcher* source,
     82                                   const GURL& url,
     83                                   const net::URLRequestStatus& status,
     84                                   int response_code,
     85                                   const ResponseCookies& cookies,
     86                                   const std::string& data);
     87 
     88   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
     89     return io_message_loop_proxy_;
     90   }
     91 
     92  protected:
     93   virtual void SetUp() {
     94     testing::Test::SetUp();
     95 
     96     io_message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread();
     97 
     98 #if defined(USE_NSS)
     99     net::EnsureOCSPInit();
    100 #endif
    101   }
    102 
    103   virtual void TearDown() {
    104 #if defined(USE_NSS)
    105     net::ShutdownOCSP();
    106 #endif
    107   }
    108 
    109   int GetNumFetcherCores() const {
    110     return URLFetcher::GetNumFetcherCores();
    111   }
    112 
    113   // URLFetcher is designed to run on the main UI thread, but in our tests
    114   // we assume that the current thread is the IO thread where the URLFetcher
    115   // dispatches its requests to.  When we wish to simulate being used from
    116   // a UI thread, we dispatch a worker thread to do so.
    117   MessageLoopForIO io_loop_;
    118   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
    119 
    120   URLFetcher* fetcher_;
    121 };
    122 
    123 void URLFetcherTest::CreateFetcher(const GURL& url) {
    124   fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
    125   fetcher_->set_request_context(new TestURLRequestContextGetter(
    126       io_message_loop_proxy()));
    127   fetcher_->Start();
    128 }
    129 
    130 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source,
    131                                         const GURL& url,
    132                                         const net::URLRequestStatus& status,
    133                                         int response_code,
    134                                         const ResponseCookies& cookies,
    135                                         const std::string& data) {
    136   EXPECT_TRUE(status.is_success());
    137   EXPECT_EQ(200, response_code);  // HTTP OK
    138   EXPECT_FALSE(data.empty());
    139 
    140   delete fetcher_;  // Have to delete this here and not in the destructor,
    141                     // because the destructor won't necessarily run on the
    142                     // same thread that CreateFetcher() did.
    143 
    144   io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    145   // If the current message loop is not the IO loop, it will be shut down when
    146   // the main loop returns and this thread subsequently goes out of scope.
    147 }
    148 
    149 namespace {
    150 
    151 // Version of URLFetcherTest that does a POST instead
    152 class URLFetcherPostTest : public URLFetcherTest {
    153  public:
    154   virtual void CreateFetcher(const GURL& url);
    155 
    156   // URLFetcher::Delegate
    157   virtual void OnURLFetchComplete(const URLFetcher* source,
    158                                   const GURL& url,
    159                                   const net::URLRequestStatus& status,
    160                                   int response_code,
    161                                   const ResponseCookies& cookies,
    162                                   const std::string& data);
    163 };
    164 
    165 // Version of URLFetcherTest that tests headers.
    166 class URLFetcherHeadersTest : public URLFetcherTest {
    167  public:
    168   // URLFetcher::Delegate
    169   virtual void OnURLFetchComplete(const URLFetcher* source,
    170                                   const GURL& url,
    171                                   const net::URLRequestStatus& status,
    172                                   int response_code,
    173                                   const ResponseCookies& cookies,
    174                                   const std::string& data);
    175 };
    176 
    177 // Version of URLFetcherTest that tests overload protection.
    178 class URLFetcherProtectTest : public URLFetcherTest {
    179  public:
    180   virtual void CreateFetcher(const GURL& url);
    181   // URLFetcher::Delegate
    182   virtual void OnURLFetchComplete(const URLFetcher* source,
    183                                   const GURL& url,
    184                                   const net::URLRequestStatus& status,
    185                                   int response_code,
    186                                   const ResponseCookies& cookies,
    187                                   const std::string& data);
    188  private:
    189   Time start_time_;
    190 };
    191 
    192 // Version of URLFetcherTest that tests overload protection, when responses
    193 // passed through.
    194 class URLFetcherProtectTestPassedThrough : public URLFetcherTest {
    195  public:
    196   virtual void CreateFetcher(const GURL& url);
    197   // URLFetcher::Delegate
    198   virtual void OnURLFetchComplete(const URLFetcher* source,
    199                                   const GURL& url,
    200                                   const net::URLRequestStatus& status,
    201                                   int response_code,
    202                                   const ResponseCookies& cookies,
    203                                   const std::string& data);
    204  private:
    205   Time start_time_;
    206 };
    207 
    208 // Version of URLFetcherTest that tests bad HTTPS requests.
    209 class URLFetcherBadHTTPSTest : public URLFetcherTest {
    210  public:
    211   URLFetcherBadHTTPSTest();
    212 
    213   // URLFetcher::Delegate
    214   virtual void OnURLFetchComplete(const URLFetcher* source,
    215                                   const GURL& url,
    216                                   const net::URLRequestStatus& status,
    217                                   int response_code,
    218                                   const ResponseCookies& cookies,
    219                                   const std::string& data);
    220 
    221  private:
    222   FilePath cert_dir_;
    223 };
    224 
    225 // Version of URLFetcherTest that tests request cancellation on shutdown.
    226 class URLFetcherCancelTest : public URLFetcherTest {
    227  public:
    228   virtual void CreateFetcher(const GURL& url);
    229   // URLFetcher::Delegate
    230   virtual void OnURLFetchComplete(const URLFetcher* source,
    231                                   const GURL& url,
    232                                   const net::URLRequestStatus& status,
    233                                   int response_code,
    234                                   const ResponseCookies& cookies,
    235                                   const std::string& data);
    236 
    237   void CancelRequest();
    238 };
    239 
    240 // Version of TestURLRequestContext that posts a Quit task to the IO
    241 // thread once it is deleted.
    242 class CancelTestURLRequestContext : public TestURLRequestContext {
    243   virtual ~CancelTestURLRequestContext() {
    244     // The d'tor should execute in the IO thread. Post the quit task to the
    245     // current thread.
    246     MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    247   }
    248 };
    249 
    250 class CancelTestURLRequestContextGetter : public net::URLRequestContextGetter {
    251  public:
    252   explicit CancelTestURLRequestContextGetter(
    253       base::MessageLoopProxy* io_message_loop_proxy)
    254       : io_message_loop_proxy_(io_message_loop_proxy),
    255         context_created_(false, false) {
    256   }
    257   virtual net::URLRequestContext* GetURLRequestContext() {
    258     if (!context_) {
    259       context_ = new CancelTestURLRequestContext();
    260       context_created_.Signal();
    261     }
    262     return context_;
    263   }
    264   virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const {
    265     return io_message_loop_proxy_;
    266   }
    267   void WaitForContextCreation() {
    268     context_created_.Wait();
    269   }
    270 
    271  private:
    272   ~CancelTestURLRequestContextGetter() {}
    273 
    274   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
    275   base::WaitableEvent context_created_;
    276   scoped_refptr<net::URLRequestContext> context_;
    277 };
    278 
    279 // Version of URLFetcherTest that tests retying the same request twice.
    280 class URLFetcherMultipleAttemptTest : public URLFetcherTest {
    281  public:
    282   // URLFetcher::Delegate
    283   virtual void OnURLFetchComplete(const URLFetcher* source,
    284                                   const GURL& url,
    285                                   const net::URLRequestStatus& status,
    286                                   int response_code,
    287                                   const ResponseCookies& cookies,
    288                                   const std::string& data);
    289  private:
    290   std::string data_;
    291 };
    292 
    293 // Wrapper that lets us call CreateFetcher() on a thread of our choice.  We
    294 // could make URLFetcherTest refcounted and use PostTask(FROM_HERE.. ) to call
    295 // CreateFetcher() directly, but the ownership of the URLFetcherTest is a bit
    296 // confusing in that case because GTest doesn't know about the refcounting.
    297 // It's less confusing to just do it this way.
    298 class FetcherWrapperTask : public Task {
    299  public:
    300   FetcherWrapperTask(URLFetcherTest* test, const GURL& url)
    301       : test_(test), url_(url) { }
    302   virtual void Run() {
    303     test_->CreateFetcher(url_);
    304   }
    305 
    306  private:
    307   URLFetcherTest* test_;
    308   GURL url_;
    309 };
    310 
    311 void URLFetcherPostTest::CreateFetcher(const GURL& url) {
    312   fetcher_ = new URLFetcher(url, URLFetcher::POST, this);
    313   fetcher_->set_request_context(new TestURLRequestContextGetter(
    314       io_message_loop_proxy()));
    315   fetcher_->set_upload_data("application/x-www-form-urlencoded",
    316                             "bobsyeruncle");
    317   fetcher_->Start();
    318 }
    319 
    320 void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source,
    321                                             const GURL& url,
    322                                             const net::URLRequestStatus& status,
    323                                             int response_code,
    324                                             const ResponseCookies& cookies,
    325                                             const std::string& data) {
    326   EXPECT_EQ(std::string("bobsyeruncle"), data);
    327   URLFetcherTest::OnURLFetchComplete(source, url, status, response_code,
    328                                      cookies, data);
    329 }
    330 
    331 void URLFetcherHeadersTest::OnURLFetchComplete(
    332     const URLFetcher* source,
    333     const GURL& url,
    334     const net::URLRequestStatus& status,
    335     int response_code,
    336     const ResponseCookies& cookies,
    337     const std::string& data) {
    338   std::string header;
    339   EXPECT_TRUE(source->response_headers()->GetNormalizedHeader("cache-control",
    340                                                               &header));
    341   EXPECT_EQ("private", header);
    342   URLFetcherTest::OnURLFetchComplete(source, url, status, response_code,
    343                                      cookies, data);
    344 }
    345 
    346 void URLFetcherProtectTest::CreateFetcher(const GURL& url) {
    347   fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
    348   fetcher_->set_request_context(new TestURLRequestContextGetter(
    349       io_message_loop_proxy()));
    350   start_time_ = Time::Now();
    351   fetcher_->set_max_retries(11);
    352   fetcher_->Start();
    353 }
    354 
    355 void URLFetcherProtectTest::OnURLFetchComplete(
    356     const URLFetcher* source,
    357     const GURL& url,
    358     const net::URLRequestStatus& status,
    359     int response_code,
    360     const ResponseCookies& cookies,
    361     const std::string& data) {
    362   const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
    363   if (response_code >= 500) {
    364     // Now running ServerUnavailable test.
    365     // It takes more than 1 second to finish all 11 requests.
    366     EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
    367     EXPECT_TRUE(status.is_success());
    368     EXPECT_FALSE(data.empty());
    369     delete fetcher_;
    370     io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    371   } else {
    372     // Now running Overload test.
    373     static int count = 0;
    374     count++;
    375     if (count < 20) {
    376       fetcher_->Start();
    377     } else {
    378       // We have already sent 20 requests continuously. And we expect that
    379       // it takes more than 1 second due to the overload protection settings.
    380       EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
    381       URLFetcherTest::OnURLFetchComplete(source, url, status, response_code,
    382                                          cookies, data);
    383     }
    384   }
    385 }
    386 
    387 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) {
    388   fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
    389   fetcher_->set_request_context(new TestURLRequestContextGetter(
    390       io_message_loop_proxy()));
    391   fetcher_->set_automatically_retry_on_5xx(false);
    392   start_time_ = Time::Now();
    393   fetcher_->set_max_retries(11);
    394   fetcher_->Start();
    395 }
    396 
    397 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete(
    398     const URLFetcher* source,
    399     const GURL& url,
    400     const net::URLRequestStatus& status,
    401     int response_code,
    402     const ResponseCookies& cookies,
    403     const std::string& data) {
    404   const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000);
    405   if (response_code >= 500) {
    406     // Now running ServerUnavailable test.
    407     // It should get here on the first attempt, so almost immediately and
    408     // *not* to attempt to execute all 11 requests (2.5 minutes).
    409     EXPECT_TRUE(Time::Now() - start_time_ < one_minute);
    410     EXPECT_TRUE(status.is_success());
    411     // Check that suggested back off time is bigger than 0.
    412     EXPECT_GT(fetcher_->backoff_delay().InMicroseconds(), 0);
    413     EXPECT_FALSE(data.empty());
    414   } else {
    415     // We should not get here!
    416     ADD_FAILURE();
    417   }
    418 
    419   delete fetcher_;
    420   io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    421 }
    422 
    423 
    424 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() {
    425   PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
    426   cert_dir_ = cert_dir_.AppendASCII("chrome");
    427   cert_dir_ = cert_dir_.AppendASCII("test");
    428   cert_dir_ = cert_dir_.AppendASCII("data");
    429   cert_dir_ = cert_dir_.AppendASCII("ssl");
    430   cert_dir_ = cert_dir_.AppendASCII("certificates");
    431 }
    432 
    433 // The "server certificate expired" error should result in automatic
    434 // cancellation of the request by
    435 // net::URLRequest::Delegate::OnSSLCertificateError.
    436 void URLFetcherBadHTTPSTest::OnURLFetchComplete(
    437     const URLFetcher* source,
    438     const GURL& url,
    439     const net::URLRequestStatus& status,
    440     int response_code,
    441     const ResponseCookies& cookies,
    442     const std::string& data) {
    443   // This part is different from URLFetcherTest::OnURLFetchComplete
    444   // because this test expects the request to be cancelled.
    445   EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status());
    446   EXPECT_EQ(net::ERR_ABORTED, status.os_error());
    447   EXPECT_EQ(-1, response_code);
    448   EXPECT_TRUE(cookies.empty());
    449   EXPECT_TRUE(data.empty());
    450 
    451   // The rest is the same as URLFetcherTest::OnURLFetchComplete.
    452   delete fetcher_;
    453   io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    454 }
    455 
    456 void URLFetcherCancelTest::CreateFetcher(const GURL& url) {
    457   fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
    458   CancelTestURLRequestContextGetter* context_getter =
    459       new CancelTestURLRequestContextGetter(io_message_loop_proxy());
    460   fetcher_->set_request_context(context_getter);
    461   fetcher_->set_max_retries(2);
    462   fetcher_->Start();
    463   // We need to wait for the creation of the net::URLRequestContext, since we
    464   // rely on it being destroyed as a signal to end the test.
    465   context_getter->WaitForContextCreation();
    466   CancelRequest();
    467 }
    468 
    469 void URLFetcherCancelTest::OnURLFetchComplete(
    470     const URLFetcher* source,
    471     const GURL& url,
    472     const net::URLRequestStatus& status,
    473     int response_code,
    474     const ResponseCookies& cookies,
    475     const std::string& data) {
    476   // We should have cancelled the request before completion.
    477   ADD_FAILURE();
    478   delete fetcher_;
    479   io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    480 }
    481 
    482 void URLFetcherCancelTest::CancelRequest() {
    483   delete fetcher_;
    484   // The URLFetcher's test context will post a Quit task once it is
    485   // deleted. So if this test simply hangs, it means cancellation
    486   // did not work.
    487 }
    488 
    489 void URLFetcherMultipleAttemptTest::OnURLFetchComplete(
    490     const URLFetcher* source,
    491     const GURL& url,
    492     const net::URLRequestStatus& status,
    493     int response_code,
    494     const ResponseCookies& cookies,
    495     const std::string& data) {
    496   EXPECT_TRUE(status.is_success());
    497   EXPECT_EQ(200, response_code);  // HTTP OK
    498   EXPECT_FALSE(data.empty());
    499   if (!data.empty() && data_.empty()) {
    500     data_ = data;
    501     fetcher_->Start();
    502   } else {
    503     EXPECT_EQ(data, data_);
    504     delete fetcher_;  // Have to delete this here and not in the destructor,
    505                       // because the destructor won't necessarily run on the
    506                       // same thread that CreateFetcher() did.
    507 
    508     io_message_loop_proxy()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    509     // If the current message loop is not the IO loop, it will be shut down when
    510     // the main loop returns and this thread subsequently goes out of scope.
    511   }
    512 }
    513 
    514 TEST_F(URLFetcherTest, SameThreadsTest) {
    515   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    516   ASSERT_TRUE(test_server.Start());
    517 
    518   // Create the fetcher on the main thread.  Since IO will happen on the main
    519   // thread, this will test URLFetcher's ability to do everything on one
    520   // thread.
    521   CreateFetcher(test_server.GetURL("defaultresponse"));
    522 
    523   MessageLoop::current()->Run();
    524 }
    525 
    526 #if defined(OS_MACOSX)
    527 // SIGSEGV on Mac: http://crbug.com/60426
    528 TEST_F(URLFetcherTest, DISABLED_DifferentThreadsTest) {
    529 #else
    530 TEST_F(URLFetcherTest, DifferentThreadsTest) {
    531 #endif
    532   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    533   ASSERT_TRUE(test_server.Start());
    534 
    535   // Create a separate thread that will create the URLFetcher.  The current
    536   // (main) thread will do the IO, and when the fetch is complete it will
    537   // terminate the main thread's message loop; then the other thread's
    538   // message loop will be shut down automatically as the thread goes out of
    539   // scope.
    540   base::Thread t("URLFetcher test thread");
    541   ASSERT_TRUE(t.Start());
    542   t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this,
    543       test_server.GetURL("defaultresponse")));
    544 
    545   MessageLoop::current()->Run();
    546 }
    547 
    548 #if defined(OS_MACOSX)
    549 // SIGSEGV on Mac: http://crbug.com/60426
    550 TEST_F(URLFetcherPostTest, DISABLED_Basic) {
    551 #else
    552 TEST_F(URLFetcherPostTest, Basic) {
    553 #endif
    554   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    555   ASSERT_TRUE(test_server.Start());
    556 
    557   CreateFetcher(test_server.GetURL("echo"));
    558   MessageLoop::current()->Run();
    559 }
    560 
    561 TEST_F(URLFetcherHeadersTest, Headers) {
    562   net::TestServer test_server(net::TestServer::TYPE_HTTP,
    563       FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
    564   ASSERT_TRUE(test_server.Start());
    565 
    566   CreateFetcher(test_server.GetURL("files/with-headers.html"));
    567   MessageLoop::current()->Run();
    568   // The actual tests are in the URLFetcherHeadersTest fixture.
    569 }
    570 
    571 TEST_F(URLFetcherProtectTest, Overload) {
    572   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    573   ASSERT_TRUE(test_server.Start());
    574 
    575   GURL url(test_server.GetURL("defaultresponse"));
    576 
    577   // Registers an entry for test url. It only allows 3 requests to be sent
    578   // in 200 milliseconds.
    579   net::URLRequestThrottlerManager* manager =
    580       net::URLRequestThrottlerManager::GetInstance();
    581   scoped_refptr<net::URLRequestThrottlerEntry> entry(
    582       new net::URLRequestThrottlerEntry(manager, 200, 3, 1, 2.0, 0.0, 256));
    583   manager->OverrideEntryForTests(url, entry);
    584 
    585   CreateFetcher(url);
    586 
    587   MessageLoop::current()->Run();
    588 
    589   net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
    590 }
    591 
    592 TEST_F(URLFetcherProtectTest, ServerUnavailable) {
    593   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    594   ASSERT_TRUE(test_server.Start());
    595 
    596   GURL url(test_server.GetURL("files/server-unavailable.html"));
    597 
    598   // Registers an entry for test url. The backoff time is calculated by:
    599   //     new_backoff = 2.0 * old_backoff + 0
    600   // and maximum backoff time is 256 milliseconds.
    601   // Maximum retries allowed is set to 11.
    602   net::URLRequestThrottlerManager* manager =
    603       net::URLRequestThrottlerManager::GetInstance();
    604   scoped_refptr<net::URLRequestThrottlerEntry> entry(
    605       new net::URLRequestThrottlerEntry(manager, 200, 3, 1, 2.0, 0.0, 256));
    606   manager->OverrideEntryForTests(url, entry);
    607 
    608   CreateFetcher(url);
    609 
    610   MessageLoop::current()->Run();
    611 
    612   net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
    613 }
    614 
    615 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) {
    616   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    617   ASSERT_TRUE(test_server.Start());
    618 
    619   GURL url(test_server.GetURL("files/server-unavailable.html"));
    620 
    621   // Registers an entry for test url. The backoff time is calculated by:
    622   //     new_backoff = 2.0 * old_backoff + 0
    623   // and maximum backoff time is 150000 milliseconds.
    624   // Maximum retries allowed is set to 11.
    625   net::URLRequestThrottlerManager* manager =
    626       net::URLRequestThrottlerManager::GetInstance();
    627   scoped_refptr<net::URLRequestThrottlerEntry> entry(
    628       new net::URLRequestThrottlerEntry(
    629           manager, 200, 3, 100, 2.0, 0.0, 150000));
    630   // Total time if *not* for not doing automatic backoff would be 150s.
    631   // In reality it should be "as soon as server responds".
    632   manager->OverrideEntryForTests(url, entry);
    633 
    634   CreateFetcher(url);
    635 
    636   MessageLoop::current()->Run();
    637 
    638   net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
    639 }
    640 
    641 #if defined(OS_MACOSX)
    642 // SIGSEGV on Mac: http://crbug.com/60426
    643 TEST_F(URLFetcherBadHTTPSTest, DISABLED_BadHTTPSTest) {
    644 #else
    645 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) {
    646 #endif
    647   net::TestServer::HTTPSOptions https_options(
    648       net::TestServer::HTTPSOptions::CERT_EXPIRED);
    649   net::TestServer test_server(https_options, FilePath(kDocRoot));
    650   ASSERT_TRUE(test_server.Start());
    651 
    652   CreateFetcher(test_server.GetURL("defaultresponse"));
    653   MessageLoop::current()->Run();
    654 }
    655 
    656 #if defined(OS_MACOSX)
    657 // SIGSEGV on Mac: http://crbug.com/60426
    658 TEST_F(URLFetcherCancelTest, DISABLED_ReleasesContext) {
    659 #else
    660 TEST_F(URLFetcherCancelTest, ReleasesContext) {
    661 #endif
    662   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    663   ASSERT_TRUE(test_server.Start());
    664 
    665   GURL url(test_server.GetURL("files/server-unavailable.html"));
    666 
    667   // Registers an entry for test url. The backoff time is calculated by:
    668   //     new_backoff = 2.0 * old_backoff + 0
    669   // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
    670   // Maximum retries allowed is set to 2.
    671   net::URLRequestThrottlerManager* manager =
    672       net::URLRequestThrottlerManager::GetInstance();
    673   scoped_refptr<net::URLRequestThrottlerEntry> entry(
    674       new net::URLRequestThrottlerEntry(
    675           manager, 200, 3, 2000, 2.0, 0.0, 4000));
    676   manager->OverrideEntryForTests(url, entry);
    677 
    678   // Create a separate thread that will create the URLFetcher.  The current
    679   // (main) thread will do the IO, and when the fetch is complete it will
    680   // terminate the main thread's message loop; then the other thread's
    681   // message loop will be shut down automatically as the thread goes out of
    682   // scope.
    683   base::Thread t("URLFetcher test thread");
    684   ASSERT_TRUE(t.Start());
    685   t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
    686 
    687   MessageLoop::current()->Run();
    688 
    689   net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
    690 }
    691 
    692 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) {
    693   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    694   ASSERT_TRUE(test_server.Start());
    695 
    696   GURL url(test_server.GetURL("files/server-unavailable.html"));
    697 
    698   // Register an entry for test url.
    699   // Using a sliding window of 4 seconds, and max of 1 request, under a fast
    700   // run we expect to have a 4 second delay when posting the Start task.
    701   net::URLRequestThrottlerManager* manager =
    702       net::URLRequestThrottlerManager::GetInstance();
    703   scoped_refptr<net::URLRequestThrottlerEntry> entry(
    704       new net::URLRequestThrottlerEntry(
    705           manager, 4000, 1, 2000, 2.0, 0.0, 4000));
    706   manager->OverrideEntryForTests(url, entry);
    707   // Fake that a request has just started.
    708   entry->ReserveSendingTimeForNextRequest(base::TimeTicks());
    709 
    710   // The next request we try to send will be delayed by ~4 seconds.
    711   // The slower the test runs, the less the delay will be (since it takes the
    712   // time difference from now).
    713 
    714   base::Thread t("URLFetcher test thread");
    715   ASSERT_TRUE(t.Start());
    716   t.message_loop()->PostTask(FROM_HERE, new FetcherWrapperTask(this, url));
    717 
    718   MessageLoop::current()->Run();
    719 
    720   net::URLRequestThrottlerManager::GetInstance()->EraseEntryForTests(url);
    721 }
    722 
    723 TEST_F(URLFetcherMultipleAttemptTest, SameData) {
    724   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    725   ASSERT_TRUE(test_server.Start());
    726 
    727   // Create the fetcher on the main thread.  Since IO will happen on the main
    728   // thread, this will test URLFetcher's ability to do everything on one
    729   // thread.
    730   CreateFetcher(test_server.GetURL("defaultresponse"));
    731 
    732   MessageLoop::current()->Run();
    733 }
    734 
    735 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers.
    736 TEST_F(URLFetcherTest, CancelAll) {
    737   net::TestServer test_server(net::TestServer::TYPE_HTTP, FilePath(kDocRoot));
    738   ASSERT_TRUE(test_server.Start());
    739   EXPECT_EQ(0, GetNumFetcherCores());
    740 
    741   CreateFetcher(test_server.GetURL("defaultresponse"));
    742   io_message_loop_proxy()->PostTask(
    743       FROM_HERE,
    744       new CurriedTask(new MessageLoop::QuitTask(), MessageLoop::current()));
    745   MessageLoop::current()->Run();
    746   EXPECT_EQ(1, GetNumFetcherCores());
    747   URLFetcher::CancelAll();
    748   EXPECT_EQ(0, GetNumFetcherCores());
    749   delete fetcher_;
    750 }
    751 
    752 }  // namespace.
    753