// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/url_request/url_fetcher_impl.h"

#include <string>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop_proxy.h"
#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/network_change_notifier.h"
#include "net/http/http_response_headers.h"
#include "net/test/test_server.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
#include "net/url_request/url_request_throttler_manager.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(USE_NSS) || defined(OS_IOS)
#include "net/ocsp/nss_ocsp.h"
#endif

namespace net {

using base::Time;
using base::TimeDelta;

// TODO(eroman): Add a regression test for http://crbug.com/40505.

namespace {

// TODO(akalin): Move all the test data to somewhere under net/.
const FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data");
const char kTestServerFilePrefix[] = "files/";

class ThrottlingTestURLRequestContext : public TestURLRequestContext {
 public:
  ThrottlingTestURLRequestContext() : TestURLRequestContext(true) {
    set_throttler_manager(&throttler_manager_);
    Init();
    DCHECK(throttler_manager() != NULL);
  }

 private:
  URLRequestThrottlerManager throttler_manager_;
};

class ThrottlingTestURLRequestContextGetter
    : public TestURLRequestContextGetter {
 public:
  ThrottlingTestURLRequestContextGetter(
      base::MessageLoopProxy* io_message_loop_proxy,
      TestURLRequestContext* request_context)
      : TestURLRequestContextGetter(io_message_loop_proxy),
        context_(request_context) {
  }

  // TestURLRequestContextGetter:
  virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE {
    return context_;
  }

 protected:
  virtual ~ThrottlingTestURLRequestContextGetter() {}

  TestURLRequestContext* const context_;
};

}  // namespace

class URLFetcherTest : public testing::Test,
                       public URLFetcherDelegate {
 public:
  URLFetcherTest()
      : fetcher_(NULL),
        context_(NULL) {
  }

  static int GetNumFetcherCores() {
    return URLFetcherImpl::GetNumFetcherCores();
  }

  // Creates a URLFetcher, using the program's main thread to do IO.
  virtual void CreateFetcher(const GURL& url);

  // URLFetcherDelegate:
  // Subclasses that override this should either call this function or
  // CleanupAfterFetchComplete() at the end of their processing, depending on
  // whether they want to check for a non-empty HTTP 200 response or not.
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

  // Deletes |fetcher| and terminates the message loop.
  void CleanupAfterFetchComplete();

  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
    return io_message_loop_proxy_;
  }

  TestURLRequestContext* request_context() {
    return context_.get();
  }

 protected:
  // testing::Test:
  virtual void SetUp() OVERRIDE {
    testing::Test::SetUp();

    context_.reset(new ThrottlingTestURLRequestContext());
    io_message_loop_proxy_ = base::MessageLoopProxy::current();

#if defined(USE_NSS) || defined(OS_IOS)
    crypto::EnsureNSSInit();
    EnsureNSSHttpIOInit();
#endif
  }

  virtual void TearDown() OVERRIDE {
#if defined(USE_NSS) || defined(OS_IOS)
    ShutdownNSSHttpIO();
#endif
  }

  // URLFetcher is designed to run on the main UI thread, but in our tests
  // we assume that the current thread is the IO thread where the URLFetcher
  // dispatches its requests to.  When we wish to simulate being used from
  // a UI thread, we dispatch a worker thread to do so.
  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;

  URLFetcherImpl* fetcher_;
  scoped_ptr<TestURLRequestContext> context_;
};

// A test fixture that uses a MockHostResolver, so that name resolutions can
// be manipulated by the tests to keep connections in the resolving state.
class URLFetcherMockDnsTest : public URLFetcherTest {
 public:
  // testing::Test:
  virtual void SetUp() OVERRIDE;

  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

 protected:
  GURL test_url_;
  scoped_ptr<TestServer> test_server_;
  MockHostResolver resolver_;
  scoped_ptr<URLFetcher> completed_fetcher_;
};

void URLFetcherTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  fetcher_->Start();
}

void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) {
  EXPECT_TRUE(source->GetStatus().is_success());
  EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK

  std::string data;
  EXPECT_TRUE(source->GetResponseAsString(&data));
  EXPECT_FALSE(data.empty());

  CleanupAfterFetchComplete();
}

void URLFetcherTest::CleanupAfterFetchComplete() {
  delete fetcher_;  // Have to delete this here and not in the destructor,
                    // because the destructor won't necessarily run on the
                    // same thread that CreateFetcher() did.

  io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
  // If the current message loop is not the IO loop, it will be shut down when
  // the main loop returns and this thread subsequently goes out of scope.
}

