// 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/proxy_resolution/proxy_resolution_service.h"

#include <cstdarg>
#include <string>
#include <vector>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/proxy_resolution/dhcp_pac_file_fetcher.h"
#include "net/proxy_resolution/mock_pac_file_fetcher.h"
#include "net/proxy_resolution/mock_proxy_resolver.h"
#include "net/proxy_resolution/pac_file_fetcher.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using testing::ElementsAre;
using testing::Key;

using net::test::IsError;
using net::test::IsOk;

using base::ASCIIToUTF16;

// TODO(eroman): Write a test which exercises
//              ProxyResolutionService::SuspendAllPendingRequests().
namespace net {
namespace {

// This polling policy will decide to poll every 1 ms.
class ImmediatePollPolicy : public ProxyResolutionService::PacPollPolicy {
 public:
  ImmediatePollPolicy() = default;

  Mode GetNextDelay(int error,
                    base::TimeDelta current_delay,
                    base::TimeDelta* next_delay) const override {
    *next_delay = base::TimeDelta::FromMilliseconds(1);
    return MODE_USE_TIMER;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
};

// This polling policy chooses a fantastically large delay. In other words, it
// will never trigger a poll
class NeverPollPolicy : public ProxyResolutionService::PacPollPolicy {
 public:
  NeverPollPolicy() = default;

  Mode GetNextDelay(int error,
                    base::TimeDelta current_delay,
                    base::TimeDelta* next_delay) const override {
    *next_delay = base::TimeDelta::FromDays(60);
    return MODE_USE_TIMER;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
};

// This polling policy starts a poll immediately after network activity.
class ImmediateAfterActivityPollPolicy
    : public ProxyResolutionService::PacPollPolicy {
 public:
  ImmediateAfterActivityPollPolicy() = default;

  Mode GetNextDelay(int error,
                    base::TimeDelta current_delay,
                    base::TimeDelta* next_delay) const override {
    *next_delay = base::TimeDelta();
    return MODE_START_AFTER_ACTIVITY;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
};

// This test fixture is used to partially disable the background polling done by
// the ProxyResolutionService (which it uses to detect whenever its PAC script
// contents or WPAD results have changed).
//
// We disable the feature by setting the poll interval to something really
// large, so it will never actually be reached even on the slowest bots that run
// these tests.
//
// We disable the polling in order to avoid any timing dependencies in the
// tests. If the bot were to run the tests very slowly and we hadn't disabled
// polling, then it might start a background re-try in the middle of our test
// and confuse our expectations leading to flaky failures.
//
// The tests which verify the polling code re-enable the polling behavior but
// are careful to avoid timing problems.
class ProxyResolutionServiceTest : public TestWithScopedTaskEnvironment {
 protected:
  void SetUp() override {
    testing::Test::SetUp();
    previous_policy_ =
        ProxyResolutionService::set_pac_script_poll_policy(&never_poll_policy_);
  }

  void TearDown() override {
    // Restore the original policy.
    ProxyResolutionService::set_pac_script_poll_policy(previous_policy_);
    testing::Test::TearDown();
  }

 private:
  NeverPollPolicy never_poll_policy_;
  const ProxyResolutionService::PacPollPolicy* previous_policy_;
};

const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";

class MockProxyConfigService: public ProxyConfigService {
 public:
  explicit MockProxyConfigService(const ProxyConfig& config)
      : availability_(CONFIG_VALID),
        config_(
            ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)) {}

  explicit MockProxyConfigService(const std::string& pac_url)
      : availability_(CONFIG_VALID),
        config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url)),
                TRAFFIC_ANNOTATION_FOR_TESTS) {}

  void AddObserver(Observer* observer) override {
    observers_.AddObserver(observer);
  }

  void RemoveObserver(Observer* observer) override {
    observers_.RemoveObserver(observer);
  }

  ConfigAvailability GetLatestProxyConfig(
      ProxyConfigWithAnnotation* results) override {
    if (availability_ == CONFIG_VALID)
      *results = config_;
    return availability_;
  }

  void SetConfig(const ProxyConfigWithAnnotation& config) {
    availability_ = CONFIG_VALID;
    config_ = config;
    for (auto& observer : observers_)
      observer.OnProxyConfigChanged(config_, availability_);
  }

  void SetPacUrlConfig(base::StringPiece pac_url) {
    SetConfig(ProxyConfigWithAnnotation(
        ProxyConfig::CreateFromCustomPacURL(GURL(pac_url)),
        TRAFFIC_ANNOTATION_FOR_TESTS));
  }

 private:
  ConfigAvailability availability_;
  ProxyConfigWithAnnotation config_;
  base::ObserverList<Observer, true>::Unchecked observers_;
};

// A test network delegate that exercises the OnResolveProxy callback.
class TestResolveProxyDelegate : public ProxyDelegate {
 public:
  void OnResolveProxy(const GURL& url,
                      const std::string& method,
                      const ProxyRetryInfoMap& proxy_retry_info,
                      ProxyInfo* result) override {
    method_ = method;
    num_resolve_proxy_called_++;
    proxy_retry_info_ = proxy_retry_info;
    DCHECK(!add_proxy_ || !remove_proxy_);
    if (add_proxy_) {
      result->UseNamedProxy("delegate_proxy.com");
    } else if (remove_proxy_) {
      result->UseDirect();
    }
  }

  int num_resolve_proxy_called() const { return num_resolve_proxy_called_; }

  const std::string& method() const { return method_; }

  void set_add_proxy(bool add_proxy) {
    add_proxy_ = add_proxy;
  }

  void set_remove_proxy(bool remove_proxy) {
    remove_proxy_ = remove_proxy;
  }

  const ProxyRetryInfoMap& proxy_retry_info() const {
    return proxy_retry_info_;
  }

  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}

 private:
  int num_resolve_proxy_called_ = 0;
  bool add_proxy_ = false;
  bool remove_proxy_ = false;
  std::string method_;
  ProxyRetryInfoMap proxy_retry_info_;
};

// A test network delegate that exercises the OnProxyFallback callback.
class TestProxyFallbackProxyDelegate : public ProxyDelegate {
 public:
  // ProxyDelegate implementation:
  void OnResolveProxy(const GURL& url,
                      const std::string& method,
                      const ProxyRetryInfoMap& proxy_retry_info,
                      ProxyInfo* result) override {}
  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {
    proxy_server_ = bad_proxy;
    last_proxy_fallback_net_error_ = net_error;
    num_proxy_fallback_called_++;
  }

  bool num_proxy_fallback_called() const { return num_proxy_fallback_called_; }

  const ProxyServer& proxy_server() const {
    return proxy_server_;
  }

  int last_proxy_fallback_net_error() const {
    return last_proxy_fallback_net_error_;
  }

 private:
  int num_proxy_fallback_called_ = 0;
  ProxyServer proxy_server_;
  int last_proxy_fallback_net_error_ = OK;
};

using JobMap = std::map<GURL, MockAsyncProxyResolver::Job*>;

// Given a jobmap and a list of target URLs |urls|, asserts that the set of URLs
// of the jobs appearing in |list| is exactly the set of URLs in |urls|.
JobMap GetJobsForURLs(const JobMap& map, const std::vector<GURL>& urls) {
  size_t a = urls.size();
  size_t b = map.size();
  if (a != b) {
    ADD_FAILURE() << "map size (" << map.size() << ") != urls size ("
                  << urls.size() << ")";
    return map;
  }
  for (const auto& it : urls) {
    if (map.count(it) != 1U) {
      ADD_FAILURE() << "url not in map: " << it.spec();
      break;
    }
  }
  return map;
}

// Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
// set of pending request URLs for |resolver| is exactly the supplied list of
// URLs and returns a map from URLs to the corresponding pending jobs.
JobMap GetPendingJobsForURLs(const MockAsyncProxyResolver& resolver,
                             const GURL& url1 = GURL(),
                             const GURL& url2 = GURL(),
                             const GURL& url3 = GURL()) {
  std::vector<GURL> urls;
  if (!url1.is_empty())
    urls.push_back(url1);
  if (!url2.is_empty())
    urls.push_back(url2);
  if (!url3.is_empty())
    urls.push_back(url3);

  JobMap map;
  for (MockAsyncProxyResolver::Job* it : resolver.pending_jobs()) {
    DCHECK(it);
    map[it->url()] = it;
  }

  return GetJobsForURLs(map, urls);
}

// Given a MockAsyncProxyResolver |resolver| and some GURLs, validates that the
// set of cancelled request URLs for |resolver| is exactly the supplied list of
// URLs and returns a map from URLs to the corresponding cancelled jobs.
JobMap GetCancelledJobsForURLs(const MockAsyncProxyResolver& resolver,
                               const GURL& url1 = GURL(),
                               const GURL& url2 = GURL(),
                               const GURL& url3 = GURL()) {
  std::vector<GURL> urls;
  if (!url1.is_empty())
    urls.push_back(url1);
  if (!url2.is_empty())
    urls.push_back(url2);
  if (!url3.is_empty())
    urls.push_back(url3);

  JobMap map;
  for (const std::unique_ptr<MockAsyncProxyResolver::Job>& it :
       resolver.cancelled_jobs()) {
    DCHECK(it);
    map[it->url()] = it.get();
  }

  return GetJobsForURLs(map, urls);
}

