15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/dhcp_proxy_script_fetcher.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/mock_proxy_resolver.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/mock_proxy_script_fetcher.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_script_fetcher.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(eroman): Write a test which exercises
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//              ProxyService::SuspendAllPendingRequests().
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This polling policy will decide to poll every 1 ms.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediatePollPolicy() {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta* next_delay) const OVERRIDE {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *next_delay = base::TimeDelta::FromMilliseconds(1);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return MODE_USE_TIMER;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This polling policy chooses a fantastically large delay. In other words, it
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will never trigger a poll
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NeverPollPolicy : public ProxyService::PacPollPolicy {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NeverPollPolicy() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta* next_delay) const OVERRIDE {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *next_delay = base::TimeDelta::FromDays(60);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return MODE_USE_TIMER;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This polling policy starts a poll immediately after network activity.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediateAfterActivityPollPolicy() {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::TimeDelta* next_delay) const OVERRIDE {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *next_delay = base::TimeDelta();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return MODE_START_AFTER_ACTIVITY;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test fixture is used to partially disable the background polling done by
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ProxyService (which it uses to detect whenever its PAC script contents or
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WPAD results have changed).
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We disable the feature by setting the poll interval to something really
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// large, so it will never actually be reached even on the slowest bots that run
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these tests.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We disable the polling in order to avoid any timing dependencies in the
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. If the bot were to run the tests very slowly and we hadn't disabled
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// polling, then it might start a background re-try in the middle of our test
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and confuse our expectations leading to flaky failures.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The tests which verify the polling code re-enable the polling behavior but
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are careful to avoid timing problems.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyServiceTest : public testing::Test {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::Test::SetUp();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    previous_policy_ =
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restore the original policy.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService::set_pac_script_poll_policy(previous_policy_);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::Test::TearDown();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NeverPollPolicy never_poll_policy_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProxyService::PacPollPolicy* previous_policy_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockProxyConfigService: public ProxyConfigService {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockProxyConfigService(const ProxyConfig& config)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : availability_(CONFIG_VALID),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        config_(config) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockProxyConfigService(const std::string& pac_url)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : availability_(CONFIG_VALID),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AddObserver(Observer* observer) OVERRIDE {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.AddObserver(observer);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RemoveObserver(Observer* observer) OVERRIDE {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.RemoveObserver(observer);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* results)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OVERRIDE {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (availability_ == CONFIG_VALID)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *results = config_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return availability_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetConfig(const ProxyConfig& config) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    availability_ = CONFIG_VALID;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config_ = config;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnProxyConfigChanged(config_, availability_));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigAvailability availability_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<Observer, true> observers_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, Direct) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(new MockProxyConfigService(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyConfig::CreateDirect()), resolver, NULL);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback.callback(), NULL, log.bound());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(info.proxy_resolve_start_time().is_null());
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(info.proxy_resolve_end_time().is_null());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the NetLog was filled correctly.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingNetLog::CapturedEntryList entries;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, entries.size());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsBeginEvent(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_PROXY_SERVICE));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEvent(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEndEvent(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 2, NetLog::TYPE_PROXY_SERVICE));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyService::PacRequest* request;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url, &info, callback.callback(), &request, log.bound());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request));
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.did_use_pac_script());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the NetLog was filled correctly.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingNetLog::CapturedEntryList entries;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5u, entries.size());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsBeginEvent(
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_PROXY_SERVICE));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsBeginEvent(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEndEvent(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEndEvent(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 4, NetLog::TYPE_PROXY_SERVICE));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the proxy resolver does not see the URL's username/password
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or its reference section.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://username:password@www.google.com/?ref#hash#hash");
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback.callback(), NULL, BoundNetLog());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL should have been simplified, stripping the username/password/hash.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://www.google.com/?ref"),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 resolver->pending_requests()[0]->url());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We end here without ever completing the request -- destruction of
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyService will cancel the outstanding request.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.did_use_pac_script());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, imagine that connecting to foopy:8080 fails: there is nothing
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // left to fallback to, since our proxy list was NOT terminated by
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DIRECT.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback2.callback(), NULL, BoundNetLog());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ReconsiderProxyAfterError returns error indicating nothing left.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_FAILED, rv);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_empty());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if the execution of the PAC script fails (i.e. javascript runtime
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error), and the PAC settings are non-mandatory, that we fall-back to direct.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC_RuntimeError) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://this-causes-js-error/");
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a failure in the PAC executor.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since the PAC script was non-mandatory, we should have fallen-back to
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DIRECT.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.did_use_pac_script());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, info.config_id());
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The proxy list could potentially contain the DIRECT fallback choice
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in a location other than the very end of the list, and could even
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specify it multiple times.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is not a typical usage, but we will obey it.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (If we wanted to disallow this type of input, the right place to
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enforce it would be in parsing the PAC result string).
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test will use the PAC result string:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then foobar:20, and then give up and error.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The important check of this test is to make sure that DIRECT is not somehow
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cached as being a bad proxy.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UsePacString(
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fallback 1.
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fallback 2.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fallback 3.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fallback 4 -- Nothing to fall back to!
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_FAILED, rv);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_empty());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to ProxyInfo after the proxy is resolved via a PAC script.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config =
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_source(PROXY_CONFIG_SOURCE_TEST);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resolve something.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback.callback(), NULL, BoundNetLog());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.did_use_pac_script());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyResolverFails) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test what happens when the ProxyResolver fails. The download and setting
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the PAC script have already succeeded, so this corresponds with a
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // javascript runtime error while calling FindProxyForURL().
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start first resolve request.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fail the first resolve request in MockAsyncProxyResolver.
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Although the proxy resolver failed the request, ProxyService implicitly
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls-back to DIRECT.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Failed PAC executions still have proxy resolution times.
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second resolve request will try to run through the proxy resolver,
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // regardless of whether the first request failed in it.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback2.callback(), NULL, BoundNetLog());
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This time we will have the resolver succeed (perhaps the PAC script has
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a dependency on the current time).
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test what happens when the ProxyScriptResolver fails to download a
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mandatory PAC script.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_mandatory(true);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start first resolve request.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As the proxy resolver failed the request and is configured for a mandatory
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback1.WaitForResult());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As the proxy resolver failed the request and is configured for a mandatory
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback2.callback(), NULL, BoundNetLog());
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test what happens when the ProxyResolver fails that is configured to use a
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mandatory PAC script. The download of the PAC script has already
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeeded but the PAC script contains no valid javascript.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config(
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_mandatory(true);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start resolve request.
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback.callback(), NULL, BoundNetLog());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Downloading the PAC script succeeds.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fetcher->has_pending_request());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mandatory for this configuration, the ProxyService must not implicitly
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fall-back to DIRECT.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback.WaitForResult());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test what happens when the ProxyResolver fails that is configured to use a
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mandatory PAC script. The download and setting of the PAC script have
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // already succeeded, so this corresponds with a javascript runtime error
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while calling FindProxyForURL().
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config(
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_mandatory(true);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start first resolve request.
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fail the first resolve request in MockAsyncProxyResolver.
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As the proxy resolver failed the request and is configured for a mandatory
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback1.WaitForResult());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second resolve request will try to run through the proxy resolver,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // regardless of whether the first request failed in it.
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback2.callback(), NULL, BoundNetLog());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This time we will have the resolver succeed (perhaps the PAC script has
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a dependency on the current time).
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyFallback) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test what happens when we specify multiple proxy servers and some of them
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are bad.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the proxy information.
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first item is valid.
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks proxy_resolve_start_time = info.proxy_resolve_start_time();
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks proxy_resolve_end_time = info.proxy_resolve_end_time();
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake an error on the proxy.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Proxy times should not have been modified by fallback.
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second proxy should be specified.
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Report back that the second proxy worked.  This will globally mark the
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first proxy as bad.
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.ReportSuccess(info);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback3.callback(), NULL, BoundNetLog());
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver -- the second result is already known
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be bad, so we will not try to use it initially.
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy3:7070;foopy1:8080;foopy2:9090");
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Proxy times should have been updated, so get them again.
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  proxy_resolve_start_time = info.proxy_resolve_start_time();
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  proxy_resolve_end_time = info.proxy_resolve_end_time();
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We fake another error. It should now try the third one.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We fake another error. At this point we have tried all of the
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy servers we thought were valid; next we try the proxy server
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that was in our bad proxies map (foopy1:8080).
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake another error, the last proxy is gone, the list should now be empty,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so there is nothing left to try.
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback6;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback6.callback(), NULL,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_FAILED, rv);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_empty());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Proxy times should not have been modified by fallback.
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look up proxies again
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback7;
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(url, &info, callback7.callback(), NULL,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            BoundNetLog());
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This time, the first 3 results have been found to be bad, but only the
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first proxy has been confirmed ...
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ... therefore, we should see the second proxy first.
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback7.WaitForResult());
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(nsylvain): Test that the proxy can be retried after the delay.
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is similar to ProxyFallback, but this time we have an explicit
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fallback choice to DIRECT.
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the proxy information.
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UsePacString(
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the first result.
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake an error on the proxy.
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now we get back the second proxy.
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake an error on this proxy as well.
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, we get back DIRECT.
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info.is_direct());
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now we tell the proxy service that even DIRECT failed.
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There was nothing left to try after DIRECT, so we are out of
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // choices.
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_FAILED, rv);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test proxy failover when new settings are available.
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the proxy information.
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the result in proxy resolver.
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first item is valid.
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake an error on the proxy, and also a new configuration on the proxy.
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_service->SetConfig(
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first proxy is still there since the configuration changed.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We fake another error. It should now ignore the first one.
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We simulate a new configuration.
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_service->SetConfig(
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL("http://foopy-new2/proxy.pac")));
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We fake another error. It should go back to the first proxy.
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback4.WaitForResult());
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test proxy failover when the configuration is bad.
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the proxy information.
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first item is valid.
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a proxy error.
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first proxy is ignored, and the second one is selected.
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a PAC failure.
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info2, callback3.callback(), NULL, BoundNetLog());
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates a javascript runtime error in the PAC script.
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Although the resolver failed, the ProxyService will implicitly fall-back
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a DIRECT connection.
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2.is_direct());
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info2.is_empty());
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PAC script will work properly next time and successfully return a
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy list. Since we have not marked the configuration as bad, it should
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "just work" the next time we call it.
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         NULL, BoundNetLog());
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first proxy is not there since the it was added to the bad proxies
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // list by the earlier ReconsiderProxyAfterError().
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback4.WaitForResult());
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info3.is_direct());
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test proxy failover when the configuration is bad.
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config(
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_mandatory(true);
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the proxy information.
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback1.callback(), NULL, BoundNetLog());
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first item is valid.
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a proxy error.
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BoundNetLog());
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first proxy is ignored, and the second one is selected.
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info.is_direct());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fake a PAC failure.
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info2, callback3.callback(), NULL, BoundNetLog());
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates a javascript runtime error in the PAC script.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Although the resolver failed, the ProxyService will NOT fall-back
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a DIRECT connection as it is configured as mandatory.
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback3.WaitForResult());
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info2.is_direct());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2.is_empty());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PAC script will work properly next time and successfully return a
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy list. Since we have not marked the configuration as bad, it should
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "just work" the next time we call it.
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         NULL, BoundNetLog());
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy(
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foopy1:8080;foopy2:9090");
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first proxy is not there since the it was added to the bad proxies
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // list by the earlier ReconsiderProxyAfterError().
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback4.WaitForResult());
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(info3.is_direct());
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyBypassList) {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that the proxy bypass rules are consulted.
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback[2];
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info[2];
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(false);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().bypass_rules.ParseFromString("*.org");
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv;
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url1("http://www.webkit.org");
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url2("http://www.webkit.com");
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request for a .org domain should bypass proxy.
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, &info[0], callback[0].callback(), NULL, BoundNetLog());
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info[0].is_direct());
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request for a .com domain hits the proxy.
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, &info[1], callback[1].callback(), NULL, BoundNetLog());
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(false);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://www.msn.com");
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("ftp://ftp.google.com");
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(info.is_direct());
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("direct://", info.proxy_server().ToURI());
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("https://webbranch.techcu.com");
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.proxy_rules().ParseFromString("foopy1:8080");
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://www.microsoft.com");
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that the proxy config source is set correctly when resolving proxies
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // using manual proxy rules. Namely, the config source should only be set if
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any of the rules were applied.
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyConfig config;
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.set_source(PROXY_CONFIG_SOURCE_TEST);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.proxy_rules().ParseFromString("https=foopy2:8080");
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://www.google.com");
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, rv);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyConfig config;
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.set_source(PROXY_CONFIG_SOURCE_TEST);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.proxy_rules().ParseFromString("https=foopy2:8080");
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("https://www.google.com");
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, rv);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Used the HTTPS proxy. So source should be TEST.
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyConfig config;
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    config.set_source(PROXY_CONFIG_SOURCE_TEST);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://www.google.com");
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, rv);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ProxyConfig is empty. Source should still be TEST.
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fall back to the SOCKS proxy.
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(false);
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            config.proxy_rules().type);
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://www.msn.com");
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("ftp://ftp.google.com");
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("https://webbranch.techcu.com");
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyService service(
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("unknown://www.microsoft.com");
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyInfo info;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  BoundNetLog());
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(info.is_direct());
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test cancellation of an in-progress request.
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, CancelInProgressRequest) {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 3 requests.
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the proxy resolver yet, since the proxy
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resolver has not been configured yet.
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Successfully initialize the PAC script.
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request2;
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, resolver->pending_requests().size());
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request3"), &info3,
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback3.callback(), NULL, BoundNetLog());
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, resolver->pending_requests().size());
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel the second request
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.CancelPacRequest(request2);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, resolver->pending_requests().size());
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the two un-cancelled requests.
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We complete the last one first, just to mix it up a bit.
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->CompleteNow(OK);
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete and verify that requests ran as expected.
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(callback2.have_result());  // Cancelled.
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->cancelled_requests().size());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the initial PAC download for resolver that expects bytes.
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 3 requests.
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyService::PacRequest* request1;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                callback1.callback(), &request1, BoundNetLog());
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered download of PAC script.
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyService::PacRequest* request2;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyService::PacRequest* request3;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request3"), &info3,
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            callback3.callback(), &request3, BoundNetLog());
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            service.GetLoadState(request1));
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            service.GetLoadState(request2));
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            service.GetLoadState(request3));
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, it will have been sent to the proxy
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resolver.
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, resolver->pending_requests().size());
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1));
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2));
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3));
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete all the requests (in some order).
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that as we complete requests, they shift up in |pending_requests()|.
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[2]->CompleteNow(OK);
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete and verify that requests ran as expected.
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info3.proxy_resolve_start_time().is_null());
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info3.proxy_resolve_end_time().is_null());
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test changing the ProxyScriptFetcher while PAC download is in progress.
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 2 requests.
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered download of PAC script.
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), NULL, BoundNetLog());
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now change out the ProxyService's script fetcher. We should restart
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the initialization with the new fetcher.
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher = new MockProxyScriptFetcher;
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, it will have been sent to the proxy
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resolver.
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, resolver->pending_requests().size());
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test cancellation of a request, while the PAC script is being fetched.
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 3 requests.
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request1;
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log1;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), &request1, log1.bound());
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered download of PAC script.
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request2;
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request3"), &info3,
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback3.callback(), NULL, BoundNetLog());
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel the first 2 requests.
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.CancelPacRequest(request1);
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.CancelPacRequest(request2);
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, it will have been sent to the
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy resolver.
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete all the requests.
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->cancelled_requests().empty());
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(callback1.have_result());  // Cancelled.
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(callback2.have_result());  // Cancelled.
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingNetLog::CapturedEntryList entries1;
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log1.GetEntries(&entries1);
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the NetLog for request 1 (which was cancelled) got filled properly.
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4u, entries1.size());
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsBeginEvent(
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries1, 0, NetLog::TYPE_PROXY_SERVICE));
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsBeginEvent(
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the cancellation occured.
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEvent(
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEndEvent(
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries1, 3, NetLog::TYPE_PROXY_SERVICE));
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if auto-detect fails, we fall-back to the custom pac.
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(true);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_url(GURL("http://foopy/proxy.pac"));
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 2 requests.
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request2;
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be trying to auto-detect first -- FAIL the autodetect during
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the script download.
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next it should be trying the custom PAC url.
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now finally, the pending requests should have been sent to the resolver
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (which was initialized with custom PAC script).
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, resolver->pending_requests().size());
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending requests.
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->CompleteNow(OK);
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that requests ran as expected.
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the same test as FallbackFromAutodetectToCustomPac, except
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the auto-detect script fails parsing rather than downloading.
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(true);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_url(GURL("http://foopy/proxy.pac"));
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 2 requests.
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request2;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be trying to auto-detect first -- succeed the download.
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The script contents passed failed basic verification step (since didn't
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contain token FindProxyForURL), so it was never passed to the resolver.
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next it should be trying the custom PAC url.
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now finally, the pending requests should have been sent to the resolver
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (which was initialized with custom PAC script).
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, resolver->pending_requests().size());
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending requests.
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[1]->CompleteNow(OK);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that requests ran as expected.
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if all of auto-detect, a custom PAC script, and manual settings
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are given, then we will try them in that order.
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(true);
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_url(GURL("http://foopy/proxy.pac"));
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy:80");
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 2 requests.
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacRequest* request2;
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), &request2, BoundNetLog());
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be trying to auto-detect first -- fail the download.
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Next it should be trying the custom PAC url -- fail the download.
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we never managed to initialize a ProxyResolver, nothing should have
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // been sent to it.
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that requests ran as expected -- they should have fallen back to
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the manual proxy configuration for HTTP urls.
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the bypass rules are NOT applied when using autodetect.
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config;
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_auto_detect(true);
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.set_pac_url(GURL("http://foopy/proxy.pac"));
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().ParseFromString("http=foopy:80");  // Not used.
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 requests.
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://www.google.com"), &info1, callback1.callback(), NULL,
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be trying to auto-detect first -- succeed the download.
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://www.google.com"),
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_requests()[0]->url());
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that request ran as expected.
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start another request, it should pickup the bypass item.
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), NULL, BoundNetLog());
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://www.google.com"),
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_requests()[0]->url());
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delete the ProxyService while InitProxyResolver has an outstanding
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// request to the script fetcher. When run under valgrind, should not
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// have any memory errors (used to be that the ProxyScriptFetcher was
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// being deleted prior to the InitProxyResolver).
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config =
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // InitProxyResolver should have issued a request to the ProxyScriptFetcher
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and be waiting on that to complete.
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delete the ProxyService while InitProxyResolver has an outstanding
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// request to the proxy resolver. When run under valgrind, should not
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// have any memory errors (used to be that the ProxyResolver was
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// being deleted prior to the InitProxyResolver).
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://www.google.com/");
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, &info, callback.callback(), NULL, BoundNetLog());
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->url());
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, ResetProxyConfigService) {
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config1;
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config1.proxy_rules().ParseFromString("foopy1:8080");
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config1.set_auto_detect(false);
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService(config1),
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes, NULL);
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info;
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info,
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config2;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config2.proxy_rules().ParseFromString("foopy2:8080");
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config2.set_auto_detect(false);
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.ResetConfigService(new MockProxyConfigService(config2));
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info,
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), NULL, BoundNetLog());
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that when going from a configuration that required PAC to one
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that does NOT, we unset the variable |should_use_proxy_resolver_|.
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig config = ProxyConfig::CreateAutoDetect();
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service = new MockProxyConfigService(config);
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that nothing has been sent to the proxy resolver yet.
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, resolver->pending_requests().size());
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Successfully set the autodetect script.
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->type());
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that request ran as expected.
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force the ProxyService to pull down a new proxy configuration.
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (Even though the configuration isn't old/bad).
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This new configuration no longer has auto_detect set, so
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requests should complete synchronously now as direct-connect.
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_service->SetConfig(ProxyConfig::CreateDirect());
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start another request -- the effective configuration has changed.
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), NULL, BoundNetLog());
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2.is_direct());
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingNetLog log;
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, &log);
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable the "wait after IP address changes" hack, so this unit-test can
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complete quickly.
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.set_stall_proxy_auto_config_delay(base::TimeDelta());
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                callback1.callback(), NULL, BoundNetLog());
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the request will have been sent to
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proxy resolver.
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simluate a change in the network. The ProxyConfigService is still
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // going to return the same PAC URL as before, but this URL needs to be
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // refetched on the new network.
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
215990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();  // Notification happens async.
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(GURL("http://request2"), &info2,
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            callback2.callback(), NULL, BoundNetLog());
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This second request should have triggered the re-download of the PAC
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // script (since we marked the network as having changed).
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the PAC script fetch as having completed (this time with
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // different data).
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the second request will have been
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sent to the proxy resolver.
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending second request.
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the expected events were output to the log stream. In particular
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // setup), and NOT a second time when the IP address changed.
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingNetLog::CapturedEntryList entries;
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       NetLog::TYPE_PROXY_CONFIG_CHANGED));
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(9u, entries.size());
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 1; i < entries.size(); ++i)
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test verifies that the PAC script specified by the settings is
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// periodically polled for changes. Specifically, if the initial fetch fails due
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a network error, we will eventually re-configure the service to use the
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// script once it becomes available.
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the retry policy to wait a mere 1 ms before retrying, so the test
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs quickly.
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediatePollPolicy poll_policy;
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::set_pac_script_poll_policy(&poll_policy);
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request1"), &info1, callback1.callback(),
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, BoundNetLog());
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We simulate a failed download attempt, the proxy service should now
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fall-back to DIRECT connections.
2254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify it used DIRECT.
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info1.is_direct());
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point we have initialized the proxy service using a PAC script,
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // however it failed and fell-back to DIRECT.
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A background task to periodically re-check the PAC script for validity will
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have been started. We will now wait for the next download attempt to start.
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we shouldn't have to wait long here, since our test enables a
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special unit-test mode.
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->WaitUntilFetch();
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that our background checker is trying to download the expected
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script (same one as before). This time we will simulate a successful
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // download of the script.
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, it should be used to initialize the
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyResolver. Simulate a successful parse.
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should have re-configured itself to use the
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script (thereby recovering from the initial fetch failure). We will
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // verify that the next Resolve request uses the resolver rather than
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DIRECT.
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request2"), &info2, callback2.callback(), NULL,
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that it was sent to the resolver.
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending second request.
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test verifies that the PAC script specified by the settings is
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// periodically polled for changes. Specifically, if the initial fetch succeeds,
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// however at a later time its *contents* change, we will eventually
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// re-configure the service to use the new script.
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the retry policy to wait a mere 1 ms before retrying, so the test
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs quickly.
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediatePollPolicy poll_policy;
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::set_pac_script_poll_policy(&poll_policy);
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request1"), &info1, callback1.callback(), NULL,
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the request will have been sent to
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proxy resolver.
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point we have initialized the proxy service using a PAC script.
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A background task to periodically re-check the PAC script for validity will
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have been started. We will now wait for the next download attempt to start.
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we shouldn't have to wait long here, since our test enables a
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special unit-test mode.
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->WaitUntilFetch();
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that our background checker is trying to download the expected
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script (same one as before). This time we will simulate a successful
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // download of a DIFFERENT script.
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
239390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, it should be used to initialize the
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyResolver. Simulate a successful parse.
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should have re-configured itself to use the
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new PAC script.
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request2"), &info2, callback2.callback(), NULL,
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that it was sent to the resolver.
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending second request.
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test verifies that the PAC script specified by the settings is
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// periodically polled for changes. Specifically, if the initial fetch succeeds
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and so does the next poll, however the contents of the downloaded script
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// have NOT changed, then we do not bother to re-initialize the proxy resolver.
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the retry policy to wait a mere 1 ms before retrying, so the test
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs quickly.
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediatePollPolicy poll_policy;
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::set_pac_script_poll_policy(&poll_policy);
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request1"), &info1, callback1.callback(), NULL,
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the request will have been sent to
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proxy resolver.
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point we have initialized the proxy service using a PAC script.
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A background task to periodically re-check the PAC script for validity will
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have been started. We will now wait for the next download attempt to start.
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we shouldn't have to wait long here, since our test enables a
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special unit-test mode.
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->WaitUntilFetch();
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that our background checker is trying to download the expected
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script (same one as before). We will simulate the same response as
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // last time (i.e. the script is unchanged).
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(resolver->has_pending_set_pac_script_request());
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService is still running the same PAC script as
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before.
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request2"), &info2, callback2.callback(), NULL,
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that it was sent to the resolver.
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending second request.
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test verifies that the PAC script specified by the settings is
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// periodically polled for changes. Specifically, if the initial fetch succeeds,
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// however at a later time it starts to fail, we should re-configure the
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyService to stop using that PAC script.
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the retry policy to wait a mere 1 ms before retrying, so the test
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // runs quickly.
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediatePollPolicy poll_policy;
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::set_pac_script_poll_policy(&poll_policy);
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request1"), &info1, callback1.callback(), NULL,
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the request will have been sent to
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proxy resolver.
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point we have initialized the proxy service using a PAC script.
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A background task to periodically re-check the PAC script for validity will
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have been started. We will now wait for the next download attempt to start.
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we shouldn't have to wait long here, since our test enables a
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special unit-test mode.
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->WaitUntilFetch();
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that our background checker is trying to download the expected
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script (same one as before). This time we will simulate a failure
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to download the script.
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
2607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
260990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should have re-configured itself to use
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DIRECT connections rather than the given proxy resolver.
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request2"), &info2, callback2.callback(), NULL,
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2.is_direct());
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the code which decides at what times to poll the PAC
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// script follows the expected policy.
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the internal polling policy implementation used by ProxyService.
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ProxyService::PacPollPolicy> policy =
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateDefaultPacPollPolicy();
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error;
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::PacPollPolicy::Mode mode;
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta delay = initial_delay;
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --------------------------------------------------
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the poll sequence in response to a failure.
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --------------------------------------------------
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = ERR_NAME_NOT_RESOLVED;
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #0
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, initial_delay, &delay);
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, delay.InSeconds());
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #1
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(32, delay.InSeconds());
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #2
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(120, delay.InSeconds());
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #3
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14400, delay.InSeconds());
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #4
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14400, delay.InSeconds());
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --------------------------------------------------
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test the poll sequence in response to a success.
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --------------------------------------------------
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error = OK;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #0
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, initial_delay, &delay);
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(43200, delay.InSeconds());
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #1
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(43200, delay.InSeconds());
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Poll #2
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mode = policy->GetNextDelay(error, delay, &delay);
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(43200, delay.InSeconds());
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the polling of the PAC script. Specifically, it tests that
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// polling occurs in response to user activity.
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImmediateAfterActivityPollPolicy poll_policy;
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService::set_pac_script_poll_policy(&poll_policy);
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyConfigService* config_service =
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockProxyConfigService("http://foopy/proxy.pac");
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAsyncProxyResolverExpectsBytes* resolver =
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockAsyncProxyResolverExpectsBytes;
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyService service(config_service, resolver, NULL);
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.SetProxyScriptFetchers(fetcher,
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 new DoNothingDhcpProxyScriptFetcher());
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start 1 request.
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info1;
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = service.ResolveProxy(
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request1"), &info1, callback1.callback(), NULL,
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request should have triggered initial download of PAC script.
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing has been sent to the resolver yet.
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(resolver->pending_requests().empty());
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the ProxyService should be waiting for the
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProxyScriptFetcher to invoke its completion callback, notifying it of
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PAC script download completion.
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that the PAC script is downloaded, the request will have been sent to
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proxy resolver.
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            resolver->pending_set_pac_script_request()->script_data()->utf16());
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_set_pac_script_request()->CompleteNow(OK);
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the pending request.
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for completion callback, and verify that the request ran as expected.
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point we have initialized the proxy service using a PAC script.
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our PAC poller is set to update ONLY in response to network activity,
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (i.e. another call to ResolveProxy()).
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(fetcher->has_pending_request());
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resolver->pending_requests().empty());
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a second request.
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info2;
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request2"), &info2, callback2.callback(), NULL,
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This request should have sent work to the resolver; complete it.
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, resolver->pending_requests().size());
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resolver->pending_requests()[0]->CompleteNow(OK);
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In response to getting that resolve request, the poller should have
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // started the next poll, and made it as far as to request the download.
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->has_pending_request());
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This time we will fail the download, to simulate a PAC script change.
2774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drain the message loop, so ProxyService is notified of the change
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and has a chance to re-configure itself.
277890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a third request -- this time we expect to get a direct connection
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the PAC script poller experienced a failure.
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyInfo info3;
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = service.ResolveProxy(
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("http://request3"), &info3, callback3.callback(), NULL,
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundNetLog());
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info3.is_direct());
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2792