void URLFetcherMockDnsTest::SetUp() {
  URLFetcherTest::SetUp();

  resolver_.set_ondemand_mode(true);
  resolver_.rules()->AddRule("example.com", "127.0.0.1");

  context_.reset(new TestURLRequestContext(true));
  context_->set_host_resolver(&resolver_);
  context_->Init();

  test_server_.reset(new TestServer(TestServer::TYPE_HTTP,
                                    TestServer::kLocalhost,
                                    FilePath(kDocRoot)));
  ASSERT_TRUE(test_server_->Start());

  // test_server_.GetURL() returns a URL with 127.0.0.1 (kLocalhost), that is
  // immediately resolved by the MockHostResolver. Use a hostname instead to
  // trigger an async resolve.
  test_url_ = GURL(
      base::StringPrintf("http://example.com:%d/defaultresponse",
      test_server_->host_port_pair().port()));
  ASSERT_TRUE(test_url_.is_valid());
}

void URLFetcherMockDnsTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
}

void URLFetcherMockDnsTest::OnURLFetchComplete(const URLFetcher* source) {
  io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
  ASSERT_EQ(fetcher_, source);
  EXPECT_EQ(test_url_, source->GetOriginalURL());
  completed_fetcher_.reset(fetcher_);
}

namespace {

// Version of URLFetcherTest that does a POST instead
class URLFetcherPostTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
};

// Version of URLFetcherTest that does a POST instead with empty upload body
class URLFetcherEmptyPostTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
};

// Version of URLFetcherTest that tests download progress reports.
class URLFetcherDownloadProgressTest : public URLFetcherTest {
 public:
  URLFetcherDownloadProgressTest()
      : previous_progress_(0),
        expected_total_(0) {
  }

  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchDownloadProgress(const URLFetcher* source,
                                          int64 current,
                                          int64 total) OVERRIDE;

 protected:
  // Download progress returned by the previous callback.
  int64 previous_progress_;
  // Size of the file being downloaded, known in advance (provided by each test
  // case).
  int64 expected_total_;
};

// Version of URLFetcherTest that tests progress reports at cancellation.
class URLFetcherDownloadProgressCancelTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
  virtual void OnURLFetchDownloadProgress(const URLFetcher* source,
                                          int64 current,
                                          int64 total) OVERRIDE;
 protected:
  bool cancelled_;
};

// Version of URLFetcherTest that tests upload progress reports.
class URLFetcherUploadProgressTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchUploadProgress(const URLFetcher* source,
                                        int64 current,
                                        int64 total) OVERRIDE;
 protected:
  int64 previous_progress_;
  std::string chunk_;
  int64 number_of_chunks_added_;
};

// Version of URLFetcherTest that tests headers.
class URLFetcherHeadersTest : public URLFetcherTest {
 public:
  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
};

// Version of URLFetcherTest that tests SocketAddress.
class URLFetcherSocketAddressTest : public URLFetcherTest {
 public:
  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
 protected:
  std::string expected_host_;
  uint16 expected_port_;
};

// Version of URLFetcherTest that tests stopping on a redirect.
class URLFetcherStopOnRedirectTest : public URLFetcherTest {
 public:
  URLFetcherStopOnRedirectTest();
  virtual ~URLFetcherStopOnRedirectTest();

  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

 protected:
  // The URL we should be redirected to.
  static const char* kRedirectTarget;

  bool callback_called_;  // Set to true in OnURLFetchComplete().
};

// Version of URLFetcherTest that tests overload protection.
class URLFetcherProtectTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
 private:
  Time start_time_;
};

// Version of URLFetcherTest that tests overload protection, when responses
// passed through.
class URLFetcherProtectTestPassedThrough : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
 private:
  Time start_time_;
};

// Version of URLFetcherTest that tests bad HTTPS requests.
class URLFetcherBadHTTPSTest : public URLFetcherTest {
 public:
  URLFetcherBadHTTPSTest();

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

 private:
  FilePath cert_dir_;
};

// Version of URLFetcherTest that tests request cancellation on shutdown.
class URLFetcherCancelTest : public URLFetcherTest {
 public:
  // URLFetcherTest:
  virtual void CreateFetcher(const GURL& url) OVERRIDE;

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

  void CancelRequest();
};

// Version of TestURLRequestContext that posts a Quit task to the IO
// thread once it is deleted.
class CancelTestURLRequestContext : public ThrottlingTestURLRequestContext {
 public:
  explicit CancelTestURLRequestContext() {
  }

 private:
  virtual ~CancelTestURLRequestContext() {
    // The d'tor should execute in the IO thread. Post the quit task to the
    // current thread.
    MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
  }
};