// Helper class to verify the bucket counts for PacUrlScheme histogram.
class PacUrlSchemeHistogramTester {
 public:
  void VerifyHistogram() const {
    const char kPacUrlSchemeHistogram[] =
        "Net.ProxyResolutionService.PacUrlScheme";

    int total = GetTotal();

    histograms_.ExpectTotalCount(kPacUrlSchemeHistogram, total);

    if (total > 0) {
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 0, num_other);
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 1, num_http);
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 2, num_https);
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 3, num_ftp);
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 4, num_file);
      histograms_.ExpectBucketCount(kPacUrlSchemeHistogram, 5, num_data);
    }
  }

  int num_http = 0;
  int num_https = 0;
  int num_ftp = 0;
  int num_data = 0;
  int num_file = 0;
  int num_other = 0;

 private:
  int GetTotal() const {
    return num_http + num_https + num_ftp + num_data + num_file + num_other;
  }

  base::HistogramTester histograms_;
};

}  // namespace

TEST_F(ProxyResolutionServiceTest, Direct) {
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(ProxyConfig::CreateDirect()),
      base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, log.bound());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(factory->pending_requests().empty());

  EXPECT_TRUE(info.is_direct());
  EXPECT_TRUE(info.proxy_resolve_start_time().is_null());
  EXPECT_TRUE(info.proxy_resolve_end_time().is_null());

  // Check the NetLog was filled correctly.
  TestNetLogEntry::List entries;
  log.GetEntries(&entries);

  EXPECT_EQ(3u, entries.size());
  EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
                                    NetLogEventType::PROXY_RESOLUTION_SERVICE));
  EXPECT_TRUE(LogContainsEvent(
      entries, 1, NetLogEventType::PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST,
      NetLogEventPhase::NONE));
  EXPECT_TRUE(LogContainsEndEvent(entries, 2,
                                  NetLogEventType::PROXY_RESOLUTION_SERVICE));
}

TEST_F(ProxyResolutionServiceTest, OnResolveProxyCallbackAddProxy) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString("badproxy:8080,foopy1:8080");
  config.set_auto_detect(false);
  config.proxy_rules().bypass_rules.ParseFromString("*.org");

  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);

  GURL url("http://www.google.com/");
  GURL bypass_url("http://internet.org");

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;

  // First, warm up the ProxyResolutionService and fake an error to mark the
  // first server as bad.
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, log.bound());
  EXPECT_THAT(rv, IsOk());
  EXPECT_EQ("badproxy:8080", info.proxy_server().ToURI());

  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  service.ReportSuccess(info);

  // Verify that network delegate is invoked.
  TestResolveProxyDelegate delegate;
  service.SetProxyDelegate(&delegate);
  rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request,
                            log.bound());
  EXPECT_EQ(1, delegate.num_resolve_proxy_called());
  EXPECT_THAT(delegate.proxy_retry_info(), ElementsAre(Key("badproxy:8080")));
  EXPECT_EQ(delegate.method(), "GET");

  // Verify that the ProxyDelegate's behavior is stateless across
  // invocations of ResolveProxy. Start by having the callback add a proxy
  // and checking that subsequent jobs are not affected.
  delegate.set_add_proxy(true);

  // Callback should interpose:
  rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request,
                            log.bound());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ(info.proxy_server().host_port_pair().host(), "delegate_proxy.com");
  delegate.set_add_proxy(false);

  // Check non-bypassed URL:
  rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request,
                            log.bound());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");

  // Check bypassed URL:
  rv = service.ResolveProxy(bypass_url, "GET", &info, callback.callback(),
                            &request, log.bound());
  EXPECT_TRUE(info.is_direct());
}

TEST_F(ProxyResolutionServiceTest, OnResolveProxyCallbackRemoveProxy) {
  // Same as OnResolveProxyCallbackAddProxy, but verify that the
  // ProxyDelegate's behavior is stateless across invocations after it
  // *removes* a proxy.
  ProxyConfig config;
  config.proxy_rules().ParseFromString("foopy1:8080");
  config.set_auto_detect(false);
  config.proxy_rules().bypass_rules.ParseFromString("*.org");

  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);

  GURL url("http://www.google.com/");
  GURL bypass_url("http://internet.org");

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;

  // First, warm up the ProxyResolutionService.
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, log.bound());
  EXPECT_THAT(rv, IsOk());

  TestResolveProxyDelegate delegate;
  service.SetProxyDelegate(&delegate);
  delegate.set_remove_proxy(true);

  // Callback should interpose:
  rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request,
                            log.bound());
  EXPECT_TRUE(info.is_direct());
  delegate.set_remove_proxy(false);

  // Check non-bypassed URL:
  rv = service.ResolveProxy(url, "GET", &info, callback.callback(), &request,
                            log.bound());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");

  // Check bypassed URL:
  rv = service.ResolveProxy(bypass_url, "GET", &info, callback.callback(),
                            &request, log.bound());
  EXPECT_TRUE(info.is_direct());
}

// Test callback that deletes an item when called.  This is used to test various
// permutations of important objects being deleted in the middle of a series of
// requests.
template <typename T>
class DeletingCallback : public TestCompletionCallbackBase {
 public:
  explicit DeletingCallback(std::unique_ptr<T>* deletee);
  ~DeletingCallback() override;

  CompletionOnceCallback callback() {
    return base::BindOnce(&DeletingCallback::DeleteItem,
                          base::Unretained(this));
  }

 private:
  void DeleteItem(int result) {
    deletee_->reset();
    SetResult(result);
  }

  std::unique_ptr<T>* deletee_;

  DISALLOW_COPY_AND_ASSIGN(DeletingCallback);
};

template <typename T>
DeletingCallback<T>::DeletingCallback(std::unique_ptr<T>* deletee)
    : deletee_(deletee) {}

template <typename T>
DeletingCallback<T>::~DeletingCallback() = default;

