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

#include <vector>

#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate_impl.h"
#include "net/base/test_completion_callback.h"
#include "net/log/net_log.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/dhcp_proxy_script_fetcher.h"
#include "net/proxy/mock_proxy_resolver.h"
#include "net/proxy/mock_proxy_script_fetcher.h"
#include "net/proxy/proxy_config_service.h"
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_script_fetcher.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using base::ASCIIToUTF16;

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

// This polling policy will decide to poll every 1 ms.
class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
 public:
  ImmediatePollPolicy() {}

  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 ProxyService::PacPollPolicy {
 public:
  NeverPollPolicy() {}

  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 ProxyService::PacPollPolicy {
 public:
  ImmediateAfterActivityPollPolicy() {}

  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 ProxyService (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 ProxyServiceTest : public testing::Test {
 protected:
  void SetUp() override {
    testing::Test::SetUp();
    previous_policy_ =
        ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
  }

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

 private:
  NeverPollPolicy never_poll_policy_;
  const ProxyService::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_(config) {
  }

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

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

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

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

  void SetConfig(const ProxyConfig& config) {
    availability_ = CONFIG_VALID;
    config_ = config;
    FOR_EACH_OBSERVER(Observer, observers_,
                      OnProxyConfigChanged(config_, availability_));
  }

 private:
  ConfigAvailability availability_;
  ProxyConfig config_;
  ObserverList<Observer, true> observers_;
};

// A test network delegate that exercises the OnResolveProxy callback.
class TestResolveProxyNetworkDelegate : public NetworkDelegateImpl {
 public:
  TestResolveProxyNetworkDelegate()
      : on_resolve_proxy_called_(false),
        add_proxy_(false),
        remove_proxy_(false),
        proxy_service_(NULL) {
  }

  void OnResolveProxy(const GURL& url,
                      int load_flags,
                      const ProxyService& proxy_service,
                      ProxyInfo* result) override {
    on_resolve_proxy_called_ = true;
    proxy_service_ = &proxy_service;
    DCHECK(!add_proxy_ || !remove_proxy_);
    if (add_proxy_) {
      result->UseNamedProxy("delegate_proxy.com");
    } else if (remove_proxy_) {
      result->UseDirect();
    }
  }

  bool on_resolve_proxy_called() const {
    return on_resolve_proxy_called_;
  }

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

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

  const ProxyService* proxy_service() const {
    return proxy_service_;
  }

 private:
  bool on_resolve_proxy_called_;
  bool add_proxy_;
  bool remove_proxy_;
  const ProxyService* proxy_service_;
};

// A test network delegate that exercises the OnProxyFallback callback.
class TestProxyFallbackNetworkDelegate : public NetworkDelegateImpl {
 public:
  TestProxyFallbackNetworkDelegate()
      : on_proxy_fallback_called_(false),
        proxy_fallback_net_error_(OK) {
  }

  void OnProxyFallback(const ProxyServer& proxy_server,
                       int net_error) override {
    proxy_server_ = proxy_server;
    proxy_fallback_net_error_ = net_error;
    on_proxy_fallback_called_ = true;
  }

  bool on_proxy_fallback_called() const {
    return on_proxy_fallback_called_;
  }

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

  int proxy_fallback_net_error() const {
    return proxy_fallback_net_error_;
  }

 private:
  bool on_proxy_fallback_called_;
  ProxyServer proxy_server_;
  int proxy_fallback_net_error_;
};

}  // namespace

TEST_F(ProxyServiceTest, Direct) {
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyService service(new MockProxyConfigService(ProxyConfig::CreateDirect()),
                       make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, log.bound());
  EXPECT_EQ(OK, rv);
  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, NetLog::TYPE_PROXY_SERVICE));
  EXPECT_TRUE(LogContainsEvent(
      entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
      NetLog::PHASE_NONE));
  EXPECT_TRUE(LogContainsEndEvent(
      entries, 2, NetLog::TYPE_PROXY_SERVICE));
}

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

  ProxyService service(new MockProxyConfigService(config), nullptr, NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;

  // First, warm up the ProxyService.
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, log.bound());
  EXPECT_EQ(OK, rv);

  // Verify that network delegate is invoked.
  TestResolveProxyNetworkDelegate delegate;
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
                            &delegate, log.bound());
  EXPECT_TRUE(delegate.on_resolve_proxy_called());
  EXPECT_EQ(&service, delegate.proxy_service());

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

  // Callback should interpose:
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
                            &delegate, 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, LOAD_NORMAL, &info, callback.callback(), NULL,
                            &delegate, 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, LOAD_NORMAL, &info, callback.callback(),
                            NULL, &delegate, log.bound());
  EXPECT_TRUE(info.is_direct());
}

TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
  // Same as OnResolveProxyCallbackAddProxy, but verify that the
  // NetworkDelegate'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");

  ProxyService service(new MockProxyConfigService(config), nullptr, NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  BoundTestNetLog log;

  // First, warm up the ProxyService.
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, log.bound());
  EXPECT_EQ(OK, rv);

  TestResolveProxyNetworkDelegate delegate;
  delegate.set_remove_proxy(true);

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

  // Check non-bypassed URL:
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(), NULL,
                            &delegate, 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, LOAD_NORMAL, &info, callback.callback(),
                            NULL, &delegate, log.bound());
  EXPECT_TRUE(info.is_direct());
}

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  ProxyService::PacRequest* request;
  BoundTestNetLog log;

  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                &request, NULL, log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request));

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  EXPECT_EQ(OK, callback.WaitForResult());
  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, NetLog::TYPE_PROXY_SERVICE));
  EXPECT_TRUE(LogContainsBeginEvent(
      entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
  EXPECT_TRUE(LogContainsEndEvent(
      entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
  EXPECT_TRUE(LogContainsEndEvent(
      entries, 4, NetLog::TYPE_PROXY_SERVICE));
}

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  // The URL should have been simplified, stripping the username/password/hash.
  EXPECT_EQ(GURL("http://www.google.com/?ref"),
            resolver.pending_requests()[0]->url());

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  EXPECT_EQ(OK, callback1.WaitForResult());
  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.
  NetworkDelegateImpl network_delegate;
  TestCompletionCallback callback2;
  ProxyServer expected_proxy_server = info.proxy_server();
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, &network_delegate, BoundNetLog());
  // ReconsiderProxyAfterError returns error indicating nothing left.
  EXPECT_EQ(ERR_FAILED, rv);
  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(ProxyServiceTest, PAC_RuntimeError) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  EXPECT_EQ(OK, callback1.WaitForResult());

  // 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_EQ(1, info.config_id());

  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(ProxyServiceTest, PAC_FailoverAfterDirect) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  EXPECT_EQ(OK, callback1.WaitForResult());
  EXPECT_TRUE(info.is_direct());

  // Fallback 1.
  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foobar:10", info.proxy_server().ToURI());

  // Fallback 2.
  NetworkDelegateImpl network_delegate;
  ProxyServer expected_proxy_server3 = info.proxy_server();
  TestCompletionCallback callback3;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback3.callback(), NULL, &network_delegate, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(info.is_direct());

  // Fallback 3.
  ProxyServer expected_proxy_server4 = info.proxy_server();
  TestCompletionCallback callback4;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback4.callback(), NULL, &network_delegate, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foobar:20", info.proxy_server().ToURI());

  // Fallback 4 -- Nothing to fall back to!
  ProxyServer expected_proxy_server5 = info.proxy_server();
  TestCompletionCallback callback5;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback5.callback(), NULL, &network_delegate, BoundNetLog());
  EXPECT_EQ(ERR_FAILED, rv);
  EXPECT_TRUE(info.is_empty());
}

TEST_F(ProxyServiceTest, 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"));
  config.set_source(PROXY_CONFIG_SOURCE_TEST);

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Resolve something.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, BoundNetLog());
  ASSERT_EQ(ERR_IO_PENDING, rv);
  factory->pending_requests()[0]->CompleteNowWithForwarder(OK, &resolver);
  ASSERT_EQ(1u, resolver.pending_requests().size());

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

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
  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(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  // Although the proxy resolver failed the request, ProxyService implicitly
  // falls-back to DIRECT.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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, LOAD_NORMAL, &info, callback2.callback(), NULL,
                            NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

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

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), nullptr);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback1.callback(),
                           nullptr, nullptr, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  // Although the proxy resolver failed the request, ProxyService implicitly
  // falls-back to DIRECT.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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 ProxyService waits for a new request before
  // initializing a new ProxyResolver.
  EXPECT_TRUE(factory->pending_requests().empty());

  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback2.callback(),
                            nullptr, nullptr, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

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