class CancelTestURLRequestContextGetter
    : public TestURLRequestContextGetter {
 public:
  CancelTestURLRequestContextGetter(
      base::MessageLoopProxy* io_message_loop_proxy,
      const GURL& throttle_for_url)
      : TestURLRequestContextGetter(io_message_loop_proxy),
        io_message_loop_proxy_(io_message_loop_proxy),
        context_created_(false, false),
        throttle_for_url_(throttle_for_url) {
  }

  // TestURLRequestContextGetter:
  virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE {
    if (!context_.get()) {
      context_.reset(new CancelTestURLRequestContext());
      DCHECK(context_->throttler_manager());

      // Registers an entry for test url. The backoff time is calculated by:
      //     new_backoff = 2.0 * old_backoff + 0
      // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
      // Maximum retries allowed is set to 2.
      scoped_refptr<URLRequestThrottlerEntry> entry(
          new URLRequestThrottlerEntry(
              context_->throttler_manager(),
              "", 200, 3, 2000, 2.0, 0.0, 4000));
      context_->throttler_manager()->OverrideEntryForTests(
          throttle_for_url_, entry);

      context_created_.Signal();
    }
    return context_.get();
  }

  virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const {
    return io_message_loop_proxy_;
  }

  void WaitForContextCreation() {
    context_created_.Wait();
  }

 protected:
  virtual ~CancelTestURLRequestContextGetter() {}

 private:
  scoped_ptr<TestURLRequestContext> context_;
  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
  base::WaitableEvent context_created_;
  GURL throttle_for_url_;
};

// Version of URLFetcherTest that tests retying the same request twice.
class URLFetcherMultipleAttemptTest : public URLFetcherTest {
 public:
  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
 private:
  std::string data_;
};

class URLFetcherFileTest : public URLFetcherTest {
 public:
  URLFetcherFileTest() : take_ownership_of_file_(false),
                         expected_file_error_(base::PLATFORM_FILE_OK) {}

  void CreateFetcherForFile(const GURL& url, const FilePath& file_path);
  void CreateFetcherForTempFile(const GURL& url);

  // URLFetcherDelegate:
  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;

 protected:
  FilePath expected_file_;
  FilePath file_path_;

  // Set by the test. Used in OnURLFetchComplete() to decide if
  // the URLFetcher should own the temp file, so that we can test
  // disowning prevents the file from being deleted.
  bool take_ownership_of_file_;

  // Expected file error code for the test.
  // PLATFORM_FILE_OK when expecting success.
  base::PlatformFileError expected_file_error_;
};

void URLFetcherPostTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  fetcher_->SetUploadData("application/x-www-form-urlencoded",
                          "bobsyeruncle");
  fetcher_->Start();
}

void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source) {
  std::string data;
  EXPECT_TRUE(source->GetResponseAsString(&data));
  EXPECT_EQ(std::string("bobsyeruncle"), data);
  URLFetcherTest::OnURLFetchComplete(source);
}

void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
  fetcher_->SetRequestContext(new TestURLRequestContextGetter(
      io_message_loop_proxy()));
  fetcher_->SetUploadData("text/plain", "");
  fetcher_->Start();
}

void URLFetcherEmptyPostTest::OnURLFetchComplete(const URLFetcher* source) {
  EXPECT_TRUE(source->GetStatus().is_success());
  EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK

  std::string data;
  EXPECT_TRUE(source->GetResponseAsString(&data));
  EXPECT_TRUE(data.empty());

  CleanupAfterFetchComplete();
  // Do not call the super class method URLFetcherTest::OnURLFetchComplete,
  // since it expects a non-empty response.
}

void URLFetcherDownloadProgressTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  fetcher_->Start();
}

void URLFetcherDownloadProgressTest::OnURLFetchDownloadProgress(
    const URLFetcher* source, int64 progress, int64 total) {
  // Increasing between 0 and total.
  EXPECT_LE(0, progress);
  EXPECT_GE(total, progress);
  EXPECT_LE(previous_progress_, progress);
  EXPECT_EQ(expected_total_, total);
  previous_progress_ = progress;
}

void URLFetcherDownloadProgressCancelTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  cancelled_ = false;
  fetcher_->Start();
}

void URLFetcherDownloadProgressCancelTest::OnURLFetchDownloadProgress(
    const URLFetcher* source, int64 current, int64 total) {
  EXPECT_FALSE(cancelled_);
  if (!cancelled_) {
    cancelled_ = true;
    CleanupAfterFetchComplete();
  }
}

void URLFetcherDownloadProgressCancelTest::OnURLFetchComplete(
    const URLFetcher* source) {
  // Should have been cancelled.
  ADD_FAILURE();
  CleanupAfterFetchComplete();
}

void URLFetcherUploadProgressTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  previous_progress_ = 0;
  // Large enough data to require more than one read from UploadDataStream.
  chunk_.assign(1<<16, 'a');
  // Use chunked upload to wait for a timer event of progress notification.
  fetcher_->SetChunkedUpload("application/x-www-form-urlencoded");
  fetcher_->Start();
  number_of_chunks_added_ = 1;
  fetcher_->AppendChunkToUpload(chunk_, false);
}