// Test that the ProxyResolutionService correctly handles the case where a
// request callback deletes another request.
TEST_F(ProxyResolutionServiceTest, CallbackDeletesRequest) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  std::unique_ptr<ProxyResolutionService> service =
      std::make_unique<ProxyResolutionService>(
          base::WrapUnique(config_service), base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");
  GURL url2("http://www.example.com/");

  ProxyInfo info;
  std::unique_ptr<ProxyResolutionService::Request> request, request2;
  DeletingCallback<ProxyResolutionService::Request> callback(&request2);
  net::CompletionOnceCallback callback2 =
      base::BindOnce([](int result) { ASSERT_FALSE(true); });

  int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(),
                                 &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  rv = service->ResolveProxy(url2, std::string(), &info, std::move(callback2),
                             &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Run pending requests.
  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(2u, resolver.pending_jobs().size());
  // Job order is nondeterministic, as requests are stored in an std::set, so
  // this loop figures out which one is the correct one to start.
  int deleting_job = 2;
  for (int i = 0; i < 2; i++) {
    if (resolver.pending_jobs()[i]->url() == url) {
      deleting_job = i;
      break;
    }
    ASSERT_LE(i, 1); // The loop should never actually make it to the end.
  }

  // Set the result in proxy resolver.
  resolver.pending_jobs()[deleting_job]->results()->UseNamedProxy("foopy");
  resolver.pending_jobs()[deleting_job]->CompleteNow(OK);

  //// Only one of the callbacks should have been run:
  EXPECT_TRUE(callback.have_result());
  EXPECT_THAT(callback.WaitForResult(), IsOk());

  ASSERT_EQ(0u, resolver.pending_jobs().size());
  ASSERT_EQ(1u, resolver.cancelled_jobs().size());
  ASSERT_EQ(url2, resolver.cancelled_jobs()[0]->url());
}

// Test that the ProxyResolutionService correctly handles the case where a
// request callback deletes another request.  (Triggered by the loop in
// ProxyResolutionService's destructor).
TEST_F(ProxyResolutionServiceTest, CallbackDeletesRequestDuringDestructor) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  std::unique_ptr<ProxyResolutionService> service =
      std::make_unique<ProxyResolutionService>(
          base::WrapUnique(config_service), base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  std::unique_ptr<ProxyResolutionService::Request> request, request2;
  DeletingCallback<ProxyResolutionService::Request> callback(&request2),
      callback2(&request);

  int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(),
                                 &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(),
                             &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Make sure that ProxyResolutionServices is deleted before the requests, as
  // this triggers completion of the pending requests.
  service.reset();

  // Only one of the callbacks should have been run:
  EXPECT_TRUE(callback.have_result() ^ callback2.have_result());

  // Callbacks run during destruction of ProxyResolutionService for Requests
  // that have not been started are called with net::ERR_ABORTED
  if (callback.have_result()) {
    EXPECT_THAT(callback.WaitForResult(),
                IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
  }
  if (callback2.have_result()) {
    EXPECT_THAT(callback2.WaitForResult(),
                IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
  }
}

// Test that the ProxyResolutionService correctly handles the case where a
// request callback deletes its own handle.
TEST_F(ProxyResolutionServiceTest, CallbackDeletesSelf) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  std::unique_ptr<ProxyResolutionService> service =
      std::make_unique<ProxyResolutionService>(
          base::WrapUnique(config_service), base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");
  ProxyInfo info;

  std::unique_ptr<ProxyResolutionService::Request> request1;
  TestCompletionCallback callback1;
  int rv =
      service->ResolveProxy(url, std::string(), &info, callback1.callback(),
                            &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  GURL url2("http://www.example.com/");
  std::unique_ptr<ProxyResolutionService::Request> request2;
  DeletingCallback<ProxyResolutionService::Request> callback2(&request2);
  rv = service->ResolveProxy(url2, std::string(), &info, callback2.callback(),
                             &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  std::unique_ptr<ProxyResolutionService::Request> request3;
  TestCompletionCallback callback3;
  rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(),
                             &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(3u, resolver.pending_jobs().size());
  // Job order is nondeterministic, as requests are stored in an std::set, so
  // this loop figures out which one is the correct one to start.
  int self_deleting_job = 3;
  for (int i = 0; i < 3; i++) {
    if (resolver.pending_jobs()[i]->url() == url2) {
      self_deleting_job = i;
      break;
    }
    ASSERT_LE(i, 2); // The loop should never actually make it to the end.
  }

  // Set the result in proxy resolver.
  resolver.pending_jobs()[self_deleting_job]->results()->UseNamedProxy("foopy");
  resolver.pending_jobs()[self_deleting_job]->CompleteNow(OK);

  ASSERT_EQ(2u, resolver.pending_jobs().size());
  ASSERT_EQ(0u, resolver.cancelled_jobs().size());
  ASSERT_EQ(url, resolver.pending_jobs()[0]->url());
  ASSERT_EQ(url, resolver.pending_jobs()[1]->url());
}

// Test that the ProxyResolutionService correctly handles the case where a
// request callback deletes its own handle, when triggered by
// ProxyResolutionService's destructor.
TEST_F(ProxyResolutionServiceTest, CallbackDeletesSelfDuringDestructor) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  std::unique_ptr<ProxyResolutionService> service =
      std::make_unique<ProxyResolutionService>(
          base::WrapUnique(config_service), base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");
  ProxyInfo info;

  std::unique_ptr<ProxyResolutionService::Request> request1;
  TestCompletionCallback callback1;
  int rv =
      service->ResolveProxy(url, std::string(), &info, callback1.callback(),
                            &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  std::unique_ptr<ProxyResolutionService::Request> request2;
  DeletingCallback<ProxyResolutionService::Request> callback2(&request2);
  rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(),
                             &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  std::unique_ptr<ProxyResolutionService::Request> request3;
  TestCompletionCallback callback3;
  rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(),
                             &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  service.reset();

  EXPECT_THAT(callback1.WaitForResult(),
              IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
  EXPECT_THAT(callback2.WaitForResult(),
              IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
  EXPECT_THAT(callback3.WaitForResult(),
              IsError(net::ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
}

TEST_F(ProxyResolutionServiceTest, ProxyServiceDeletedBeforeRequest) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  BoundTestNetLog log;

  int rv;
  {
    ProxyResolutionService service(base::WrapUnique(config_service),
                                   base::WrapUnique(factory), nullptr);
    rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                              &request, log.bound());
    EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

    EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->GetLoadState());

    ASSERT_EQ(1u, factory->pending_requests().size());
    EXPECT_EQ(GURL("http://foopy/proxy.pac"),
              factory->pending_requests()[0]->script_data()->url());
    factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
    ASSERT_EQ(1u, resolver.pending_jobs().size());
  }

  ASSERT_EQ(0u, resolver.pending_jobs().size());

  EXPECT_THAT(callback.WaitForResult(), IsOk());
}

// Test that the ProxyResolutionService correctly handles the case where a
// request callback deletes the service.
TEST_F(ProxyResolutionServiceTest, CallbackDeletesService) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  std::unique_ptr<ProxyResolutionService> service =
      std::make_unique<ProxyResolutionService>(
          base::WrapUnique(config_service), base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;

  DeletingCallback<ProxyResolutionService> callback(&service);
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service->ResolveProxy(url, std::string(), &info, callback.callback(),
                                 &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request1->GetLoadState());

  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service->ResolveProxy(url, std::string(), &info, callback2.callback(),
                             &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv = service->ResolveProxy(url, std::string(), &info, callback3.callback(),
                             &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  config_service->SetConfig(ProxyConfigWithAnnotation(
      ProxyConfig::CreateDirect(), TRAFFIC_ANNOTATION_FOR_TESTS));

  ASSERT_EQ(0u, resolver.pending_jobs().size());
  ASSERT_THAT(callback.WaitForResult(), IsOk());
  ASSERT_THAT(callback2.WaitForResult(), IsOk());
  ASSERT_THAT(callback3.WaitForResult(), IsOk());
}

TEST_F(ProxyResolutionServiceTest, PAC) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  BoundTestNetLog log;

  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, log.bound());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->GetLoadState());

  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
  EXPECT_TRUE(info.did_use_pac_script());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // Check the NetLog was filled correctly.
  TestNetLogEntry::List entries;
  log.GetEntries(&entries);

  EXPECT_EQ(5u, entries.size());
  EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
                                    NetLogEventType::PROXY_RESOLUTION_SERVICE));
  EXPECT_TRUE(LogContainsBeginEvent(
      entries, 1,
      NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
  EXPECT_TRUE(LogContainsEndEvent(
      entries, 2,
      NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
  EXPECT_TRUE(LogContainsEndEvent(entries, 4,
                                  NetLogEventType::PROXY_RESOLUTION_SERVICE));
}

// Test that the proxy resolver does not see the URL's username/password
// or its reference section.
TEST_F(ProxyResolutionServiceTest, PAC_NoIdentityOrHash) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://username:password@www.google.com/?ref#hash#hash");

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  // The URL should have been simplified, stripping the username/password/hash.
  EXPECT_EQ(GURL("http://www.google.com/?ref"),
            resolver.pending_jobs()[0]->url());

  // We end here without ever completing the request -- destruction of
  // ProxyResolutionService will cancel the outstanding request.
}

TEST_F(ProxyResolutionServiceTest, PAC_FailoverWithoutDirect) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy:8080");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
  EXPECT_TRUE(info.did_use_pac_script());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // Now, imagine that connecting to foopy:8080 fails: there is nothing
  // left to fallback to, since our proxy list was NOT terminated by
  // DIRECT.
  EXPECT_FALSE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_TRUE(info.is_empty());
}

// Test that if the execution of the PAC script fails (i.e. javascript runtime
// error), and the PAC settings are non-mandatory, that we fall-back to direct.
TEST_F(ProxyResolutionServiceTest, PAC_RuntimeError) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://this-causes-js-error/");

  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Simulate a failure in the PAC executor.
  resolver.pending_jobs()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);

  EXPECT_THAT(callback1.WaitForResult(), IsOk());

  // Since the PAC script was non-mandatory, we should have fallen-back to
  // DIRECT.
  EXPECT_TRUE(info.is_direct());
  EXPECT_TRUE(info.did_use_pac_script());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
}

// The proxy list could potentially contain the DIRECT fallback choice
// in a location other than the very end of the list, and could even
// specify it multiple times.
//
// This is not a typical usage, but we will obey it.
// (If we wanted to disallow this type of input, the right place to
// enforce it would be in parsing the PAC result string).
//
// This test will use the PAC result string:
//
//   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
//
// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
// then foobar:20, and then give up and error.
//
// The important check of this test is to make sure that DIRECT is not somehow
// cached as being a bad proxy.
TEST_F(ProxyResolutionServiceTest, PAC_FailoverAfterDirect) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UsePacString(
      "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_TRUE(info.is_direct());

  // Fallback 1.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foobar:10", info.proxy_server().ToURI());

  // Fallback 2.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_TRUE(info.is_direct());

  // Fallback 3.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foobar:20", info.proxy_server().ToURI());

  // Fallback 4 -- Nothing to fall back to!
  EXPECT_FALSE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_TRUE(info.is_empty());
}

TEST_F(ProxyResolutionServiceTest, PAC_ConfigSourcePropagates) {
  // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
  // to ProxyInfo after the proxy is resolved via a PAC script.
  ProxyConfig config =
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Resolve something.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, NetLogWithSource());
  ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
  ASSERT_EQ(1u, resolver.pending_jobs().size());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
            info.traffic_annotation());
  EXPECT_TRUE(info.did_use_pac_script());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
}

TEST_F(ProxyResolutionServiceTest, ProxyResolverFails) {
  // Test what happens when the ProxyResolver fails. The download and setting
  // of the PAC script have already succeeded, so this corresponds with a
  // javascript runtime error while calling FindProxyForURL().

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Fail the first resolve request in MockAsyncProxyResolver.
  resolver.pending_jobs()[0]->CompleteNow(ERR_FAILED);

  // Although the proxy resolver failed the request, ProxyResolutionService
  // implicitly falls-back to DIRECT.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_TRUE(info.is_direct());

  // Failed PAC executions still have proxy resolution times.
  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // The second resolve request will try to run through the proxy resolver,
  // regardless of whether the first request failed in it.
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This time we will have the resolver succeed (perhaps the PAC script has
  // a dependency on the current time).
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy_valid:8080");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}

TEST_F(ProxyResolutionServiceTest, ProxyResolverTerminatedDuringRequest) {
  // Test what happens when the ProxyResolver fails with a fatal error while
  // a GetProxyForURL() call is in progress.

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Fail the first resolve request in MockAsyncProxyResolver.
  resolver.pending_jobs()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);

  // Although the proxy resolver failed the request, ProxyResolutionService
  // implicitly falls-back to DIRECT.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_TRUE(info.is_direct());

  // Failed PAC executions still have proxy resolution times.
  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // With no other requests, the ProxyResolutionService waits for a new request
  // before initializing a new ProxyResolver.
  EXPECT_TRUE(factory->pending_requests().empty());

  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This time we will have the resolver succeed.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy_valid:8080");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}

TEST_F(ProxyResolutionServiceTest,
       ProxyResolverTerminatedDuringRequestWithConcurrentRequest) {
  // Test what happens when the ProxyResolver fails with a fatal error while
  // a GetProxyForURL() call is in progress.

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start two resolve requests.
  GURL url1("http://www.google.com/");
  GURL url2("https://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1, request2;
  int rv =
      service.ResolveProxy(url1, std::string(), &info, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url2, std::string(), &info, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  JobMap jobs = GetPendingJobsForURLs(resolver, url1, url2);

  // Fail the first resolve request in MockAsyncProxyResolver.
  jobs[url1]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);

  // Although the proxy resolver failed the request, ProxyResolutionService
  // implicitly falls-back to DIRECT.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_TRUE(info.is_direct());

  // Failed PAC executions still have proxy resolution times.
  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // The second request is cancelled when the proxy resolver terminates.
  jobs = GetCancelledJobsForURLs(resolver, url2);

  // Since a second request was in progress, the ProxyResolutionService starts
  // initializating a new ProxyResolver.
  ASSERT_EQ(1u, factory->pending_requests().size());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  jobs = GetPendingJobsForURLs(resolver, url2);

  // This request succeeds.
  jobs[url2]->results()->UseNamedProxy("foopy_valid:8080");
  jobs[url2]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}

TEST_F(ProxyResolutionServiceTest, PacFileFetcherFailsDownloadingMandatoryPac) {
  // Test what happens when the ProxyResolver fails to download a mandatory PAC
  // script.

  ProxyConfig config(
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
  config.set_pac_mandatory(true);

  MockProxyConfigService* config_service = new MockProxyConfigService(config);

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNow(ERR_FAILED, nullptr);

  ASSERT_EQ(0u, factory->pending_requests().size());
  // As the proxy resolver factory failed the request and is configured for a
  // mandatory PAC script, ProxyResolutionService must not implicitly fall-back
  // to DIRECT.
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
            callback1.WaitForResult());
  EXPECT_FALSE(info.is_direct());

  // As the proxy resolver factory failed the request and is configured for a
  // mandatory PAC script, ProxyResolutionService must not implicitly fall-back
  // to DIRECT.
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
  EXPECT_FALSE(info.is_direct());
}

TEST_F(ProxyResolutionServiceTest,
       ProxyResolverFailsParsingJavaScriptMandatoryPac) {
  // Test what happens when the ProxyResolver fails that is configured to use a
  // mandatory PAC script. The download of the PAC script has already
  // succeeded but the PAC script contains no valid javascript.

  ProxyConfig config(
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
  config.set_pac_mandatory(true);

  MockProxyConfigService* config_service = new MockProxyConfigService(config);

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // Downloading the PAC script succeeds.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");

  EXPECT_FALSE(fetcher->has_pending_request());
  ASSERT_EQ(0u, factory->pending_requests().size());

  // Since PacFileDecider failed to identify a valid PAC and PAC was
  // mandatory for this configuration, the ProxyResolutionService must not
  // implicitly fall-back to DIRECT.
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
            callback.WaitForResult());
  EXPECT_FALSE(info.is_direct());
}

TEST_F(ProxyResolutionServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
  // Test what happens when the ProxyResolver fails that is configured to use a
  // mandatory PAC script. The download and setting of the PAC script have
  // already succeeded, so this corresponds with a javascript runtime error
  // while calling FindProxyForURL().

  ProxyConfig config(
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
  config.set_pac_mandatory(true);

  MockProxyConfigService* config_service = new MockProxyConfigService(config);

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Fail the first resolve request in MockAsyncProxyResolver.
  resolver.pending_jobs()[0]->CompleteNow(ERR_FAILED);

  // As the proxy resolver failed the request and is configured for a mandatory
  // PAC script, ProxyResolutionService must not implicitly fall-back to DIRECT.
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
            callback1.WaitForResult());
  EXPECT_FALSE(info.is_direct());

  // The second resolve request will try to run through the proxy resolver,
  // regardless of whether the first request failed in it.
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, std::string(), &info, callback2.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This time we will have the resolver succeed (perhaps the PAC script has
  // a dependency on the current time).
  resolver.pending_jobs()[0]->results()->UseNamedProxy("foopy_valid:8080");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}

TEST_F(ProxyResolutionServiceTest, ProxyFallback) {
  // Test what happens when we specify multiple proxy servers and some of them
  // are bad.

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // The first item is valid.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
  base::TimeTicks proxy_resolve_start_time = info.proxy_resolve_start_time();
  base::TimeTicks proxy_resolve_end_time = info.proxy_resolve_end_time();

  // Fake an error on the proxy.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));

  // Proxy times should not have been modified by fallback.
  EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
  EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());

  // The second proxy should be specified.
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
  // Report back that the second proxy worked.  This will globally mark the
  // first proxy as bad.
  TestProxyFallbackProxyDelegate test_delegate;
  service.SetProxyDelegate(&test_delegate);
  service.ReportSuccess(info);
  EXPECT_EQ("foopy1:8080", test_delegate.proxy_server().ToURI());
  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
            test_delegate.last_proxy_fallback_net_error());
  service.SetProxyDelegate(nullptr);

  TestCompletionCallback callback3;
  rv = service.ResolveProxy(url, std::string(), &info, callback3.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver -- the second result is already known
  // to be bad, so we will not try to use it initially.
  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy3:7070;foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());

  // Proxy times should have been updated, so get them again.
  EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
  proxy_resolve_start_time = info.proxy_resolve_start_time();
  proxy_resolve_end_time = info.proxy_resolve_end_time();

  // We fake another error. It should now try the third one.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());

  // We fake another error. At this point we have tried all of the
  // proxy servers we thought were valid; next we try the proxy server
  // that was in our bad proxies map (foopy1:8080).
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  // Fake another error, the last proxy is gone, the list should now be empty,
  // so there is nothing left to try.
  EXPECT_FALSE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
  EXPECT_FALSE(info.is_direct());
  EXPECT_TRUE(info.is_empty());

  // Proxy times should not have been modified by fallback.
  EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
  EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());

  // Look up proxies again
  TestCompletionCallback callback7;
  rv = service.ResolveProxy(url, std::string(), &info, callback7.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This time, the first 3 results have been found to be bad, but only the
  // first proxy has been confirmed ...
  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // ... therefore, we should see the second proxy first.
  EXPECT_THAT(callback7.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());

  EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  // TODO(nsylvain): Test that the proxy can be retried after the delay.
}

// This test is similar to ProxyFallback, but this time we have an explicit
// fallback choice to DIRECT.
TEST_F(ProxyResolutionServiceTest, ProxyFallbackToDirect) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // Set the result in proxy resolver.
  resolver.pending_jobs()[0]->results()->UsePacString(
      "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Get the first result.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  // Fake an error on the proxy.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));

  // Now we get back the second proxy.
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());

  // Fake an error on this proxy as well.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));

  // Finally, we get back DIRECT.
  EXPECT_TRUE(info.is_direct());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  // Now we tell the proxy service that even DIRECT failed.
  // There was nothing left to try after DIRECT, so we are out of
  // choices.
  EXPECT_FALSE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));
}

TEST_F(ProxyResolutionServiceTest, ProxyFallback_BadConfig) {
  // Test proxy failover when the configuration is bad.

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  TestResolveProxyDelegate delegate;
  std::unique_ptr<ProxyResolutionService::Request> request;
  service.SetProxyDelegate(&delegate);
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // The first item is valid.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  // Fake a proxy error.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));

  // The first proxy is ignored, and the second one is selected.
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());

  // Persist foopy1's failure to |service|'s cache of bad proxies, so it will
  // be considered by subsequent calls to ResolveProxy().
  service.ReportSuccess(info);

  // Fake a PAC failure.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, std::string(), &info2, callback2.callback(),
                            &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This simulates a javascript runtime error in the PAC script.
  resolver.pending_jobs()[0]->CompleteNow(ERR_FAILED);

  // Although the resolver failed, the ProxyResolutionService will implicitly
  // fall-back to a DIRECT connection.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_TRUE(info2.is_direct());
  EXPECT_FALSE(info2.is_empty());

  // The PAC script will work properly next time and successfully return a
  // proxy list. Since we have not marked the configuration as bad, it should
  // "just work" the next time we call it.
  ProxyInfo info3;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv = service.ResolveProxy(url, std::string(), &info3, callback3.callback(),
                            &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // The first proxy was deprioritized since it was added to the bad proxies
  // list by the earlier ReportSuccess().
  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_FALSE(info3.is_direct());
  EXPECT_EQ("foopy2:9090", info3.proxy_server().ToURI());
  EXPECT_EQ(2u, info3.proxy_list().size());

  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());

  EXPECT_EQ(3, delegate.num_resolve_proxy_called());
}