TEST_F(ProxyServiceTest,
       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);

  ProxyService service(config_service, make_scoped_ptr(factory), nullptr);

  // Start two resolve requests.
  GURL url1("http://www.google.com/");
  GURL url2("https://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(url1, net::LOAD_NORMAL, &info, callback1.callback(),
                           nullptr, nullptr, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url2, net::LOAD_NORMAL, &info, callback2.callback(),
                            nullptr, nullptr, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url1, resolver.pending_requests()[0]->url());
  EXPECT_EQ(url2, resolver.pending_requests()[1]->url());

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

  // Although the proxy resolver failed the request, ProxyService implicitly
  // falls-back to DIRECT.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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.
  ASSERT_EQ(1u, resolver.cancelled_requests().size());
  EXPECT_EQ(url2, resolver.cancelled_requests()[0]->url());

  // Since a second request was in progress, the ProxyService 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);

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

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

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

TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
  // Test what happens when the ProxyScriptResolver 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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, ProxyService 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, ProxyService must not implicitly fall-back to DIRECT.
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback2.callback(), NULL,
                            NULL, BoundNetLog());
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
  EXPECT_FALSE(info.is_direct());
}

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
  service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);

  // Start resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyScriptDecider failed to identify a valid PAC and PAC was
  // mandatory for this configuration, the ProxyService must not implicitly
  // fall-back to DIRECT.
  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
            callback.WaitForResult());
  EXPECT_FALSE(info.is_direct());
}

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Start first resolve request.
  GURL url("http://www.google.com/");
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  // As the proxy resolver failed the request and is configured for a mandatory
  // PAC script, ProxyService 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, LOAD_NORMAL, &info, callback2.callback(), NULL,
                            NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

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

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

  // The first item is valid.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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.
  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

  // 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.
  TestProxyFallbackNetworkDelegate test_delegate;
  service.ReportSuccess(info, &test_delegate);
  EXPECT_EQ("foopy1:8080", test_delegate.proxy_server().ToURI());
  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
            test_delegate.proxy_fallback_net_error());

  TestCompletionCallback callback3;
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback3.callback(), NULL,
                            NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ASSERT_EQ(1u, resolver.pending_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[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_requests()[0]->results()->UseNamedProxy(
      "foopy3:7070;foopy1:8080;foopy2:9090");
  resolver.pending_requests()[0]->CompleteNow(OK);

  EXPECT_EQ(OK, callback3.WaitForResult());
  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.
  TestCompletionCallback callback4;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback4.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  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).
  TestCompletionCallback callback5;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback5.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  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.
  TestCompletionCallback callback6;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback6.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_FAILED, rv);
  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, LOAD_NORMAL, &info, callback7.callback(), NULL,
                            NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // ... therefore, we should see the second proxy first.
  EXPECT_EQ(OK, callback7.WaitForResult());
  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(ProxyServiceTest, ProxyFallbackToDirect) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

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

  // Fake an error on the proxy.
  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

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

  // Fake an error on this proxy as well.
  TestCompletionCallback callback3;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback3.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

  // 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.
  TestCompletionCallback callback4;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback4.callback(), NULL, NULL, BoundNetLog());
  // There was nothing left to try after DIRECT, so we are out of
  // choices.
  EXPECT_EQ(ERR_FAILED, rv);
}

TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
  // Test proxy failover when new settings are available.

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

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

  // Fake an error on the proxy, and also a new configuration on the proxy.
  config_service->SetConfig(
      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));

  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

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

  // The first proxy is still there since the configuration changed.
  EXPECT_EQ(OK, callback2.WaitForResult());
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  // We fake another error. It should now ignore the first one.
  TestCompletionCallback callback3;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback3.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());

  // We simulate a new configuration.
  config_service->SetConfig(
      ProxyConfig::CreateFromCustomPacURL(
          GURL("http://foopy-new2/proxy.pac")));

  // We fake another error. It should go back to the first proxy.
  TestCompletionCallback callback4;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback4.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

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

  EXPECT_EQ(OK, callback4.WaitForResult());
  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());
}

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

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

  // Fake a proxy error.
  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

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

  // Fake a PAC failure.
  ProxyInfo info2;
  TestCompletionCallback callback3;
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info2, callback3.callback(),
                            NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // Although the resolver failed, the ProxyService will implicitly fall-back
  // to a DIRECT connection.
  EXPECT_EQ(OK, callback3.WaitForResult());
  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 callback4;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info3,
      callback4.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // The first proxy is not there since the it was added to the bad proxies
  // list by the earlier ReconsiderProxyAfterError().
  EXPECT_EQ(OK, callback4.WaitForResult());
  EXPECT_FALSE(info3.is_direct());
  EXPECT_EQ("foopy1:8080", info3.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());
}