void URLFetcherUploadProgressTest::OnURLFetchUploadProgress(
    const URLFetcher* source, int64 current, int64 total) {
  // Increasing between 0 and total.
  EXPECT_LE(0, current);
  EXPECT_GE(static_cast<int64>(chunk_.size()) * number_of_chunks_added_,
            current);
  EXPECT_LE(previous_progress_, current);
  previous_progress_ = current;
  EXPECT_EQ(-1, total);

  if (number_of_chunks_added_ < 2) {
    number_of_chunks_added_ += 1;
    fetcher_->AppendChunkToUpload(chunk_, true);
  }
}

void URLFetcherHeadersTest::OnURLFetchComplete(
    const URLFetcher* source) {
  std::string header;
  EXPECT_TRUE(source->GetResponseHeaders()->GetNormalizedHeader("cache-control",
                                                                &header));
  EXPECT_EQ("private", header);
  URLFetcherTest::OnURLFetchComplete(source);
}

void URLFetcherSocketAddressTest::OnURLFetchComplete(
    const URLFetcher* source) {
  EXPECT_EQ("127.0.0.1", source->GetSocketAddress().host());
  EXPECT_EQ(expected_port_, source->GetSocketAddress().port());
  URLFetcherTest::OnURLFetchComplete(source);
}

// static
const char* URLFetcherStopOnRedirectTest::kRedirectTarget =
    "http://redirect.target.com";

URLFetcherStopOnRedirectTest::URLFetcherStopOnRedirectTest()
    : callback_called_(false) {
}

URLFetcherStopOnRedirectTest::~URLFetcherStopOnRedirectTest() {
}

void URLFetcherStopOnRedirectTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  fetcher_->SetStopOnRedirect(true);
  fetcher_->Start();
}

void URLFetcherStopOnRedirectTest::OnURLFetchComplete(
    const URLFetcher* source) {
  callback_called_ = true;
  EXPECT_EQ(GURL(kRedirectTarget), source->GetURL());
  EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status());
  EXPECT_EQ(ERR_ABORTED, source->GetStatus().error());
  EXPECT_EQ(301, source->GetResponseCode());
  CleanupAfterFetchComplete();
}

void URLFetcherProtectTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  start_time_ = Time::Now();
  fetcher_->SetMaxRetriesOn5xx(11);
  fetcher_->Start();
}

void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source) {
  const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
  if (source->GetResponseCode() >= 500) {
    // Now running ServerUnavailable test.
    // It takes more than 1 second to finish all 11 requests.
    EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
    EXPECT_TRUE(source->GetStatus().is_success());
    std::string data;
    EXPECT_TRUE(source->GetResponseAsString(&data));
    EXPECT_FALSE(data.empty());
    CleanupAfterFetchComplete();
  } else {
    // Now running Overload test.
    static int count = 0;
    count++;
    if (count < 20) {
      fetcher_->SetRequestContext(
          new ThrottlingTestURLRequestContextGetter(
              io_message_loop_proxy(), request_context()));
      fetcher_->Start();
    } else {
      // We have already sent 20 requests continuously. And we expect that
      // it takes more than 1 second due to the overload protection settings.
      EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
      URLFetcherTest::OnURLFetchComplete(source);
    }
  }
}

void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));
  fetcher_->SetAutomaticallyRetryOn5xx(false);
  start_time_ = Time::Now();
  fetcher_->SetMaxRetriesOn5xx(11);
  fetcher_->Start();
}

void URLFetcherProtectTestPassedThrough::OnURLFetchComplete(
    const URLFetcher* source) {
  const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000);
  if (source->GetResponseCode() >= 500) {
    // Now running ServerUnavailable test.
    // It should get here on the first attempt, so almost immediately and
    // *not* to attempt to execute all 11 requests (2.5 minutes).
    EXPECT_TRUE(Time::Now() - start_time_ < one_minute);
    EXPECT_TRUE(source->GetStatus().is_success());
    // Check that suggested back off time is bigger than 0.
    EXPECT_GT(fetcher_->GetBackoffDelay().InMicroseconds(), 0);
    std::string data;
    EXPECT_TRUE(source->GetResponseAsString(&data));
    EXPECT_FALSE(data.empty());
  } else {
    // We should not get here!
    ADD_FAILURE();
  }

  CleanupAfterFetchComplete();
}


URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() {
  PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
  cert_dir_ = cert_dir_.AppendASCII("chrome");
  cert_dir_ = cert_dir_.AppendASCII("test");
  cert_dir_ = cert_dir_.AppendASCII("data");
  cert_dir_ = cert_dir_.AppendASCII("ssl");
  cert_dir_ = cert_dir_.AppendASCII("certificates");
}

// The "server certificate expired" error should result in automatic
// cancellation of the request by
// URLRequest::Delegate::OnSSLCertificateError.
void URLFetcherBadHTTPSTest::OnURLFetchComplete(
    const URLFetcher* source) {
  // This part is different from URLFetcherTest::OnURLFetchComplete
  // because this test expects the request to be cancelled.
  EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status());
  EXPECT_EQ(ERR_ABORTED, source->GetStatus().error());
  EXPECT_EQ(-1, source->GetResponseCode());
  EXPECT_TRUE(source->GetCookies().empty());
  std::string data;
  EXPECT_TRUE(source->GetResponseAsString(&data));
  EXPECT_TRUE(data.empty());
  CleanupAfterFetchComplete();
}

void URLFetcherCancelTest::CreateFetcher(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  CancelTestURLRequestContextGetter* context_getter =
      new CancelTestURLRequestContextGetter(io_message_loop_proxy(),
                                            url);
  fetcher_->SetRequestContext(context_getter);
  fetcher_->SetMaxRetriesOn5xx(2);
  fetcher_->Start();
  // We need to wait for the creation of the URLRequestContext, since we
  // rely on it being destroyed as a signal to end the test.
  context_getter->WaitForContextCreation();
  CancelRequest();
}

void URLFetcherCancelTest::OnURLFetchComplete(
    const URLFetcher* source) {
  // We should have cancelled the request before completion.
  ADD_FAILURE();
  CleanupAfterFetchComplete();
}

void URLFetcherCancelTest::CancelRequest() {
  delete fetcher_;
  // The URLFetcher's test context will post a Quit task once it is
  // deleted. So if this test simply hangs, it means cancellation
  // did not work.
}

void URLFetcherMultipleAttemptTest::OnURLFetchComplete(
    const URLFetcher* source) {
  EXPECT_TRUE(source->GetStatus().is_success());
  EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK
  std::string data;
  EXPECT_TRUE(source->GetResponseAsString(&data));
  EXPECT_FALSE(data.empty());
  if (!data.empty() && data_.empty()) {
    data_ = data;
    fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
        io_message_loop_proxy(), request_context()));
    fetcher_->Start();
  } else {
    EXPECT_EQ(data, data_);
    CleanupAfterFetchComplete();
  }
}

void URLFetcherFileTest::CreateFetcherForFile(const GURL& url,
                                              const FilePath& file_path) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));

  // Use the IO message loop to do the file operations in this test.
  fetcher_->SaveResponseToFileAtPath(file_path, io_message_loop_proxy());
  fetcher_->Start();
}

void URLFetcherFileTest::CreateFetcherForTempFile(const GURL& url) {
  fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
  fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
      io_message_loop_proxy(), request_context()));

  // Use the IO message loop to do the file operations in this test.
  fetcher_->SaveResponseToTemporaryFile(io_message_loop_proxy());
  fetcher_->Start();
}

void URLFetcherFileTest::OnURLFetchComplete(const URLFetcher* source) {
  if (expected_file_error_ == base::PLATFORM_FILE_OK) {
    EXPECT_TRUE(source->GetStatus().is_success());
    EXPECT_EQ(source->GetResponseCode(), 200);

    base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
    EXPECT_FALSE(fetcher_->FileErrorOccurred(&error_code));

    EXPECT_TRUE(source->GetResponseAsFilePath(
        take_ownership_of_file_, &file_path_));

    EXPECT_TRUE(file_util::ContentsEqual(expected_file_, file_path_));
  } else {
    base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
    EXPECT_TRUE(fetcher_->FileErrorOccurred(&error_code));
    EXPECT_EQ(expected_file_error_, error_code);
  }
  CleanupAfterFetchComplete();
}

TEST_F(URLFetcherTest, SameThreadsTest) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Create the fetcher on the main thread.  Since IO will happen on the main
  // thread, this will test URLFetcher's ability to do everything on one
  // thread.
  CreateFetcher(test_server.GetURL("defaultresponse"));

  MessageLoop::current()->Run();
}

#if defined(OS_MACOSX)
// SIGSEGV on Mac: http://crbug.com/60426
TEST_F(URLFetcherTest, DISABLED_DifferentThreadsTest) {
#else
TEST_F(URLFetcherTest, DifferentThreadsTest) {
#endif
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Create a separate thread that will create the URLFetcher.  The current
  // (main) thread will do the IO, and when the fetch is complete it will
  // terminate the main thread's message loop; then the other thread's
  // message loop will be shut down automatically as the thread goes out of
  // scope.
  base::Thread t("URLFetcher test thread");
  ASSERT_TRUE(t.Start());
  t.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&URLFetcherTest::CreateFetcher,
                 base::Unretained(this),
                 test_server.GetURL("defaultresponse")));

  MessageLoop::current()->Run();
}