TEST_F(ProxyResolutionServiceTest, ProxyFallback_BadConfigMandatory) {
  // Test proxy failover when the configuration is bad.

  ProxyConfig config(
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));

  config.set_pac_mandatory(true);
  MockProxyConfigService* config_service = new MockProxyConfigService(config);

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv = service.ResolveProxy(url, std::string(), &info, callback1.callback(),
                                &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // The first item is valid.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  // Fake a proxy error.
  EXPECT_TRUE(info.Fallback(ERR_PROXY_CONNECTION_FAILED, NetLogWithSource()));

  // The first proxy is ignored, and the second one is selected.
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());

  // Persist foopy1's failure to |service|'s cache of bad proxies, so it will
  // be considered by subsequent calls to ResolveProxy().
  service.ReportSuccess(info);

  // Fake a PAC failure.
  ProxyInfo info2;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv = service.ResolveProxy(url, std::string(), &info2, callback3.callback(),
                            &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  // This simulates a javascript runtime error in the PAC script.
  resolver.pending_jobs()[0]->CompleteNow(ERR_FAILED);

  // Although the resolver failed, the ProxyResolutionService will NOT fall-back
  // to a DIRECT connection as it is configured as mandatory.
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
            callback3.WaitForResult());
  EXPECT_FALSE(info2.is_direct());
  EXPECT_TRUE(info2.is_empty());

  // The PAC script will work properly next time and successfully return a
  // proxy list. Since we have not marked the configuration as bad, it should
  // "just work" the next time we call it.
  ProxyInfo info3;
  TestCompletionCallback callback4;
  std::unique_ptr<ProxyResolutionService::Request> request4;
  rv = service.ResolveProxy(url, std::string(), &info3, callback4.callback(),
                            &request4, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

  resolver.pending_jobs()[0]->results()->UseNamedProxy(
      "foopy1:8080;foopy2:9090");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // The first proxy was deprioritized since it was added to the bad proxies
  // list by the earlier ReportSuccess().
  EXPECT_THAT(callback4.WaitForResult(), IsOk());
  EXPECT_FALSE(info3.is_direct());
  EXPECT_EQ("foopy2:9090", info3.proxy_server().ToURI());
  EXPECT_EQ(2u, info3.proxy_list().size());
}