TEST_F(ProxyServiceTest, 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);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  // Get the proxy information.
  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback1.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  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_requests().size());
  EXPECT_EQ(url, resolver.pending_requests()[0]->url());

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

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

  // Fake a proxy error.
  TestCompletionCallback callback2;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info,
      callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

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

  // Fake a PAC failure.
  ProxyInfo info2;
  TestCompletionCallback callback3;
  rv = service.ResolveProxy(url, LOAD_NORMAL, &info2, callback3.callback(),
                            NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // Although the resolver failed, the ProxyService 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;
  rv = service.ReconsiderProxyAfterError(
      url, LOAD_NORMAL, ERR_PROXY_CONNECTION_FAILED, &info3,
      callback4.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // The first proxy is not there since the it was added to the bad proxies
  // list by the earlier ReconsiderProxyAfterError().
  EXPECT_EQ(OK, callback4.WaitForResult());
  EXPECT_FALSE(info3.is_direct());
  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
}

TEST_F(ProxyServiceTest, 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");

  ProxyService service(new MockProxyConfigService(config), nullptr, NULL);

  int rv;
  GURL url1("http://www.webkit.org");
  GURL url2("http://www.webkit.com");

  // Request for a .org domain should bypass proxy.
  rv = service.ResolveProxy(url1, LOAD_NORMAL, &info[0], callback[0].callback(),
                            NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(info[0].is_direct());

  // Request for a .com domain hits the proxy.
  rv = service.ResolveProxy(url2, LOAD_NORMAL, &info[1], callback[1].callback(),
                            NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
}

TEST_F(ProxyServiceTest, 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());

  ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
  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, BoundNetLog());
  ASSERT_EQ(4u, retry_info.size());
  for (const ProxyServer& proxy_server :
       config.proxy_rules().proxies_for_http.GetAll()) {
    ProxyRetryInfoMap::const_iterator i =
        retry_info.find(proxy_server.host_port_pair().ToString());
    ASSERT_TRUE(i != retry_info.end());
  }
}

TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
  config.set_auto_detect(false);
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("http://www.msn.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("ftp://ftp.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_TRUE(info.is_direct());
    EXPECT_EQ("direct://", info.proxy_server().ToURI());
  }
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("https://webbranch.techcu.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
  }
  {
    config.proxy_rules().ParseFromString("foopy1:8080");
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("http://www.microsoft.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
}

TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
  // 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.
  {
    ProxyConfig config;
    config.set_source(PROXY_CONFIG_SOURCE_TEST);
    config.proxy_rules().ParseFromString("https=foopy2:8080");
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("http://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    ASSERT_EQ(OK, rv);
    // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
  }
  {
    ProxyConfig config;
    config.set_source(PROXY_CONFIG_SOURCE_TEST);
    config.proxy_rules().ParseFromString("https=foopy2:8080");
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("https://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    ASSERT_EQ(OK, rv);
    // Used the HTTPS proxy. So source should be TEST.
    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
  }
  {
    ProxyConfig config;
    config.set_source(PROXY_CONFIG_SOURCE_TEST);
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("http://www.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    ASSERT_EQ(OK, rv);
    // ProxyConfig is empty. Source should still be TEST.
    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
  }
}

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

  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("http://www.msn.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
  }
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("ftp://ftp.google.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("https://webbranch.techcu.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
  {
    ProxyService service(new MockProxyConfigService(config), nullptr, NULL);
    GURL test_url("unknown://www.microsoft.com");
    ProxyInfo info;
    TestCompletionCallback callback;
    int rv =
        service.ResolveProxy(test_url, LOAD_NORMAL, &info, callback.callback(),
                             NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, rv);
    EXPECT_FALSE(info.is_direct());
    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
  }
}

// Test cancellation of an in-progress request.
TEST_F(ProxyServiceTest, CancelInProgressRequest) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Start 3 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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);

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

  ProxyInfo info2;
  TestCompletionCallback callback2;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  ASSERT_EQ(2u, resolver.pending_requests().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());

  ProxyInfo info3;
  TestCompletionCallback callback3;
  rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
                            callback3.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  ASSERT_EQ(3u, resolver.pending_requests().size());
  EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[2]->url());

  // Cancel the second request
  service.CancelPacRequest(request2);

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

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

  resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

  // Complete and verify that requests ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());

  EXPECT_FALSE(callback2.have_result());  // Cancelled.
  ASSERT_EQ(1u, resolver.cancelled_requests().size());
  EXPECT_EQ(GURL("http://request2"), resolver.cancelled_requests()[0]->url());

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

// Test the initial PAC download for resolver that expects bytes.
TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 3 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  ProxyService::PacRequest* request1;
  int rv = service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                                callback1.callback(), &request1, NULL,
                                BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ProxyInfo info3;
  TestCompletionCallback callback3;
  ProxyService::PacRequest* request3;
  rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
                            callback3.callback(), &request3, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
            service.GetLoadState(request1));
  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
            service.GetLoadState(request2));
  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
            service.GetLoadState(request3));

  // At this point the ProxyService should be waiting for the
  // ProxyScriptFetcher 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(3u, resolver.pending_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[1]->url());
  EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[2]->url());

  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1));
  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2));
  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3));

  // Complete all the requests (in some order).
  // Note that as we complete requests, they shift up in |pending_requests()|.

  resolver.pending_requests()[2]->results()->UseNamedProxy("request3:80");
  resolver.pending_requests()[2]->CompleteNow(OK);

  resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

  resolver.pending_requests()[0]->results()->UseNamedProxy("request2:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

  // Complete and verify that requests ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_EQ(OK, callback2.WaitForResult());
  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_EQ(OK, callback3.WaitForResult());
  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 ProxyScriptFetcher while PAC download is in progress.
TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // 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);

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

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 3 requests.
  ProxyInfo info1;
  TestCompletionCallback callback1;
  ProxyService::PacRequest* request1;
  BoundTestNetLog log1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), &request1, NULL, log1.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ProxyInfo info3;
  TestCompletionCallback callback3;
  rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
                            callback3.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

  // Cancel the first 2 requests.
  service.CancelPacRequest(request1);
  service.CancelPacRequest(request2);

  // At this point the ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request3"), resolver.pending_requests()[0]->url());

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

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

  EXPECT_TRUE(resolver.cancelled_requests().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, NetLog::TYPE_PROXY_SERVICE));
  EXPECT_TRUE(LogContainsBeginEvent(
      entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
  // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
  // the cancellation occured.
  EXPECT_TRUE(LogContainsEvent(
      entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
  EXPECT_TRUE(LogContainsEndEvent(
      entries1, 3, NetLog::TYPE_PROXY_SERVICE));
}

// Test that if auto-detect fails, we fall-back to the custom pac.
TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
  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);
  MockAsyncProxyResolverExpectsBytes resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ProxyInfo info2;
  TestCompletionCallback callback2;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 requests should have been sent to the resolver
  // (which was initialized with custom PAC script).

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

  // Complete the pending requests.
  resolver.pending_requests()[1]->results()->UseNamedProxy("request2:80");
  resolver.pending_requests()[1]->CompleteNow(OK);
  resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

  // Verify that requests ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_EQ(OK, callback2.WaitForResult());
  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(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
  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);
  MockAsyncProxyResolverExpectsBytes resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ProxyInfo info2;
  TestCompletionCallback callback2;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 requests should have been sent to the resolver
  // (which was initialized with custom PAC script).

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

  // Complete the pending requests.
  resolver.pending_requests()[1]->results()->UseNamedProxy("request2:80");
  resolver.pending_requests()[1]->CompleteNow(OK);
  resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

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

  EXPECT_EQ(OK, callback2.WaitForResult());
  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(ProxyServiceTest, 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);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 2 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  ProxyInfo info2;
  TestCompletionCallback callback2;
  ProxyService::PacRequest* request2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), &request2, NULL,
                            BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 requests ran as expected -- they should have fallen back to
  // the manual proxy configuration for HTTP urls.
  EXPECT_EQ(OK, callback1.WaitForResult());
  EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());

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