void CancelAllOnIO() {
  EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores());
  URLFetcherImpl::CancelAll();
  EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores());
}

// Tests to make sure CancelAll() will successfully cancel existing URLFetchers.
TEST_F(URLFetcherTest, CancelAll) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());
  EXPECT_EQ(0, GetNumFetcherCores());

  CreateFetcher(test_server.GetURL("defaultresponse"));
  io_message_loop_proxy()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&CancelAllOnIO),
      MessageLoop::QuitClosure());
  MessageLoop::current()->Run();
  EXPECT_EQ(0, GetNumFetcherCores());
  delete fetcher_;
}

TEST_F(URLFetcherMockDnsTest, DontRetryOnNetworkChangedByDefault) {
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());

  // This posts a task to start the fetcher.
  CreateFetcher(test_url_);
  fetcher_->Start();
  EXPECT_EQ(0, GetNumFetcherCores());
  MessageLoop::current()->RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(resolver_.has_pending_requests());
  ASSERT_FALSE(completed_fetcher_);

  // A network change notification aborts the connect job.
  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
  MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());
  ASSERT_TRUE(completed_fetcher_);

  // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
  EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error());
}

TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndFail) {
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());

  // This posts a task to start the fetcher.
  CreateFetcher(test_url_);
  fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
  fetcher_->Start();
  EXPECT_EQ(0, GetNumFetcherCores());
  MessageLoop::current()->RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(resolver_.has_pending_requests());
  ASSERT_FALSE(completed_fetcher_);

  // Make it fail 3 times.
  for (int i = 0; i < 3; ++i) {
    // A network change notification aborts the connect job.
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    MessageLoop::current()->RunUntilIdle();

    // But the fetcher retries automatically.
    EXPECT_EQ(1, GetNumFetcherCores());
    EXPECT_TRUE(resolver_.has_pending_requests());
    ASSERT_FALSE(completed_fetcher_);
  }

  // A 4th failure doesn't trigger another retry, and propagates the error
  // to the owner of the fetcher.
  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
  MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());
  ASSERT_TRUE(completed_fetcher_);

  // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
  EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error());
}

TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndSucceed) {
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());

  // This posts a task to start the fetcher.
  CreateFetcher(test_url_);
  fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
  fetcher_->Start();
  EXPECT_EQ(0, GetNumFetcherCores());
  MessageLoop::current()->RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(resolver_.has_pending_requests());
  ASSERT_FALSE(completed_fetcher_);

  // Make it fail 3 times.
  for (int i = 0; i < 3; ++i) {
    // A network change notification aborts the connect job.
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    MessageLoop::current()->RunUntilIdle();

    // But the fetcher retries automatically.
    EXPECT_EQ(1, GetNumFetcherCores());
    EXPECT_TRUE(resolver_.has_pending_requests());
    ASSERT_FALSE(completed_fetcher_);
  }

  // Now let it succeed by resolving the pending request.
  resolver_.ResolveAllPending();
  MessageLoop::current()->Run();

  // URLFetcherMockDnsTest::OnURLFetchComplete() will quit the loop.
  EXPECT_EQ(0, GetNumFetcherCores());
  EXPECT_FALSE(resolver_.has_pending_requests());
  ASSERT_TRUE(completed_fetcher_);

  // This time the request succeeded.
  EXPECT_EQ(OK, completed_fetcher_->GetStatus().error());
  EXPECT_EQ(200, completed_fetcher_->GetResponseCode());
}

#if defined(OS_MACOSX)
// SIGSEGV on Mac: http://crbug.com/60426
TEST_F(URLFetcherPostTest, DISABLED_Basic) {
#else
TEST_F(URLFetcherPostTest, Basic) {
#endif
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(test_server.GetURL("echo"));
  MessageLoop::current()->Run();
}

TEST_F(URLFetcherEmptyPostTest, Basic) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(test_server.GetURL("echo"));
  MessageLoop::current()->Run();
}