TEST_F(ProxyResolutionServiceTest, ProxyBypassList) {
  // Test that the proxy bypass rules are consulted.

  TestCompletionCallback callback[2];
  ProxyInfo info[2];
  ProxyConfig config;
  config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
  config.set_auto_detect(false);
  config.proxy_rules().bypass_rules.ParseFromString("*.org");

  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);

  int rv;
  GURL url1("http://www.webkit.org");
  GURL url2("http://www.webkit.com");
  std::unique_ptr<ProxyResolutionService::Request> request1;
  std::unique_ptr<ProxyResolutionService::Request> request2;

  // Request for a .org domain should bypass proxy.
  rv = service.ResolveProxy(url1, std::string(), &info[0],
                            callback[0].callback(), &request1,
                            NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(info[0].is_direct());

  // Request for a .com domain hits the proxy.
  rv = service.ResolveProxy(url2, std::string(), &info[1],
                            callback[1].callback(), &request2,
                            NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
}

TEST_F(ProxyResolutionServiceTest, MarkProxiesAsBadTests) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString(
      "http=foopy1:8080;http=foopy2:8080;http=foopy3.8080;http=foopy4:8080");
  config.set_auto_detect(false);

  ProxyList proxy_list;
  std::vector<ProxyServer> additional_bad_proxies;
  for (const ProxyServer& proxy_server :
       config.proxy_rules().proxies_for_http.GetAll()) {
    proxy_list.AddProxyServer(proxy_server);
    if (proxy_server == config.proxy_rules().proxies_for_http.Get())
      continue;

    additional_bad_proxies.push_back(proxy_server);
  }

  EXPECT_EQ(3u, additional_bad_proxies.size());

  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
  ProxyInfo proxy_info;
  proxy_info.UseProxyList(proxy_list);
  const ProxyRetryInfoMap& retry_info = service.proxy_retry_info();
  service.MarkProxiesAsBadUntil(proxy_info, base::TimeDelta::FromSeconds(1),
                                additional_bad_proxies, NetLogWithSource());
  ASSERT_EQ(4u, retry_info.size());
  for (const ProxyServer& proxy_server :
       config.proxy_rules().proxies_for_http.GetAll()) {
    auto i = retry_info.find(proxy_server.host_port_pair().ToString());
    ASSERT_TRUE(i != retry_info.end());
  }
}

TEST_F(ProxyResolutionServiceTest, PerProtocolProxyTests) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
  config.set_auto_detect(false);
  std::unique_ptr<ProxyResolutionService::Request> request;
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("http://www.msn.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("ftp://ftp.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_TRUE(info.is_direct());
    EXPECT_EQ("direct://", info.proxy_server().ToURI());
  }
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("https://webbranch.techcu.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
  }
  {
    config.proxy_rules().ParseFromString("foopy1:8080");
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("http://www.microsoft.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
}

TEST_F(ProxyResolutionServiceTest, ProxyConfigTrafficAnnotationPropagates) {
  // Test that the proxy config source is set correctly when resolving proxies
  // using manual proxy rules. Namely, the config source should only be set if
  // any of the rules were applied.
  std::unique_ptr<ProxyResolutionService::Request> request;
  {
    ProxyConfig config;
    config.proxy_rules().ParseFromString("https=foopy2:8080");
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("http://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    ASSERT_THAT(rv, IsOk());
    // Should be test, even if there are no HTTP proxies configured.
    EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
              info.traffic_annotation());
  }
  {
    ProxyConfig config;
    config.proxy_rules().ParseFromString("https=foopy2:8080");
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("https://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    ASSERT_THAT(rv, IsOk());
    // Used the HTTPS proxy. So traffic annotation should test.
    EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
              info.traffic_annotation());
  }
  {
    ProxyConfig config;
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("http://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    ASSERT_THAT(rv, IsOk());
    // ProxyConfig is empty. Traffic annotation should still be TEST.
    EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
              info.traffic_annotation());
  }
}

// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
// fall back to the SOCKS proxy.
TEST_F(ProxyResolutionServiceTest, DefaultProxyFallbackToSOCKS) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
  config.set_auto_detect(false);
  EXPECT_EQ(ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
            config.proxy_rules().type);

  std::unique_ptr<ProxyResolutionService::Request> request;
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("http://www.msn.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("ftp://ftp.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("https://webbranch.techcu.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
  {
    ProxyResolutionService service(
        std::make_unique<MockProxyConfigService>(config), nullptr, nullptr);
    GURL test_url("unknown://www.microsoft.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, std::string(), &info,
                             callback.callback(), &request, NetLogWithSource());
    EXPECT_THAT(rv, IsOk());
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
}

// Test cancellation of an in-progress request.
TEST_F(ProxyResolutionServiceTest, CancelInProgressRequest) {
  const GURL url1("http://request1");
  const GURL url2("http://request2");
  const GURL url3("http://request3");
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start 3 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Successfully initialize the PAC script.
  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  GetPendingJobsForURLs(resolver, url1);

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  GetPendingJobsForURLs(resolver, url1, url2);

  ProxyInfo info3;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv = service.ResolveProxy(url3, std::string(), &info3, callback3.callback(),
                            &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  GetPendingJobsForURLs(resolver, url1, url2, url3);

  // Cancel the second request
  request2.reset();

  JobMap jobs = GetPendingJobsForURLs(resolver, url1, url3);

  // Complete the two un-cancelled jobs.
  // We complete the last one first, just to mix it up a bit.
  jobs[url3]->results()->UseNamedProxy("request3:80");
  jobs[url3]->CompleteNow(OK);  // dsaadsasd

  jobs[url1]->results()->UseNamedProxy("request1:80");
  jobs[url1]->CompleteNow(OK);

  EXPECT_EQ(OK, callback1.WaitForResult());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  EXPECT_FALSE(callback2.have_result());  // Cancelled.
  GetCancelledJobsForURLs(resolver, url2);

  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
}

// Test the initial PAC download for resolver that expects bytes.
TEST_F(ProxyResolutionServiceTest, InitialPACScriptDownload) {
  const GURL url1("http://request1");
  const GURL url2("http://request2");
  const GURL url3("http://request3");
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 3 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ProxyInfo info3;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv = service.ResolveProxy(url3, std::string(), &info3, callback3.callback(),
                            &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request1->GetLoadState());
  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request2->GetLoadState());
  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PAC_FILE, request3->GetLoadState());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, it will have been sent to the proxy
  // resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  JobMap jobs = GetPendingJobsForURLs(resolver, url1, url2, url3);

  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request1->GetLoadState());
  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request2->GetLoadState());
  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request3->GetLoadState());

  // Complete all the jobs (in some order).

  jobs[url3]->results()->UseNamedProxy("request3:80");
  jobs[url3]->CompleteNow(OK);

  jobs[url1]->results()->UseNamedProxy("request1:80");
  jobs[url1]->CompleteNow(OK);

  jobs[url2]->results()->UseNamedProxy("request2:80");
  jobs[url2]->CompleteNow(OK);

  // Complete and verify that jobs ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  // ProxyResolver::GetProxyForURL() to take a std::unique_ptr<Request>* rather
  // than a RequestHandle* (patchset #11 id:200001 of
  // https://codereview.chromium.org/1439053002/ )
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
  EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
  EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
  EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
  EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());

  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
  EXPECT_FALSE(info3.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info3.proxy_resolve_end_time().is_null());
  EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
}

// Test changing the PacFileFetcher while PAC download is in progress.
TEST_F(ProxyResolutionServiceTest,
       ChangeScriptFetcherWhilePACDownloadInProgress) {
  const GURL url1("http://request1");
  const GURL url2("http://request2");
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 2 jobs.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.

  // We now change out the ProxyResolutionService's script fetcher. We should
  // restart the initialization with the new fetcher.

  fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, it will have been sent to the proxy
  // resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  GetPendingJobsForURLs(resolver, url1, url2);
}