// Test that the bypass rules are NOT applied when using autodetect.
TEST_F(ProxyServiceTest, 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);
  MockAsyncProxyResolverExpectsBytes resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 requests.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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_requests().size());
  EXPECT_EQ(GURL("http://www.google.com"),
            resolver.pending_requests()[0]->url());

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

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

  // Start another request, it should pickup the bypass item.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

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

// Delete the ProxyService 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 ProxyScriptFetcher was
// being deleted prior to the InitProxyResolver).
TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
  ProxyConfig config =
    ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(true);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyScriptFetcher
  // 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 ProxyService 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(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  TestCompletionCallback callback;
  int rv = service.ResolveProxy(url, LOAD_NORMAL, &info, callback.callback(),
                                NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

TEST_F(ProxyServiceTest, ResetProxyConfigService) {
  ProxyConfig config1;
  config1.proxy_rules().ParseFromString("foopy1:8080");
  config1.set_auto_detect(false);
  ProxyService service(new MockProxyConfigService(config1), nullptr, NULL);

  ProxyInfo info;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());

  ProxyConfig config2;
  config2.proxy_rules().ParseFromString("foopy2:8080");
  config2.set_auto_detect(false);
  service.ResetConfigService(new MockProxyConfigService(config2));
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  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(ProxyServiceTest, UpdateConfigFromPACToDirect) {
  ProxyConfig config = ProxyConfig::CreateAutoDetect();

  MockProxyConfigService* config_service = new MockProxyConfigService(config);
  MockAsyncProxyResolver resolver;
  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);
  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // Successfully set the autodetect script.
  EXPECT_EQ(ProxyResolverScriptData::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_requests().size());
  resolver.pending_requests()[0]->results()->UseNamedProxy("request1:80");
  resolver.pending_requests()[0]->CompleteNow(OK);

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

  // Force the ProxyService 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
  // requests should complete synchronously now as direct-connect.
  config_service->SetConfig(ProxyConfig::CreateDirect());

  // Start another request -- the effective configuration has changed.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://www.google.com"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);

  EXPECT_TRUE(info2.is_direct());
}

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

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

  TestNetLog log;

  ProxyService service(config_service, make_scoped_ptr(factory), &log);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // 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;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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::MessageLoop::current()->RunUntilIdle();  // Notification happens async.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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_requests().size());
  EXPECT_EQ(GURL("http://request2"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback2.WaitForResult());
  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,
                                       NetLog::TYPE_PROXY_CONFIG_CHANGED));
  ASSERT_EQ(9u, entries.size());
  for (size_t i = 1; i < entries.size(); ++i)
    EXPECT_NE(NetLog::TYPE_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(ProxyServiceTest, PACScriptRefetchAfterFailure) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyService::set_pac_script_poll_policy(&poll_policy);

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_EQ(OK, callback1.WaitForResult());
  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::MessageLoop::current()->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 ProxyService 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;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback2.WaitForResult());
  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(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyService::set_pac_script_poll_policy(&poll_policy);

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_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 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::MessageLoop::current()->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 ProxyService should have re-configured itself to use the
  // new PAC script.

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback2.WaitForResult());
  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(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyService::set_pac_script_poll_policy(&poll_policy);

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_requests().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::MessageLoop::current()->RunUntilIdle();

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

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

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback2.WaitForResult());
  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