#if defined(OS_MACOSX)
// SIGSEGV on Mac: http://crbug.com/60426
TEST_F(URLFetcherUploadProgressTest, DISABLED_Basic) {
#else
TEST_F(URLFetcherUploadProgressTest, Basic) {
#endif
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(test_server.GetURL("echo"));
  MessageLoop::current()->Run();
}

TEST_F(URLFetcherDownloadProgressTest, Basic) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  static const char kFileToFetch[] = "animate1.gif";
  // Hardcoded file size - it cannot be easily fetched when a remote http server
  // is used for testing.
  static const int64 kFileSize = 19021;

  expected_total_ = kFileSize;

  CreateFetcher(test_server.GetURL(
      std::string(kTestServerFilePrefix) + kFileToFetch));

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherDownloadProgressCancelTest, CancelWhileProgressReport) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  static const char kFileToFetch[] = "animate1.gif";
  CreateFetcher(test_server.GetURL(
      std::string(kTestServerFilePrefix) + kFileToFetch));

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherHeadersTest, Headers) {
  TestServer test_server(
      TestServer::TYPE_HTTP,
      TestServer::kLocalhost,
      FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(test_server.GetURL("files/with-headers.html"));
  MessageLoop::current()->Run();
  // The actual tests are in the URLFetcherHeadersTest fixture.
}

TEST_F(URLFetcherSocketAddressTest, SocketAddress) {
  TestServer test_server(
      TestServer::TYPE_HTTP,
      TestServer::kLocalhost,
      FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
  ASSERT_TRUE(test_server.Start());
  expected_port_ = test_server.host_port_pair().port();

  // Reusing "with-headers.html" but doesn't really matter.
  CreateFetcher(test_server.GetURL("files/with-headers.html"));
  MessageLoop::current()->Run();
  // The actual tests are in the URLFetcherSocketAddressTest fixture.
}

TEST_F(URLFetcherStopOnRedirectTest, StopOnRedirect) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(
      test_server.GetURL(std::string("server-redirect?") + kRedirectTarget));
  MessageLoop::current()->Run();
  EXPECT_TRUE(callback_called_);
}

TEST_F(URLFetcherProtectTest, Overload) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  GURL url(test_server.GetURL("defaultresponse"));

  // Registers an entry for test url. It only allows 3 requests to be sent
  // in 200 milliseconds.
  scoped_refptr<URLRequestThrottlerEntry> entry(
      new URLRequestThrottlerEntry(
          request_context()->throttler_manager(),
          "", 200, 3, 1, 2.0, 0.0, 256));
  request_context()->throttler_manager()->OverrideEntryForTests(url, entry);

  CreateFetcher(url);

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherProtectTest, ServerUnavailable) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  GURL url(test_server.GetURL("files/server-unavailable.html"));

  // Registers an entry for test url. The backoff time is calculated by:
  //     new_backoff = 2.0 * old_backoff + 0
  // and maximum backoff time is 256 milliseconds.
  // Maximum retries allowed is set to 11.
  scoped_refptr<URLRequestThrottlerEntry> entry(
      new URLRequestThrottlerEntry(
          request_context()->throttler_manager(),
          "", 200, 3, 1, 2.0, 0.0, 256));
  request_context()->throttler_manager()->OverrideEntryForTests(url, entry);

  CreateFetcher(url);

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  GURL url(test_server.GetURL("files/server-unavailable.html"));

  // Registers an entry for test url. The backoff time is calculated by:
  //     new_backoff = 2.0 * old_backoff + 0
  // and maximum backoff time is 150000 milliseconds.
  // Maximum retries allowed is set to 11.
  scoped_refptr<URLRequestThrottlerEntry> entry(
      new URLRequestThrottlerEntry(
          request_context()->throttler_manager(),
          "", 200, 3, 100, 2.0, 0.0, 150000));
  // Total time if *not* for not doing automatic backoff would be 150s.
  // In reality it should be "as soon as server responds".
  request_context()->throttler_manager()->OverrideEntryForTests(url, entry);

  CreateFetcher(url);

  MessageLoop::current()->Run();
}