// Test cancellation of a request, while the PAC script is being fetched.
TEST_F(ProxyResolutionServiceTest, CancelWhilePACFetching) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 3 requests.
  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  BoundTestNetLog log1;
  int rv = service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                                callback1.callback(), &request1, log1.bound());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ProxyInfo info3;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv =
      service.ResolveProxy(GURL("http://request3"), std::string(), &info3,
                           callback3.callback(), &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // Cancel the first 2 jobs.
  request1.reset();
  request2.reset();

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, it will have been sent to the
  // proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request3"), resolver.pending_jobs()[0]->url());

  // Complete all the jobs.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request3:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());

  EXPECT_TRUE(resolver.cancelled_jobs().empty());

  EXPECT_FALSE(callback1.have_result());  // Cancelled.
  EXPECT_FALSE(callback2.have_result());  // Cancelled.

  TestNetLogEntry::List entries1;
  log1.GetEntries(&entries1);

  // Check the NetLog for request 1 (which was cancelled) got filled properly.
  EXPECT_EQ(4u, entries1.size());
  EXPECT_TRUE(LogContainsBeginEvent(entries1, 0,
                                    NetLogEventType::PROXY_RESOLUTION_SERVICE));
  EXPECT_TRUE(LogContainsBeginEvent(
      entries1, 1,
      NetLogEventType::PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC));
  // Note that PROXY_RESOLUTION_SERVICE_WAITING_FOR_INIT_PAC is never completed
  // before the cancellation occured.
  EXPECT_TRUE(LogContainsEvent(entries1, 2, NetLogEventType::CANCELLED,
                               NetLogEventPhase::NONE));
  EXPECT_TRUE(LogContainsEndEvent(entries1, 3,
                                  NetLogEventType::PROXY_RESOLUTION_SERVICE));
}

// Test that if auto-detect fails, we fall-back to the custom pac.
TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomPac) {
  const GURL url1("http://request1");
  const GURL url2("http://request2");
  ProxyConfig config;
  config.set_auto_detect(true);
  config.set_pac_url(GURL("http://foopy/proxy.pac"));
  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // It should be trying to auto-detect first -- FAIL the autodetect during
  // the script download.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  // Next it should be trying the custom PAC url.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  // Now finally, the pending jobs should have been sent to the resolver
  // (which was initialized with custom PAC script).

  JobMap jobs = GetPendingJobsForURLs(resolver, url1, url2);

  // Complete the pending jobs.
  jobs[url2]->results()->UseNamedProxy("request2:80");
  jobs[url2]->CompleteNow(OK);
  jobs[url1]->results()->UseNamedProxy("request1:80");
  jobs[url1]->CompleteNow(OK);

  // Verify that jobs ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  // ProxyResolver::GetProxyForURL() to take a std::unique_ptr<Request>* rather
  // than a RequestHandle* (patchset #11 id:200001 of
  // https://codereview.chromium.org/1439053002/ )
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
  EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
  EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
  EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
  EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
  EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
}

// This is the same test as FallbackFromAutodetectToCustomPac, except
// the auto-detect script fails parsing rather than downloading.
TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomPac2) {
  const GURL url1("http://request1");
  const GURL url2("http://request2");
  ProxyConfig config;
  config.set_auto_detect(true);
  config.set_pac_url(GURL("http://foopy/proxy.pac"));
  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(url1, std::string(), &info1, callback1.callback(),
                           &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv = service.ResolveProxy(url2, std::string(), &info2, callback2.callback(),
                            &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // It should be trying to auto-detect first -- succeed the download.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");

  // The script contents passed failed basic verification step (since didn't
  // contain token FindProxyForURL), so it was never passed to the resolver.

  // Next it should be trying the custom PAC url.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  // Now finally, the pending jobs should have been sent to the resolver
  // (which was initialized with custom PAC script).

  JobMap jobs = GetPendingJobsForURLs(resolver, url1, url2);

  // Complete the pending jobs.
  jobs[url2]->results()->UseNamedProxy("request2:80");
  jobs[url2]->CompleteNow(OK);
  jobs[url1]->results()->UseNamedProxy("request1:80");
  jobs[url1]->CompleteNow(OK);

  // Verify that jobs ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  // ProxyResolver::GetProxyForURL() to take a std::unique_ptr<Request>* rather
  // than a RequestHandle* (patchset #11 id:200001 of
  // https://codereview.chromium.org/1439053002/ )
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
}

// Test that if all of auto-detect, a custom PAC script, and manual settings
// are given, then we will try them in that order.
TEST_F(ProxyResolutionServiceTest, FallbackFromAutodetectToCustomToManual) {
  ProxyConfig config;
  config.set_auto_detect(true);
  config.set_pac_url(GURL("http://foopy/proxy.pac"));
  config.proxy_rules().ParseFromString("http=foopy:80");

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 2 jobs.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // It should be trying to auto-detect first -- fail the download.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  // Next it should be trying the custom PAC url -- fail the download.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  // Since we never managed to initialize a resolver, nothing should have been
  // sent to it.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // Verify that jobs ran as expected -- they should have fallen back to
  // the manual proxy configuration for HTTP urls.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
}

// Test that the bypass rules are NOT applied when using autodetect.
TEST_F(ProxyResolutionServiceTest, BypassDoesntApplyToPac) {
  ProxyConfig config;
  config.set_auto_detect(true);
  config.set_pac_url(GURL("http://foopy/proxy.pac"));
  config.proxy_rules().ParseFromString("http=foopy:80");  // Not used.
  config.proxy_rules().bypass_rules.ParseFromString("www.google.com");

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // It should be trying to auto-detect first -- succeed the download.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://www.google.com"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Verify that request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // Start another request, it should pickup the bypass item.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://www.google.com"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://www.google.com"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
}

// Delete the ProxyResolutionService while InitProxyResolver has an outstanding
// request to the script fetcher. When run under valgrind, should not
// have any memory errors (used to be that the PacFileFetcher was
// being deleted prior to the InitProxyResolver).
TEST_F(ProxyResolutionServiceTest,
       DeleteWhileInitProxyResolverHasOutstandingFetch) {
  ProxyConfig config =
    ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that nothing has been sent to the proxy resolver factory yet.
  ASSERT_EQ(0u, factory->pending_requests().size());

  // InitProxyResolver should have issued a request to the PacFileFetcher
  // and be waiting on that to complete.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
}

// Delete the ProxyResolutionService while InitProxyResolver has an outstanding
// request to the proxy resolver. When run under valgrind, should not
// have any memory errors (used to be that the ProxyResolver was
// being deleted prior to the InitProxyResolver).
TEST_F(ProxyResolutionServiceTest,
       DeleteWhileInitProxyResolverHasOutstandingSet) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  GURL url("http://www.google.com/");

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv = service.ResolveProxy(url, std::string(), &info, callback.callback(),
                                &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
            factory->pending_requests()[0]->script_data()->url());
}

TEST_F(ProxyResolutionServiceTest, ResetProxyConfigService) {
  ProxyConfig config1;
  config1.proxy_rules().ParseFromString("foopy1:8080");
  config1.set_auto_detect(false);
  ProxyResolutionService service(
      std::make_unique<MockProxyConfigService>(config1), nullptr, nullptr);

  ProxyInfo info;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  ProxyConfig config2;
  config2.proxy_rules().ParseFromString("foopy2:8080");
  config2.set_auto_detect(false);
  service.ResetConfigService(std::make_unique<MockProxyConfigService>(config2));
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
}

// Test that when going from a configuration that required PAC to one
// that does NOT, we unset the variable |should_use_proxy_resolver_|.
TEST_F(ProxyResolutionServiceTest, UpdateConfigFromPACToDirect) {
  ProxyConfig config = ProxyConfig::CreateAutoDetect();

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Successfully set the autodetect script.
  EXPECT_EQ(PacFileData::TYPE_AUTO_DETECT,
            factory->pending_requests()[0]->script_data()->type());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  // Complete the pending request.
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Verify that request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // Force the ProxyResolutionService to pull down a new proxy configuration.
  // (Even though the configuration isn't old/bad).
  //
  // This new configuration no longer has auto_detect set, so
  // jobs should complete synchronously now as direct-connect.
  config_service->SetConfig(ProxyConfigWithAnnotation::CreateDirect());

  // Start another request -- the effective configuration has changed.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://www.google.com"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());

  EXPECT_TRUE(info2.is_direct());
}

TEST_F(ProxyResolutionServiceTest, NetworkChangeTriggersPacRefetch) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  TestNetLog log;

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), &log);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Disable the "wait after IP address changes" hack, so this unit-test can
  // complete quickly.
  service.set_stall_proxy_auto_config_delay(base::TimeDelta());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, the request will have been sent to
  // the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // Now simluate a change in the network. The ProxyConfigService is still
  // going to return the same PAC URL as before, but this URL needs to be
  // refetched on the new network.
  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
  base::RunLoop().RunUntilIdle();  // Notification happens async.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // This second request should have triggered the re-download of the PAC
  // script (since we marked the network as having changed).
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // Simulate the PAC script fetch as having completed (this time with
  // different data).
  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);

  // Now that the PAC script is downloaded, the second request will have been
  // sent to the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_jobs()[0]->url());

  // Complete the pending second request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());

  // Check that the expected events were output to the log stream. In particular
  // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
  // setup), and NOT a second time when the IP address changed.
  TestNetLogEntry::List entries;
  log.GetEntries(&entries);

  EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
                                       NetLogEventType::PROXY_CONFIG_CHANGED));
  ASSERT_EQ(9u, entries.size());
  for (size_t i = 1; i < entries.size(); ++i)
    EXPECT_NE(NetLogEventType::PROXY_CONFIG_CHANGED, entries[i].type);
}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch fails due
// to a network error, we will eventually re-configure the service to use the
// script once it becomes available.
TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterFailure) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  //
  // We simulate a failed download attempt, the proxy service should now
  // fall-back to DIRECT connections.
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  ASSERT_TRUE(factory->pending_requests().empty());

  // Wait for completion callback, and verify it used DIRECT.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_TRUE(info1.is_direct());

  // At this point we have initialized the proxy service using a PAC script,
  // however it failed and fell-back to DIRECT.
  //
  // A background task to periodically re-check the PAC script for validity will
  // have been started. We will now wait for the next download attempt to start.
  //
  // Note that we shouldn't have to wait long here, since our test enables a
  // special unit-test mode.
  fetcher->WaitUntilFetch();

  ASSERT_TRUE(factory->pending_requests().empty());

  // Make sure that our background checker is trying to download the expected
  // PAC script (same one as before). This time we will simulate a successful
  // download of the script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  base::RunLoop().RunUntilIdle();

  // Now that the PAC script is downloaded, it should be used to initialize the
  // ProxyResolver. Simulate a successful parse.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  // At this point the ProxyResolutionService should have re-configured itself
  // to use the PAC script (thereby recovering from the initial fetch failure).
  // We will verify that the next Resolve request uses the resolver rather than
  // DIRECT.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that it was sent to the resolver.
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_jobs()[0]->url());

  // Complete the pending second request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time its *contents* change, we will eventually