// ProxyService to stop using that PAC script.
TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
  // Change the retry policy to wait a mere 1 ms before retrying, so the test
  // runs quickly.
  ImmediatePollPolicy poll_policy;
  ProxyService::set_pac_script_poll_policy(&poll_policy);

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_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 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::MessageLoop::current()->RunUntilIdle();

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

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  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(ProxyServiceTest, PACScriptPollingPolicy) {
  // Retrieve the internal polling policy implementation used by ProxyService.
  scoped_ptr<ProxyService::PacPollPolicy> policy =
      ProxyService::CreateDefaultPacPollPolicy();

  int error;
  ProxyService::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(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);

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

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

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

  // Poll #4
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(14400, delay.InSeconds());
  EXPECT_EQ(ProxyService::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(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);

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

  // Poll #2
  mode = policy->GetNextDelay(error, delay, &delay);
  EXPECT_EQ(43200, delay.InSeconds());
  EXPECT_EQ(ProxyService::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(ProxyServiceTest, PACScriptRefetchAfterActivity) {
  ImmediateAfterActivityPollPolicy poll_policy;
  ProxyService::set_pac_script_poll_policy(&poll_policy);

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

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

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
  service.SetProxyScriptFetchers(fetcher,
                                 new DoNothingDhcpProxyScriptFetcher());

  // Start 1 request.

  ProxyInfo info1;
  TestCompletionCallback callback1;
  int rv =
      service.ResolveProxy(GURL("http://request1"), LOAD_NORMAL, &info1,
                           callback1.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // 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 ProxyService should be waiting for the
  // ProxyScriptFetcher 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_requests().size());
  EXPECT_EQ(GURL("http://request1"), resolver.pending_requests()[0]->url());

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

  // Wait for completion callback, and verify that the request ran as expected.
  EXPECT_EQ(OK, callback1.WaitForResult());
  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_requests().empty());

  // Start a second request.
  ProxyInfo info2;
  TestCompletionCallback callback2;
  rv = service.ResolveProxy(GURL("http://request2"), LOAD_NORMAL, &info2,
                            callback2.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

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

  EXPECT_EQ(OK, callback2.WaitForResult());
  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 ProxyService is notified of the change
  // and has a chance to re-configure itself.
  base::MessageLoop::current()->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;
  rv = service.ResolveProxy(GURL("http://request3"), LOAD_NORMAL, &info3,
                            callback3.callback(), NULL, NULL, BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(info3.is_direct());
}

// Test that the synchronous resolution fails when a PAC script is active.
TEST_F(ProxyServiceTest, SynchronousWithPAC) {
  MockProxyConfigService* config_service =
      new MockProxyConfigService("http://foopy/proxy.pac");

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyService service(config_service, make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  info.UseDirect();
  BoundTestNetLog log;

  bool synchronous_success = service.TryResolveProxySynchronously(
      url, LOAD_NORMAL, &info, NULL, log.bound());
  EXPECT_FALSE(synchronous_success);

  // |info| should not have been modified.
  EXPECT_TRUE(info.is_direct());
}

// Test that synchronous results are returned correctly if a fixed proxy
// configuration is active.
TEST_F(ProxyServiceTest, SynchronousWithFixedConfiguration) {
  ProxyConfig config;
  config.proxy_rules().ParseFromString("foopy1:8080");
  config.set_auto_detect(false);

  MockAsyncProxyResolverFactory* factory =
      new MockAsyncProxyResolverFactory(false);

  ProxyService service(new MockProxyConfigService(config),
                       make_scoped_ptr(factory), NULL);

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

  ProxyInfo info;
  BoundTestNetLog log;

  bool synchronous_success = service.TryResolveProxySynchronously(
      url, LOAD_NORMAL, &info, NULL, log.bound());
  EXPECT_TRUE(synchronous_success);
  EXPECT_FALSE(info.is_direct());
  EXPECT_EQ("foopy1", info.proxy_server().host_port_pair().host());

  // No request should have been queued.
  EXPECT_EQ(0u, factory->pending_requests().size());
}

}  // namespace net