#if defined(OS_MACOSX)
// SIGSEGV on Mac: http://crbug.com/60426
TEST_F(URLFetcherBadHTTPSTest, DISABLED_BadHTTPSTest) {
#else
TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) {
#endif
  TestServer::SSLOptions ssl_options(
      TestServer::SSLOptions::CERT_EXPIRED);
  TestServer test_server(TestServer::TYPE_HTTPS,
                         ssl_options,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  CreateFetcher(test_server.GetURL("defaultresponse"));
  MessageLoop::current()->Run();
}

#if defined(OS_MACOSX)
// SIGSEGV on Mac: http://crbug.com/60426
TEST_F(URLFetcherCancelTest, DISABLED_ReleasesContext) {
#else
TEST_F(URLFetcherCancelTest, ReleasesContext) {
#endif
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  GURL url(test_server.GetURL("files/server-unavailable.html"));

  // Create a separate thread that will create the URLFetcher.  The current
  // (main) thread will do the IO, and when the fetch is complete it will
  // terminate the main thread's message loop; then the other thread's
  // message loop will be shut down automatically as the thread goes out of
  // scope.
  base::Thread t("URLFetcher test thread");
  ASSERT_TRUE(t.Start());
  t.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&URLFetcherCancelTest::CreateFetcher,
                 base::Unretained(this), url));

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  GURL url(test_server.GetURL("files/server-unavailable.html"));

  // Register an entry for test url.
  // Using a sliding window of 4 seconds, and max of 1 request, under a fast
  // run we expect to have a 4 second delay when posting the Start task.
  scoped_refptr<URLRequestThrottlerEntry> entry(
      new URLRequestThrottlerEntry(
          request_context()->throttler_manager(),
          "", 4000, 1, 2000, 2.0, 0.0, 4000));
  request_context()->throttler_manager()->OverrideEntryForTests(url, entry);
  // Fake that a request has just started.
  entry->ReserveSendingTimeForNextRequest(base::TimeTicks());

  // The next request we try to send will be delayed by ~4 seconds.
  // The slower the test runs, the less the delay will be (since it takes the
  // time difference from now).

  base::Thread t("URLFetcher test thread");
  ASSERT_TRUE(t.Start());
  t.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url));

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherMultipleAttemptTest, SameData) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Create the fetcher on the main thread.  Since IO will happen on the main
  // thread, this will test URLFetcher's ability to do everything on one
  // thread.
  CreateFetcher(test_server.GetURL("defaultresponse"));

  MessageLoop::current()->Run();
}

TEST_F(URLFetcherFileTest, SmallGet) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Get a small file.
  static const char kFileToFetch[] = "simple.html";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      temp_dir.path().AppendASCII(kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().

  ASSERT_FALSE(file_util::PathExists(file_path_))
      << file_path_.value() << " not removed.";
}

TEST_F(URLFetcherFileTest, LargeGet) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  static const char kFileToFetch[] = "animate1.gif";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      temp_dir.path().AppendASCII(kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
}

TEST_F(URLFetcherFileTest, CanTakeOwnershipOfFile) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Get a small file.
  static const char kFileToFetch[] = "simple.html";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      temp_dir.path().AppendASCII(kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().

  MessageLoop::current()->RunUntilIdle();
  ASSERT_FALSE(file_util::PathExists(file_path_))
      << file_path_.value() << " not removed.";
}


TEST_F(URLFetcherFileTest, OverwriteExistingFile) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Create a file before trying to fetch.
  static const char kFileToFetch[] = "simple.html";
  static const char kData[] = "abcdefghijklmnopqrstuvwxyz";
  file_path_ = temp_dir.path().AppendASCII(kFileToFetch);
  const int data_size = arraysize(kData);
  ASSERT_EQ(file_util::WriteFile(file_path_, kData, data_size), data_size);
  ASSERT_TRUE(file_util::PathExists(file_path_));
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  ASSERT_FALSE(file_util::ContentsEqual(file_path_, expected_file_));

  // Get a small file.
  CreateFetcherForFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      file_path_);

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
}

TEST_F(URLFetcherFileTest, TryToOverwriteDirectory) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Create a directory before trying to fetch.
  static const char kFileToFetch[] = "simple.html";
  file_path_ = temp_dir.path().AppendASCII(kFileToFetch);
  ASSERT_TRUE(file_util::CreateDirectory(file_path_));
  ASSERT_TRUE(file_util::PathExists(file_path_));

  // Get a small file.
  expected_file_error_ = base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      file_path_);

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().

  MessageLoop::current()->RunUntilIdle();
}

TEST_F(URLFetcherFileTest, SmallGetToTempFile) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Get a small file.
  static const char kFileToFetch[] = "simple.html";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForTempFile(
      test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().

  ASSERT_FALSE(file_util::PathExists(file_path_))
      << file_path_.value() << " not removed.";
}

TEST_F(URLFetcherFileTest, LargeGetToTempFile) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  static const char kFileToFetch[] = "animate1.gif";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForTempFile(test_server.GetURL(
      std::string(kTestServerFilePrefix) + kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
}

TEST_F(URLFetcherFileTest, CanTakeOwnershipOfTempFile) {
  TestServer test_server(TestServer::TYPE_HTTP,
                         TestServer::kLocalhost,
                         FilePath(kDocRoot));
  ASSERT_TRUE(test_server.Start());

  // Get a small file.
  static const char kFileToFetch[] = "simple.html";
  expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
  CreateFetcherForTempFile(test_server.GetURL(
      std::string(kTestServerFilePrefix) + kFileToFetch));

  MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().

  MessageLoop::current()->RunUntilIdle();
  ASSERT_FALSE(file_util::PathExists(file_path_))
      << file_path_.value() << " not removed.";
}

}  // namespace

}  // namespace net