// re-configure the service to use the new script.
TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterContentChange) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, the request will have been sent to
  // the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // At this point we have initialized the proxy service using a PAC script.
  //
  // A background task to periodically re-check the PAC script for validity will
  // have been started. We will now wait for the next download attempt to start.
  //
  // Note that we shouldn't have to wait long here, since our test enables a
  // special unit-test mode.
  fetcher->WaitUntilFetch();

  ASSERT_TRUE(factory->pending_requests().empty());
  ASSERT_TRUE(resolver.pending_jobs().empty());

  // Make sure that our background checker is trying to download the expected
  // PAC script (same one as before). This time we will simulate a successful
  // download of a DIFFERENT script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);

  base::RunLoop().RunUntilIdle();

  // Now that the PAC script is downloaded, it should be used to initialize the
  // ProxyResolver. Simulate a successful parse.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  // At this point the ProxyResolutionService should have re-configured itself
  // to use the new PAC script.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that it was sent to the resolver.
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_jobs()[0]->url());

  // Complete the pending second request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds
// and so does the next poll, however the contents of the downloaded script
// have NOT changed, then we do not bother to re-initialize the proxy resolver.
TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterContentUnchanged) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, the request will have been sent to
  // the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // At this point we have initialized the proxy service using a PAC script.
  //
  // A background task to periodically re-check the PAC script for validity will
  // have been started. We will now wait for the next download attempt to start.
  //
  // Note that we shouldn't have to wait long here, since our test enables a
  // special unit-test mode.
  fetcher->WaitUntilFetch();

  ASSERT_TRUE(factory->pending_requests().empty());
  ASSERT_TRUE(resolver.pending_jobs().empty());

  // Make sure that our background checker is trying to download the expected
  // PAC script (same one as before). We will simulate the same response as
  // last time (i.e. the script is unchanged).
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  base::RunLoop().RunUntilIdle();

  ASSERT_TRUE(factory->pending_requests().empty());
  ASSERT_TRUE(resolver.pending_jobs().empty());

  // At this point the ProxyResolutionService is still running the same PAC
  // script as before.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Check that it was sent to the resolver.
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_jobs()[0]->url());

  // Complete the pending second request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
}

// This test verifies that the PAC script specified by the settings is
// periodically polled for changes. Specifically, if the initial fetch succeeds,
// however at a later time it starts to fail, we should re-configure the
// ProxyResolutionService to stop using that PAC script.
TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterSuccess) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, the request will have been sent to
  // the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // At this point we have initialized the proxy service using a PAC script.
  //
  // A background task to periodically re-check the PAC script for validity will
  // have been started. We will now wait for the next download attempt to start.
  //
  // Note that we shouldn't have to wait long here, since our test enables a
  // special unit-test mode.
  fetcher->WaitUntilFetch();

  ASSERT_TRUE(factory->pending_requests().empty());
  ASSERT_TRUE(resolver.pending_jobs().empty());

  // Make sure that our background checker is trying to download the expected
  // PAC script (same one as before). This time we will simulate a failure
  // to download the script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  base::RunLoop().RunUntilIdle();

  // At this point the ProxyResolutionService should have re-configured itself
  // to use DIRECT connections rather than the given proxy resolver.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(info2.is_direct());
}

// Tests that the code which decides at what times to poll the PAC
// script follows the expected policy.
TEST_F(ProxyResolutionServiceTest, PACScriptPollingPolicy) {
  // Retrieve the internal polling policy implementation used by
  // ProxyResolutionService.
  std::unique_ptr<ProxyResolutionService::PacPollPolicy> policy =
      ProxyResolutionService::CreateDefaultPacPollPolicy();

  int error;
  ProxyResolutionService::PacPollPolicy::Mode mode;
  const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
  base::TimeDelta delay = initial_delay;

  // --------------------------------------------------
  // Test the poll sequence in response to a failure.
  // --------------------------------------------------
  error = ERR_NAME_NOT_RESOLVED;

  // Poll #0
  mode = policy->GetNextDelay(error, initial_delay, &delay);
  EXPECT_EQ(8, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_USE_TIMER, mode);

  // Poll #1
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(32, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // Poll #2
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(120, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // Poll #3
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(14400, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // Poll #4
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(14400, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // --------------------------------------------------
  // Test the poll sequence in response to a success.
  // --------------------------------------------------
  error = OK;

  // Poll #0
  mode = policy->GetNextDelay(error, initial_delay, &delay);
  EXPECT_EQ(43200, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // Poll #1
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(43200, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);

  // Poll #2
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(43200, delay.InSeconds());
  EXPECT_EQ(ProxyResolutionService::PacPollPolicy::MODE_START_AFTER_ACTIVITY,
            mode);
}

// This tests the polling of the PAC script. Specifically, it tests that
// polling occurs in response to user activity.
TEST_F(ProxyResolutionServiceTest, PACScriptRefetchAfterActivity) {
  ImmediateAfterActivityPollPolicy poll_policy;
  ProxyResolutionService::set_pac_script_poll_policy(&poll_policy);

  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  std::unique_ptr<ProxyResolutionService::Request> request1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), std::string(), &info1,
                           callback1.callback(), &request1, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered initial download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // Nothing has been sent to the factory yet.
  EXPECT_TRUE(factory->pending_requests().empty());

  // At this point the ProxyResolutionService should be waiting for the
  // PacFileFetcher to invoke its completion callback, notifying it of
  // PAC script download completion.
  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);

  // Now that the PAC script is downloaded, the request will have been sent to
  // the proxy resolver.
  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
            factory->pending_requests()[0]->script_data()->utf16());
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_jobs()[0]->url());

  // Complete the pending request.
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_THAT(callback1.WaitForResult(), IsOk());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  // At this point we have initialized the proxy service using a PAC script.
  // Our PAC poller is set to update ONLY in response to network activity,
  // (i.e. another call to ResolveProxy()).

  ASSERT_FALSE(fetcher->has_pending_request());
  ASSERT_TRUE(factory->pending_requests().empty());
  ASSERT_TRUE(resolver.pending_jobs().empty());

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  std::unique_ptr<ProxyResolutionService::Request> request2;
  rv =
      service.ResolveProxy(GURL("http://request2"), std::string(), &info2,
                           callback2.callback(), &request2, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // This request should have sent work to the resolver; complete it.
  ASSERT_EQ(1u, resolver.pending_jobs().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_jobs()[0]->url());
  resolver.pending_jobs()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_jobs()[0]->CompleteNow(OK);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());

  // In response to getting that resolve request, the poller should have
  // started the next poll, and made it as far as to request the download.

  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  // This time we will fail the download, to simulate a PAC script change.
  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());

  // Drain the message loop, so ProxyResolutionService is notified of the change
  // and has a chance to re-configure itself.
  base::RunLoop().RunUntilIdle();

  // Start a third request -- this time we expect to get a direct connection
  // since the PAC script poller experienced a failure.
  ProxyInfo info3;
  TestCompletionCallback callback3;
  std::unique_ptr<ProxyResolutionService::Request> request3;
  rv =
      service.ResolveProxy(GURL("http://request3"), std::string(), &info3,
                           callback3.callback(), &request3, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(info3.is_direct());
}

// Helper class to exercise URL sanitization using the different policies. This
// works by submitted URLs to the ProxyResolutionService. In turn the
// ProxyResolutionService sanitizes the URL and then passes it along to the
// ProxyResolver. This helper returns the URL seen by the ProxyResolver.
class SanitizeUrlHelper {
 public:
  SanitizeUrlHelper() {
    std::unique_ptr<MockProxyConfigService> config_service(
        new MockProxyConfigService("http://foopy/proxy.pac"));

    factory = new MockAsyncProxyResolverFactory(false);

    service_.reset(new ProxyResolutionService(
        std::move(config_service), base::WrapUnique(factory), nullptr));

    // Do an initial request to initialize the service (configure the PAC
    // script).
    GURL url("http://example.com");

    ProxyInfo info;
    TestCompletionCallback callback;
    std::unique_ptr<ProxyResolutionService::Request> request;
    int rv =
        service_->ResolveProxy(url, std::string(), &info, callback.callback(),
                               &request, NetLogWithSource());
    EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

    // First step is to download the PAC script.
    EXPECT_EQ(GURL("http://foopy/proxy.pac"),
              factory->pending_requests()[0]->script_data()->url());
    factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);

    EXPECT_EQ(1u, resolver.pending_jobs().size());
    EXPECT_EQ(url, resolver.pending_jobs()[0]->url());

    // Complete the request.
    resolver.pending_jobs()[0]->results()->UsePacString("DIRECT");
    resolver.pending_jobs()[0]->CompleteNow(OK);
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_TRUE(info.is_direct());
  }

  // Changes the URL sanitization policy for the underlying
  // ProxyResolutionService. This will affect subsequent calls to SanitizeUrl.
  void SetSanitizeUrlPolicy(ProxyResolutionService::SanitizeUrlPolicy policy) {
    service_->set_sanitize_url_policy(policy);
  }

  // Makes a proxy resolution request through the ProxyResolutionService, and
  // returns the URL that was submitted to the Proxy Resolver.
  GURL SanitizeUrl(const GURL& raw_url) {
    // Issue a request and see what URL is sent to the proxy resolver.
    ProxyInfo info;
    TestCompletionCallback callback;
    std::unique_ptr<ProxyResolutionService::Request> request1;
    int rv = service_->ResolveProxy(raw_url, std::string(), &info,
                                    callback.callback(), &request1,
                                    NetLogWithSource());
    EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

    EXPECT_EQ(1u, resolver.pending_jobs().size());

    GURL sanitized_url = resolver.pending_jobs()[0]->url();

    // Complete the request.
    resolver.pending_jobs()[0]->results()->UsePacString("DIRECT");
    resolver.pending_jobs()[0]->CompleteNow(OK);
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_TRUE(info.is_direct());

    return sanitized_url;
  }

  // Changes the ProxyResolutionService's URL sanitization policy and then
  // sanitizes |raw_url|.
  GURL SanitizeUrl(const GURL& raw_url,
                   ProxyResolutionService::SanitizeUrlPolicy policy) {
    service_->set_sanitize_url_policy(policy);
    return SanitizeUrl(raw_url);
  }

 private:
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory;
  std::unique_ptr<ProxyResolutionService> service_;
};

TEST_F(ProxyResolutionServiceTest, SanitizeUrlDefaultsToSafe) {
  SanitizeUrlHelper helper;

  // Without changing the URL sanitization policy, the default should be to
  // strip https:// URLs.
  EXPECT_EQ(GURL("https://example.com/"),
            helper.SanitizeUrl(
                GURL("https://foo:bar@example.com/foo/bar/baz?hello#sigh")));
}

// Tests URL sanitization with input URLs that have a // non-cryptographic
// scheme (i.e. http://). The sanitized result is consistent regardless of the
// stripping mode selected.
TEST_F(ProxyResolutionServiceTest, SanitizeUrlForPacScriptNonCryptographic) {
  const struct {
    const char* raw_url;
    const char* sanitized_url;
  } kTests[] = {
      // Embedded identity is stripped.
      {
          "http://foo:bar@example.com/", "http://example.com/",
      },
      {
          "ftp://foo:bar@example.com/", "ftp://example.com/",
      },
      {
          "ftp://example.com/some/path/here",
          "ftp://example.com/some/path/here",
      },
      // Reference fragment is stripped.
      {
          "http://example.com/blah#hello", "http://example.com/blah",
      },
      // Query parameters are NOT stripped.
      {
          "http://example.com/foo/bar/baz?hello",
          "http://example.com/foo/bar/baz?hello",
      },
      // Fragment is stripped, but path and query are left intact.
      {
          "http://foo:bar@example.com/foo/bar/baz?hello#sigh",
          "http://example.com/foo/bar/baz?hello",
      },
      // Port numbers are not affected.
      {
          "http://example.com:88/hi", "http://example.com:88/hi",
      },
  };

  SanitizeUrlHelper helper;

  for (const auto& test : kTests) {
    // The result of SanitizeUrlForPacScript() is the same regardless of the
    // second parameter (sanitization mode), since the input URLs do not use a
    // cryptographic scheme.
    GURL raw_url(test.raw_url);
    ASSERT_TRUE(raw_url.is_valid());
    EXPECT_FALSE(raw_url.SchemeIsCryptographic());

    EXPECT_EQ(GURL(test.sanitized_url),
              helper.SanitizeUrl(
                  raw_url, ProxyResolutionService::SanitizeUrlPolicy::UNSAFE));

    EXPECT_EQ(GURL(test.sanitized_url),
              helper.SanitizeUrl(
                  raw_url, ProxyResolutionService::SanitizeUrlPolicy::SAFE));
  }
}

// Tests URL sanitization using input URLs that have a cryptographic schemes
// (i.e. https://). The sanitized result differs depending on the sanitization
// mode chosen.
TEST_F(ProxyResolutionServiceTest, SanitizeUrlForPacScriptCryptographic) {
  const struct {
    // Input URL.
    const char* raw_url;

    // Output URL when stripping of cryptographic URLs is disabled.
    const char* sanitized_url_unstripped;

    // Output URL when stripping of cryptographic URLs is enabled.
    const char* sanitized_url;
  } kTests[] = {
      // Embedded identity is always stripped.
      {
          "https://foo:bar@example.com/", "https://example.com/",
          "https://example.com/",
      },
      // Fragments are always stripped, but stripping path is conditional on the
      // mode.
      {
          "https://example.com/blah#hello", "https://example.com/blah",
          "https://example.com/",
      },
      // Stripping the query is conditional on the mode.
      {
          "https://example.com/?hello", "https://example.com/?hello",
          "https://example.com/",
      },
      // The embedded identity and fragment is always stripped, however path and
      // query are conditional on the stripping mode.
      {
          "https://foo:bar@example.com/foo/bar/baz?hello#sigh",
          "https://example.com/foo/bar/baz?hello", "https://example.com/",
      },
      // The URL's port should not be stripped.
      {
          "https://example.com:88/hi", "https://example.com:88/hi",
          "https://example.com:88/",
      },
      // Try a wss:// URL, to make sure it also strips (is is also a
      // cryptographic URL).
      {
          "wss://example.com:88/hi", "wss://example.com:88/hi",
          "wss://example.com:88/",
      },
  };

  SanitizeUrlHelper helper;

  for (const auto& test : kTests) {
    GURL raw_url(test.raw_url);
    ASSERT_TRUE(raw_url.is_valid());
    EXPECT_TRUE(raw_url.SchemeIsCryptographic());

    EXPECT_EQ(GURL(test.sanitized_url_unstripped),
              helper.SanitizeUrl(
                  raw_url, ProxyResolutionService::SanitizeUrlPolicy::UNSAFE));

    EXPECT_EQ(GURL(test.sanitized_url),
              helper.SanitizeUrl(
                  raw_url, ProxyResolutionService::SanitizeUrlPolicy::SAFE));
  }
}

TEST_F(ProxyResolutionServiceTest, OnShutdownWithLiveRequest) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv =
      service.ResolveProxy(GURL("http://request/"), std::string(), &info,
                           callback.callback(), &request, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // The first request should have triggered download of PAC script.
  EXPECT_TRUE(fetcher->has_pending_request());
  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());

  service.OnShutdown();
  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_FALSE(fetcher->has_pending_request());
  EXPECT_TRUE(info.is_direct());
}

TEST_F(ProxyResolutionServiceTest, OnShutdownFollowedByRequest) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);

  ProxyResolutionService service(base::WrapUnique(config_service),
                                 base::WrapUnique(factory), nullptr);

  MockPacFileFetcher* fetcher = new MockPacFileFetcher;
  service.SetPacFileFetchers(base::WrapUnique(fetcher),
                             std::make_unique<DoNothingDhcpPacFileFetcher>());

  service.OnShutdown();

  ProxyInfo info;
  TestCompletionCallback callback;
  std::unique_ptr<ProxyResolutionService::Request> request;
  int rv =
      service.ResolveProxy(GURL("http://request/"), std::string(), &info,
                           callback.callback(), &request, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_FALSE(fetcher->has_pending_request());
  EXPECT_TRUE(info.is_direct());
}

// Tests that the URL scheme for PAC files gets output to the histogram.
TEST_F(ProxyResolutionServiceTest, PacUrlSchemeHistogram) {
  PacUrlSchemeHistogramTester pac_histogram;

  MockProxyConfigService* config_service =
      new MockProxyConfigService(ProxyConfig::CreateDirect());

  ProxyResolutionService service(
      base::WrapUnique(config_service),
      std::make_unique<MockAsyncProxyResolverFactory>(false), nullptr);

  pac_histogram.VerifyHistogram();

  // Set an http:// PAC.
  config_service->SetPacUrlConfig("http://example.test/");
  pac_histogram.num_http++;
  pac_histogram.VerifyHistogram();

  // Set an https:// PAC.
  config_service->SetPacUrlConfig("hTTps://example.test/wpad.dat");
  pac_histogram.num_https++;
  pac_histogram.VerifyHistogram();

  // Set an ftp:// PAC.
  config_service->SetPacUrlConfig("ftp://example.test/pac.js");
  pac_histogram.num_ftp++;
  pac_histogram.VerifyHistogram();

  // Set an file:// PAC.
  config_service->SetPacUrlConfig("file://example.test/boo");
  pac_histogram.num_file++;
  pac_histogram.VerifyHistogram();

  // Set an mailto: PAC.
  config_service->SetPacUrlConfig("mailto:foo@example.test");
  pac_histogram.num_other++;
  pac_histogram.VerifyHistogram();

  // Set an data: PAC.
  config_service->SetPacUrlConfig("data:,Hello%2C%20World!");
  pac_histogram.num_data++;
  pac_histogram.VerifyHistogram();

  // Set an filesystem: PAC.
  config_service->SetPacUrlConfig("filesystem:http://example.test/pac.js");
  pac_histogram.num_other++;
  pac_histogram.VerifyHistogram();

  // Set another https:// as PAC.
  config_service->SetPacUrlConfig("https://example2.test/wpad.dat");
  pac_histogram.num_https++;
  pac_histogram.VerifyHistogram();
}

}  // namespace net
