Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/proxy/proxy_service.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/format_macros.h"
     10 #include "base/logging.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "net/base/load_flags.h"
     14 #include "net/base/net_errors.h"
     15 #include "net/base/net_log.h"
     16 #include "net/base/net_log_unittest.h"
     17 #include "net/base/network_delegate.h"
     18 #include "net/base/test_completion_callback.h"
     19 #include "net/proxy/dhcp_proxy_script_fetcher.h"
     20 #include "net/proxy/mock_proxy_resolver.h"
     21 #include "net/proxy/mock_proxy_script_fetcher.h"
     22 #include "net/proxy/proxy_config_service.h"
     23 #include "net/proxy/proxy_resolver.h"
     24 #include "net/proxy/proxy_script_fetcher.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 #include "url/gurl.h"
     27 
     28 using base::ASCIIToUTF16;
     29 
     30 // TODO(eroman): Write a test which exercises
     31 //              ProxyService::SuspendAllPendingRequests().
     32 namespace net {
     33 namespace {
     34 
     35 // This polling policy will decide to poll every 1 ms.
     36 class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
     37  public:
     38   ImmediatePollPolicy() {}
     39 
     40   virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
     41                             base::TimeDelta* next_delay) const OVERRIDE {
     42     *next_delay = base::TimeDelta::FromMilliseconds(1);
     43     return MODE_USE_TIMER;
     44   }
     45 
     46  private:
     47   DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
     48 };
     49 
     50 // This polling policy chooses a fantastically large delay. In other words, it
     51 // will never trigger a poll
     52 class NeverPollPolicy : public ProxyService::PacPollPolicy {
     53  public:
     54   NeverPollPolicy() {}
     55 
     56   virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
     57                             base::TimeDelta* next_delay) const OVERRIDE {
     58     *next_delay = base::TimeDelta::FromDays(60);
     59     return MODE_USE_TIMER;
     60   }
     61 
     62  private:
     63   DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
     64 };
     65 
     66 // This polling policy starts a poll immediately after network activity.
     67 class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
     68  public:
     69   ImmediateAfterActivityPollPolicy() {}
     70 
     71   virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
     72                             base::TimeDelta* next_delay) const OVERRIDE {
     73     *next_delay = base::TimeDelta();
     74     return MODE_START_AFTER_ACTIVITY;
     75   }
     76 
     77  private:
     78   DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
     79 };
     80 
     81 // This test fixture is used to partially disable the background polling done by
     82 // the ProxyService (which it uses to detect whenever its PAC script contents or
     83 // WPAD results have changed).
     84 //
     85 // We disable the feature by setting the poll interval to something really
     86 // large, so it will never actually be reached even on the slowest bots that run
     87 // these tests.
     88 //
     89 // We disable the polling in order to avoid any timing dependencies in the
     90 // tests. If the bot were to run the tests very slowly and we hadn't disabled
     91 // polling, then it might start a background re-try in the middle of our test
     92 // and confuse our expectations leading to flaky failures.
     93 //
     94 // The tests which verify the polling code re-enable the polling behavior but
     95 // are careful to avoid timing problems.
     96 class ProxyServiceTest : public testing::Test {
     97  protected:
     98   virtual void SetUp() OVERRIDE {
     99     testing::Test::SetUp();
    100     previous_policy_ =
    101         ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
    102   }
    103 
    104   virtual void TearDown() OVERRIDE {
    105     // Restore the original policy.
    106     ProxyService::set_pac_script_poll_policy(previous_policy_);
    107     testing::Test::TearDown();
    108   }
    109 
    110  private:
    111   NeverPollPolicy never_poll_policy_;
    112   const ProxyService::PacPollPolicy* previous_policy_;
    113 };
    114 
    115 const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
    116 const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";
    117 
    118 class MockProxyConfigService: public ProxyConfigService {
    119  public:
    120   explicit MockProxyConfigService(const ProxyConfig& config)
    121       : availability_(CONFIG_VALID),
    122         config_(config) {
    123   }
    124 
    125   explicit MockProxyConfigService(const std::string& pac_url)
    126       : availability_(CONFIG_VALID),
    127         config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
    128   }
    129 
    130   virtual void AddObserver(Observer* observer) OVERRIDE {
    131     observers_.AddObserver(observer);
    132   }
    133 
    134   virtual void RemoveObserver(Observer* observer) OVERRIDE {
    135     observers_.RemoveObserver(observer);
    136   }
    137 
    138   virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* results)
    139       OVERRIDE {
    140     if (availability_ == CONFIG_VALID)
    141       *results = config_;
    142     return availability_;
    143   }
    144 
    145   void SetConfig(const ProxyConfig& config) {
    146     availability_ = CONFIG_VALID;
    147     config_ = config;
    148     FOR_EACH_OBSERVER(Observer, observers_,
    149                       OnProxyConfigChanged(config_, availability_));
    150   }
    151 
    152  private:
    153   ConfigAvailability availability_;
    154   ProxyConfig config_;
    155   ObserverList<Observer, true> observers_;
    156 };
    157 
    158 // A test network delegate that exercises the OnResolveProxy callback.
    159 class TestResolveProxyNetworkDelegate : public NetworkDelegate {
    160  public:
    161   TestResolveProxyNetworkDelegate()
    162       : on_resolve_proxy_called_(false),
    163         add_proxy_(false),
    164         remove_proxy_(false),
    165         proxy_service_(NULL) {
    166   }
    167 
    168   virtual void OnResolveProxy(const GURL& url,
    169                               int load_flags,
    170                               const ProxyService& proxy_service,
    171                               ProxyInfo* result) OVERRIDE {
    172     on_resolve_proxy_called_ = true;
    173     proxy_service_ = &proxy_service;
    174     DCHECK(!add_proxy_ || !remove_proxy_);
    175     if (add_proxy_) {
    176       result->UseNamedProxy("delegate_proxy.com");
    177     } else if (remove_proxy_) {
    178       result->UseDirect();
    179     }
    180   }
    181 
    182   bool on_resolve_proxy_called() const {
    183     return on_resolve_proxy_called_;
    184   }
    185 
    186   void set_add_proxy(bool add_proxy) {
    187     add_proxy_ = add_proxy;
    188   }
    189 
    190   void set_remove_proxy(bool remove_proxy) {
    191     remove_proxy_ = remove_proxy;
    192   }
    193 
    194   const ProxyService* proxy_service() const {
    195     return proxy_service_;
    196   }
    197 
    198  private:
    199   bool on_resolve_proxy_called_;
    200   bool add_proxy_;
    201   bool remove_proxy_;
    202   const ProxyService* proxy_service_;
    203 };
    204 
    205 // A test network delegate that exercises the OnProxyFallback callback.
    206 class TestProxyFallbackNetworkDelegate : public NetworkDelegate {
    207  public:
    208   TestProxyFallbackNetworkDelegate()
    209       : on_proxy_fallback_called_(false),
    210         proxy_fallback_net_error_(OK) {
    211   }
    212 
    213   virtual void OnProxyFallback(const ProxyServer& proxy_server,
    214                                int net_error) OVERRIDE {
    215     proxy_server_ = proxy_server;
    216     proxy_fallback_net_error_ = net_error;
    217     on_proxy_fallback_called_ = true;
    218   }
    219 
    220   bool on_proxy_fallback_called() const {
    221     return on_proxy_fallback_called_;
    222   }
    223 
    224   const ProxyServer& proxy_server() const {
    225     return proxy_server_;
    226   }
    227 
    228   int proxy_fallback_net_error() const {
    229     return proxy_fallback_net_error_;
    230   }
    231 
    232  private:
    233   bool on_proxy_fallback_called_;
    234   ProxyServer proxy_server_;
    235   int proxy_fallback_net_error_;
    236 };
    237 
    238 }  // namespace
    239 
    240 TEST_F(ProxyServiceTest, Direct) {
    241   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    242   ProxyService service(new MockProxyConfigService(
    243           ProxyConfig::CreateDirect()), resolver, NULL);
    244 
    245   GURL url("http://www.google.com/");
    246 
    247   ProxyInfo info;
    248   TestCompletionCallback callback;
    249   CapturingBoundNetLog log;
    250   int rv = service.ResolveProxy(
    251       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    252       log.bound());
    253   EXPECT_EQ(OK, rv);
    254   EXPECT_TRUE(resolver->pending_requests().empty());
    255 
    256   EXPECT_TRUE(info.is_direct());
    257   EXPECT_TRUE(info.proxy_resolve_start_time().is_null());
    258   EXPECT_TRUE(info.proxy_resolve_end_time().is_null());
    259 
    260   // Check the NetLog was filled correctly.
    261   CapturingNetLog::CapturedEntryList entries;
    262   log.GetEntries(&entries);
    263 
    264   EXPECT_EQ(3u, entries.size());
    265   EXPECT_TRUE(LogContainsBeginEvent(
    266       entries, 0, NetLog::TYPE_PROXY_SERVICE));
    267   EXPECT_TRUE(LogContainsEvent(
    268       entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
    269       NetLog::PHASE_NONE));
    270   EXPECT_TRUE(LogContainsEndEvent(
    271       entries, 2, NetLog::TYPE_PROXY_SERVICE));
    272 }
    273 
    274 TEST_F(ProxyServiceTest, OnResolveProxyCallbackAddProxy) {
    275   ProxyConfig config;
    276   config.proxy_rules().ParseFromString("foopy1:8080");
    277   config.set_auto_detect(false);
    278   config.proxy_rules().bypass_rules.ParseFromString("*.org");
    279 
    280   ProxyService service(
    281       new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
    282 
    283   GURL url("http://www.google.com/");
    284   GURL bypass_url("http://internet.org");
    285 
    286   ProxyInfo info;
    287   TestCompletionCallback callback;
    288   CapturingBoundNetLog log;
    289 
    290   // First, warm up the ProxyService.
    291   int rv = service.ResolveProxy(
    292       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    293       log.bound());
    294   EXPECT_EQ(OK, rv);
    295 
    296   // Verify that network delegate is invoked.
    297   TestResolveProxyNetworkDelegate delegate;
    298   rv = service.ResolveProxy(
    299       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
    300       log.bound());
    301   EXPECT_TRUE(delegate.on_resolve_proxy_called());
    302   EXPECT_EQ(&service, delegate.proxy_service());
    303 
    304   // Verify that the NetworkDelegate's behavior is stateless across
    305   // invocations of ResolveProxy. Start by having the callback add a proxy
    306   // and checking that subsequent requests are not affected.
    307   delegate.set_add_proxy(true);
    308 
    309   // Callback should interpose:
    310   rv = service.ResolveProxy(
    311       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
    312       log.bound());
    313   EXPECT_FALSE(info.is_direct());
    314   EXPECT_EQ(info.proxy_server().host_port_pair().host(), "delegate_proxy.com");
    315   delegate.set_add_proxy(false);
    316 
    317   // Check non-bypassed URL:
    318   rv = service.ResolveProxy(
    319       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
    320       log.bound());
    321   EXPECT_FALSE(info.is_direct());
    322   EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
    323 
    324   // Check bypassed URL:
    325   rv = service.ResolveProxy(
    326        bypass_url, net::LOAD_NORMAL, &info, callback.callback(), NULL,
    327        &delegate, log.bound());
    328   EXPECT_TRUE(info.is_direct());
    329 }
    330 
    331 TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
    332   // Same as OnResolveProxyCallbackAddProxy, but verify that the
    333   // NetworkDelegate's behavior is stateless across invocations after it
    334   // *removes* a proxy.
    335   ProxyConfig config;
    336   config.proxy_rules().ParseFromString("foopy1:8080");
    337   config.set_auto_detect(false);
    338   config.proxy_rules().bypass_rules.ParseFromString("*.org");
    339 
    340   ProxyService service(
    341       new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
    342 
    343   GURL url("http://www.google.com/");
    344   GURL bypass_url("http://internet.org");
    345 
    346   ProxyInfo info;
    347   TestCompletionCallback callback;
    348   CapturingBoundNetLog log;
    349 
    350   // First, warm up the ProxyService.
    351   int rv = service.ResolveProxy(
    352       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    353       log.bound());
    354   EXPECT_EQ(OK, rv);
    355 
    356   TestResolveProxyNetworkDelegate delegate;
    357   delegate.set_remove_proxy(true);
    358 
    359   // Callback should interpose:
    360   rv = service.ResolveProxy(
    361       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
    362       log.bound());
    363   EXPECT_TRUE(info.is_direct());
    364   delegate.set_remove_proxy(false);
    365 
    366   // Check non-bypassed URL:
    367   rv = service.ResolveProxy(
    368       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
    369       log.bound());
    370   EXPECT_FALSE(info.is_direct());
    371   EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
    372 
    373   // Check bypassed URL:
    374   rv = service.ResolveProxy(
    375        bypass_url, net::LOAD_NORMAL, &info, callback.callback(), NULL,
    376        &delegate, log.bound());
    377   EXPECT_TRUE(info.is_direct());
    378 }
    379 
    380 TEST_F(ProxyServiceTest, PAC) {
    381   MockProxyConfigService* config_service =
    382       new MockProxyConfigService("http://foopy/proxy.pac");
    383 
    384   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    385 
    386   ProxyService service(config_service, resolver, NULL);
    387 
    388   GURL url("http://www.google.com/");
    389 
    390   ProxyInfo info;
    391   TestCompletionCallback callback;
    392   ProxyService::PacRequest* request;
    393   CapturingBoundNetLog log;
    394 
    395   int rv = service.ResolveProxy(
    396       url, net::LOAD_NORMAL, &info, callback.callback(), &request, NULL,
    397       log.bound());
    398   EXPECT_EQ(ERR_IO_PENDING, rv);
    399 
    400   EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request));
    401 
    402   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    403             resolver->pending_set_pac_script_request()->script_data()->url());
    404   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    405 
    406   ASSERT_EQ(1u, resolver->pending_requests().size());
    407   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    408 
    409   // Set the result in proxy resolver.
    410   resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
    411   resolver->pending_requests()[0]->CompleteNow(OK);
    412 
    413   EXPECT_EQ(OK, callback.WaitForResult());
    414   EXPECT_FALSE(info.is_direct());
    415   EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
    416   EXPECT_TRUE(info.did_use_pac_script());
    417 
    418   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    419   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    420   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    421 
    422   // Check the NetLog was filled correctly.
    423   CapturingNetLog::CapturedEntryList entries;
    424   log.GetEntries(&entries);
    425 
    426   EXPECT_EQ(5u, entries.size());
    427   EXPECT_TRUE(LogContainsBeginEvent(
    428       entries, 0, NetLog::TYPE_PROXY_SERVICE));
    429   EXPECT_TRUE(LogContainsBeginEvent(
    430       entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
    431   EXPECT_TRUE(LogContainsEndEvent(
    432       entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
    433   EXPECT_TRUE(LogContainsEndEvent(
    434       entries, 4, NetLog::TYPE_PROXY_SERVICE));
    435 }
    436 
    437 // Test that the proxy resolver does not see the URL's username/password
    438 // or its reference section.
    439 TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
    440   MockProxyConfigService* config_service =
    441       new MockProxyConfigService("http://foopy/proxy.pac");
    442 
    443   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    444 
    445   ProxyService service(config_service, resolver, NULL);
    446 
    447   GURL url("http://username:password@www.google.com/?ref#hash#hash");
    448 
    449   ProxyInfo info;
    450   TestCompletionCallback callback;
    451   int rv = service.ResolveProxy(
    452       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    453       BoundNetLog());
    454   EXPECT_EQ(ERR_IO_PENDING, rv);
    455 
    456   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    457             resolver->pending_set_pac_script_request()->script_data()->url());
    458   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    459 
    460   ASSERT_EQ(1u, resolver->pending_requests().size());
    461   // The URL should have been simplified, stripping the username/password/hash.
    462   EXPECT_EQ(GURL("http://www.google.com/?ref"),
    463                  resolver->pending_requests()[0]->url());
    464 
    465   // We end here without ever completing the request -- destruction of
    466   // ProxyService will cancel the outstanding request.
    467 }
    468 
    469 TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
    470   MockProxyConfigService* config_service =
    471       new MockProxyConfigService("http://foopy/proxy.pac");
    472   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    473 
    474   ProxyService service(config_service, resolver, NULL);
    475 
    476   GURL url("http://www.google.com/");
    477 
    478   ProxyInfo info;
    479   TestCompletionCallback callback1;
    480   int rv = service.ResolveProxy(
    481       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    482       BoundNetLog());
    483   EXPECT_EQ(ERR_IO_PENDING, rv);
    484 
    485   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    486             resolver->pending_set_pac_script_request()->script_data()->url());
    487   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    488 
    489   ASSERT_EQ(1u, resolver->pending_requests().size());
    490   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    491 
    492   // Set the result in proxy resolver.
    493   resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
    494   resolver->pending_requests()[0]->CompleteNow(OK);
    495 
    496   EXPECT_EQ(OK, callback1.WaitForResult());
    497   EXPECT_FALSE(info.is_direct());
    498   EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
    499   EXPECT_TRUE(info.did_use_pac_script());
    500 
    501   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    502   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    503   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    504 
    505   // Now, imagine that connecting to foopy:8080 fails: there is nothing
    506   // left to fallback to, since our proxy list was NOT terminated by
    507   // DIRECT.
    508   NetworkDelegate network_delegate;
    509   TestCompletionCallback callback2;
    510   ProxyServer expected_proxy_server = info.proxy_server();
    511   rv = service.ReconsiderProxyAfterError(
    512       url, net::LOAD_NORMAL, net::ERR_PROXY_CONNECTION_FAILED,
    513       &info, callback2.callback(), NULL, &network_delegate, BoundNetLog());
    514   // ReconsiderProxyAfterError returns error indicating nothing left.
    515   EXPECT_EQ(ERR_FAILED, rv);
    516   EXPECT_TRUE(info.is_empty());
    517 }
    518 
    519 // Test that if the execution of the PAC script fails (i.e. javascript runtime
    520 // error), and the PAC settings are non-mandatory, that we fall-back to direct.
    521 TEST_F(ProxyServiceTest, PAC_RuntimeError) {
    522   MockProxyConfigService* config_service =
    523       new MockProxyConfigService("http://foopy/proxy.pac");
    524   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    525 
    526   ProxyService service(config_service, resolver, NULL);
    527 
    528   GURL url("http://this-causes-js-error/");
    529 
    530   ProxyInfo info;
    531   TestCompletionCallback callback1;
    532   int rv = service.ResolveProxy(
    533       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    534       BoundNetLog());
    535   EXPECT_EQ(ERR_IO_PENDING, rv);
    536 
    537   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    538             resolver->pending_set_pac_script_request()->script_data()->url());
    539   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    540 
    541   ASSERT_EQ(1u, resolver->pending_requests().size());
    542   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    543 
    544   // Simulate a failure in the PAC executor.
    545   resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
    546 
    547   EXPECT_EQ(OK, callback1.WaitForResult());
    548 
    549   // Since the PAC script was non-mandatory, we should have fallen-back to
    550   // DIRECT.
    551   EXPECT_TRUE(info.is_direct());
    552   EXPECT_TRUE(info.did_use_pac_script());
    553   EXPECT_EQ(1, info.config_id());
    554 
    555   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    556   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    557   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    558 }
    559 
    560 // The proxy list could potentially contain the DIRECT fallback choice
    561 // in a location other than the very end of the list, and could even
    562 // specify it multiple times.
    563 //
    564 // This is not a typical usage, but we will obey it.
    565 // (If we wanted to disallow this type of input, the right place to
    566 // enforce it would be in parsing the PAC result string).
    567 //
    568 // This test will use the PAC result string:
    569 //
    570 //   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
    571 //
    572 // For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
    573 // then foobar:20, and then give up and error.
    574 //
    575 // The important check of this test is to make sure that DIRECT is not somehow
    576 // cached as being a bad proxy.
    577 TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
    578   MockProxyConfigService* config_service =
    579       new MockProxyConfigService("http://foopy/proxy.pac");
    580   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    581 
    582   ProxyService service(config_service, resolver, NULL);
    583 
    584   GURL url("http://www.google.com/");
    585 
    586   ProxyInfo info;
    587   TestCompletionCallback callback1;
    588   int rv = service.ResolveProxy(
    589       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    590       BoundNetLog());
    591   EXPECT_EQ(ERR_IO_PENDING, rv);
    592 
    593   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    594             resolver->pending_set_pac_script_request()->script_data()->url());
    595   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    596 
    597   ASSERT_EQ(1u, resolver->pending_requests().size());
    598   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    599 
    600   // Set the result in proxy resolver.
    601   resolver->pending_requests()[0]->results()->UsePacString(
    602       "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
    603   resolver->pending_requests()[0]->CompleteNow(OK);
    604 
    605   EXPECT_EQ(OK, callback1.WaitForResult());
    606   EXPECT_TRUE(info.is_direct());
    607 
    608   // Fallback 1.
    609   TestCompletionCallback callback2;
    610   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    611                                          net::ERR_PROXY_CONNECTION_FAILED,
    612                                          &info, callback2.callback(), NULL,
    613                                          NULL, BoundNetLog());
    614   EXPECT_EQ(OK, rv);
    615   EXPECT_FALSE(info.is_direct());
    616   EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
    617 
    618   // Fallback 2.
    619   NetworkDelegate network_delegate;
    620   ProxyServer expected_proxy_server3 = info.proxy_server();
    621   TestCompletionCallback callback3;
    622   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    623                                          net::ERR_PROXY_CONNECTION_FAILED,
    624                                          &info, callback3.callback(), NULL,
    625                                          &network_delegate, BoundNetLog());
    626   EXPECT_EQ(OK, rv);
    627   EXPECT_TRUE(info.is_direct());
    628 
    629   // Fallback 3.
    630   ProxyServer expected_proxy_server4 = info.proxy_server();
    631   TestCompletionCallback callback4;
    632   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    633                                          net::ERR_PROXY_CONNECTION_FAILED,
    634                                          &info, callback4.callback(), NULL,
    635                                          &network_delegate, BoundNetLog());
    636   EXPECT_EQ(OK, rv);
    637   EXPECT_FALSE(info.is_direct());
    638   EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
    639 
    640   // Fallback 4 -- Nothing to fall back to!
    641   ProxyServer expected_proxy_server5 = info.proxy_server();
    642   TestCompletionCallback callback5;
    643   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    644                                          net::ERR_PROXY_CONNECTION_FAILED,
    645                                          &info, callback5.callback(), NULL,
    646                                          &network_delegate, BoundNetLog());
    647   EXPECT_EQ(ERR_FAILED, rv);
    648   EXPECT_TRUE(info.is_empty());
    649 }
    650 
    651 TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
    652   // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
    653   // to ProxyInfo after the proxy is resolved via a PAC script.
    654   ProxyConfig config =
    655       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
    656   config.set_source(PROXY_CONFIG_SOURCE_TEST);
    657 
    658   MockProxyConfigService* config_service = new MockProxyConfigService(config);
    659   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    660   ProxyService service(config_service, resolver, NULL);
    661 
    662   // Resolve something.
    663   GURL url("http://www.google.com/");
    664   ProxyInfo info;
    665   TestCompletionCallback callback;
    666   int rv = service.ResolveProxy(
    667       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    668       BoundNetLog());
    669   ASSERT_EQ(ERR_IO_PENDING, rv);
    670   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    671   ASSERT_EQ(1u, resolver->pending_requests().size());
    672 
    673   // Set the result in proxy resolver.
    674   resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
    675   resolver->pending_requests()[0]->CompleteNow(OK);
    676 
    677   EXPECT_EQ(OK, callback.WaitForResult());
    678   EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
    679   EXPECT_TRUE(info.did_use_pac_script());
    680 
    681   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    682   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    683   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    684 }
    685 
    686 TEST_F(ProxyServiceTest, ProxyResolverFails) {
    687   // Test what happens when the ProxyResolver fails. The download and setting
    688   // of the PAC script have already succeeded, so this corresponds with a
    689   // javascript runtime error while calling FindProxyForURL().
    690 
    691   MockProxyConfigService* config_service =
    692       new MockProxyConfigService("http://foopy/proxy.pac");
    693 
    694   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    695 
    696   ProxyService service(config_service, resolver, NULL);
    697 
    698   // Start first resolve request.
    699   GURL url("http://www.google.com/");
    700   ProxyInfo info;
    701   TestCompletionCallback callback1;
    702   int rv = service.ResolveProxy(
    703       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    704       BoundNetLog());
    705   EXPECT_EQ(ERR_IO_PENDING, rv);
    706 
    707   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    708             resolver->pending_set_pac_script_request()->script_data()->url());
    709   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    710 
    711   ASSERT_EQ(1u, resolver->pending_requests().size());
    712   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    713 
    714   // Fail the first resolve request in MockAsyncProxyResolver.
    715   resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
    716 
    717   // Although the proxy resolver failed the request, ProxyService implicitly
    718   // falls-back to DIRECT.
    719   EXPECT_EQ(OK, callback1.WaitForResult());
    720   EXPECT_TRUE(info.is_direct());
    721 
    722   // Failed PAC executions still have proxy resolution times.
    723   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    724   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    725   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    726 
    727   // The second resolve request will try to run through the proxy resolver,
    728   // regardless of whether the first request failed in it.
    729   TestCompletionCallback callback2;
    730   rv = service.ResolveProxy(
    731       url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
    732       BoundNetLog());
    733   EXPECT_EQ(ERR_IO_PENDING, rv);
    734 
    735   ASSERT_EQ(1u, resolver->pending_requests().size());
    736   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    737 
    738   // This time we will have the resolver succeed (perhaps the PAC script has
    739   // a dependency on the current time).
    740   resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
    741   resolver->pending_requests()[0]->CompleteNow(OK);
    742 
    743   EXPECT_EQ(OK, callback2.WaitForResult());
    744   EXPECT_FALSE(info.is_direct());
    745   EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
    746 }
    747 
    748 TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
    749   // Test what happens when the ProxyScriptResolver fails to download a
    750   // mandatory PAC script.
    751 
    752   ProxyConfig config(
    753       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
    754   config.set_pac_mandatory(true);
    755 
    756   MockProxyConfigService* config_service = new MockProxyConfigService(config);
    757 
    758   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    759 
    760   ProxyService service(config_service, resolver, NULL);
    761 
    762   // Start first resolve request.
    763   GURL url("http://www.google.com/");
    764   ProxyInfo info;
    765   TestCompletionCallback callback1;
    766   int rv = service.ResolveProxy(
    767       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    768       BoundNetLog());
    769   EXPECT_EQ(ERR_IO_PENDING, rv);
    770 
    771   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    772             resolver->pending_set_pac_script_request()->script_data()->url());
    773   resolver->pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
    774 
    775   ASSERT_EQ(0u, resolver->pending_requests().size());
    776 
    777   // As the proxy resolver failed the request and is configured for a mandatory
    778   // PAC script, ProxyService must not implicitly fall-back to DIRECT.
    779   EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
    780             callback1.WaitForResult());
    781   EXPECT_FALSE(info.is_direct());
    782 
    783   // As the proxy resolver failed the request and is configured for a mandatory
    784   // PAC script, ProxyService must not implicitly fall-back to DIRECT.
    785   TestCompletionCallback callback2;
    786   rv = service.ResolveProxy(
    787       url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
    788       BoundNetLog());
    789   EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
    790   EXPECT_FALSE(info.is_direct());
    791 }
    792 
    793 TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
    794   // Test what happens when the ProxyResolver fails that is configured to use a
    795   // mandatory PAC script. The download of the PAC script has already
    796   // succeeded but the PAC script contains no valid javascript.
    797 
    798   ProxyConfig config(
    799       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
    800   config.set_pac_mandatory(true);
    801 
    802   MockProxyConfigService* config_service = new MockProxyConfigService(config);
    803 
    804   MockAsyncProxyResolverExpectsBytes* resolver =
    805       new MockAsyncProxyResolverExpectsBytes;
    806 
    807   ProxyService service(config_service, resolver, NULL);
    808 
    809   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
    810   DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
    811   service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);
    812 
    813   // Start resolve request.
    814   GURL url("http://www.google.com/");
    815   ProxyInfo info;
    816   TestCompletionCallback callback;
    817   int rv = service.ResolveProxy(
    818       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
    819       BoundNetLog());
    820   EXPECT_EQ(ERR_IO_PENDING, rv);
    821 
    822   // Check that nothing has been sent to the proxy resolver yet.
    823   ASSERT_EQ(0u, resolver->pending_requests().size());
    824 
    825   // Downloading the PAC script succeeds.
    826   EXPECT_TRUE(fetcher->has_pending_request());
    827   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
    828   fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
    829 
    830   EXPECT_FALSE(fetcher->has_pending_request());
    831   ASSERT_EQ(0u, resolver->pending_requests().size());
    832 
    833   // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
    834   // mandatory for this configuration, the ProxyService must not implicitly
    835   // fall-back to DIRECT.
    836   EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
    837             callback.WaitForResult());
    838   EXPECT_FALSE(info.is_direct());
    839 }
    840 
    841 TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
    842   // Test what happens when the ProxyResolver fails that is configured to use a
    843   // mandatory PAC script. The download and setting of the PAC script have
    844   // already succeeded, so this corresponds with a javascript runtime error
    845   // while calling FindProxyForURL().
    846 
    847   ProxyConfig config(
    848       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
    849   config.set_pac_mandatory(true);
    850 
    851   MockProxyConfigService* config_service = new MockProxyConfigService(config);
    852 
    853   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    854 
    855   ProxyService service(config_service, resolver, NULL);
    856 
    857   // Start first resolve request.
    858   GURL url("http://www.google.com/");
    859   ProxyInfo info;
    860   TestCompletionCallback callback1;
    861   int rv = service.ResolveProxy(
    862       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    863       BoundNetLog());
    864   EXPECT_EQ(ERR_IO_PENDING, rv);
    865 
    866   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    867             resolver->pending_set_pac_script_request()->script_data()->url());
    868   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    869 
    870   ASSERT_EQ(1u, resolver->pending_requests().size());
    871   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    872 
    873   // Fail the first resolve request in MockAsyncProxyResolver.
    874   resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
    875 
    876   // As the proxy resolver failed the request and is configured for a mandatory
    877   // PAC script, ProxyService must not implicitly fall-back to DIRECT.
    878   EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
    879             callback1.WaitForResult());
    880   EXPECT_FALSE(info.is_direct());
    881 
    882   // The second resolve request will try to run through the proxy resolver,
    883   // regardless of whether the first request failed in it.
    884   TestCompletionCallback callback2;
    885   rv = service.ResolveProxy(
    886       url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
    887       BoundNetLog());
    888   EXPECT_EQ(ERR_IO_PENDING, rv);
    889 
    890   ASSERT_EQ(1u, resolver->pending_requests().size());
    891   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    892 
    893   // This time we will have the resolver succeed (perhaps the PAC script has
    894   // a dependency on the current time).
    895   resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
    896   resolver->pending_requests()[0]->CompleteNow(OK);
    897 
    898   EXPECT_EQ(OK, callback2.WaitForResult());
    899   EXPECT_FALSE(info.is_direct());
    900   EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
    901 }
    902 
    903 TEST_F(ProxyServiceTest, ProxyFallback) {
    904   // Test what happens when we specify multiple proxy servers and some of them
    905   // are bad.
    906 
    907   MockProxyConfigService* config_service =
    908       new MockProxyConfigService("http://foopy/proxy.pac");
    909 
    910   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
    911 
    912   ProxyService service(config_service, resolver, NULL);
    913 
    914   GURL url("http://www.google.com/");
    915 
    916   // Get the proxy information.
    917   ProxyInfo info;
    918   TestCompletionCallback callback1;
    919   int rv = service.ResolveProxy(
    920       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
    921       BoundNetLog());
    922   EXPECT_EQ(ERR_IO_PENDING, rv);
    923 
    924   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
    925             resolver->pending_set_pac_script_request()->script_data()->url());
    926   resolver->pending_set_pac_script_request()->CompleteNow(OK);
    927 
    928   ASSERT_EQ(1u, resolver->pending_requests().size());
    929   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    930 
    931   // Set the result in proxy resolver.
    932   resolver->pending_requests()[0]->results()->UseNamedProxy(
    933       "foopy1:8080;foopy2:9090");
    934   resolver->pending_requests()[0]->CompleteNow(OK);
    935 
    936   // The first item is valid.
    937   EXPECT_EQ(OK, callback1.WaitForResult());
    938   EXPECT_FALSE(info.is_direct());
    939   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
    940 
    941   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    942   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    943   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    944   base::TimeTicks proxy_resolve_start_time = info.proxy_resolve_start_time();
    945   base::TimeTicks proxy_resolve_end_time = info.proxy_resolve_end_time();
    946 
    947   // Fake an error on the proxy.
    948   TestCompletionCallback callback2;
    949   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    950                                          net::ERR_PROXY_CONNECTION_FAILED,
    951                                          &info, callback2.callback(), NULL,
    952                                          NULL, BoundNetLog());
    953   EXPECT_EQ(OK, rv);
    954 
    955   // Proxy times should not have been modified by fallback.
    956   EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
    957   EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
    958 
    959   // The second proxy should be specified.
    960   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
    961   // Report back that the second proxy worked.  This will globally mark the
    962   // first proxy as bad.
    963   TestProxyFallbackNetworkDelegate test_delegate;
    964   service.ReportSuccess(info, &test_delegate);
    965   EXPECT_EQ("foopy1:8080", test_delegate.proxy_server().ToURI());
    966   EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED,
    967             test_delegate.proxy_fallback_net_error());
    968 
    969   TestCompletionCallback callback3;
    970   rv = service.ResolveProxy(
    971       url, net::LOAD_NORMAL, &info, callback3.callback(), NULL, NULL,
    972       BoundNetLog());
    973   EXPECT_EQ(ERR_IO_PENDING, rv);
    974 
    975   ASSERT_EQ(1u, resolver->pending_requests().size());
    976   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
    977 
    978   // Set the result in proxy resolver -- the second result is already known
    979   // to be bad, so we will not try to use it initially.
    980   resolver->pending_requests()[0]->results()->UseNamedProxy(
    981       "foopy3:7070;foopy1:8080;foopy2:9090");
    982   resolver->pending_requests()[0]->CompleteNow(OK);
    983 
    984   EXPECT_EQ(OK, callback3.WaitForResult());
    985   EXPECT_FALSE(info.is_direct());
    986   EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
    987 
    988   // Proxy times should have been updated, so get them again.
    989   EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
    990   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
    991   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
    992   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
    993   proxy_resolve_start_time = info.proxy_resolve_start_time();
    994   proxy_resolve_end_time = info.proxy_resolve_end_time();
    995 
    996   // We fake another error. It should now try the third one.
    997   TestCompletionCallback callback4;
    998   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
    999                                          net::ERR_PROXY_CONNECTION_FAILED,
   1000                                          &info, callback4.callback(), NULL,
   1001                                          NULL, BoundNetLog());
   1002   EXPECT_EQ(OK, rv);
   1003   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
   1004 
   1005   // We fake another error. At this point we have tried all of the
   1006   // proxy servers we thought were valid; next we try the proxy server
   1007   // that was in our bad proxies map (foopy1:8080).
   1008   TestCompletionCallback callback5;
   1009   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1010                                          net::ERR_PROXY_CONNECTION_FAILED,
   1011                                          &info, callback5.callback(), NULL,
   1012                                          NULL, BoundNetLog());
   1013   EXPECT_EQ(OK, rv);
   1014   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1015 
   1016   // Fake another error, the last proxy is gone, the list should now be empty,
   1017   // so there is nothing left to try.
   1018   TestCompletionCallback callback6;
   1019   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1020                                          net::ERR_PROXY_CONNECTION_FAILED,
   1021                                          &info, callback6.callback(), NULL,
   1022                                          NULL, BoundNetLog());
   1023   EXPECT_EQ(ERR_FAILED, rv);
   1024   EXPECT_FALSE(info.is_direct());
   1025   EXPECT_TRUE(info.is_empty());
   1026 
   1027   // Proxy times should not have been modified by fallback.
   1028   EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
   1029   EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
   1030 
   1031   // Look up proxies again
   1032   TestCompletionCallback callback7;
   1033   rv = service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback7.callback(),
   1034                             NULL, NULL, BoundNetLog());
   1035   EXPECT_EQ(ERR_IO_PENDING, rv);
   1036 
   1037   ASSERT_EQ(1u, resolver->pending_requests().size());
   1038   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1039 
   1040   // This time, the first 3 results have been found to be bad, but only the
   1041   // first proxy has been confirmed ...
   1042   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1043       "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
   1044   resolver->pending_requests()[0]->CompleteNow(OK);
   1045 
   1046   // ... therefore, we should see the second proxy first.
   1047   EXPECT_EQ(OK, callback7.WaitForResult());
   1048   EXPECT_FALSE(info.is_direct());
   1049   EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
   1050 
   1051   EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
   1052   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
   1053   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
   1054   // TODO(nsylvain): Test that the proxy can be retried after the delay.
   1055 }
   1056 
   1057 // This test is similar to ProxyFallback, but this time we have an explicit
   1058 // fallback choice to DIRECT.
   1059 TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
   1060   MockProxyConfigService* config_service =
   1061       new MockProxyConfigService("http://foopy/proxy.pac");
   1062 
   1063   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   1064 
   1065   ProxyService service(config_service, resolver, NULL);
   1066 
   1067   GURL url("http://www.google.com/");
   1068 
   1069   // Get the proxy information.
   1070   ProxyInfo info;
   1071   TestCompletionCallback callback1;
   1072   int rv = service.ResolveProxy(
   1073       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
   1074       BoundNetLog());
   1075   EXPECT_EQ(ERR_IO_PENDING, rv);
   1076 
   1077   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   1078             resolver->pending_set_pac_script_request()->script_data()->url());
   1079   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1080 
   1081   ASSERT_EQ(1u, resolver->pending_requests().size());
   1082   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1083 
   1084   // Set the result in proxy resolver.
   1085   resolver->pending_requests()[0]->results()->UsePacString(
   1086       "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
   1087   resolver->pending_requests()[0]->CompleteNow(OK);
   1088 
   1089   // Get the first result.
   1090   EXPECT_EQ(OK, callback1.WaitForResult());
   1091   EXPECT_FALSE(info.is_direct());
   1092   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1093 
   1094   // Fake an error on the proxy.
   1095   TestCompletionCallback callback2;
   1096   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1097                                          net::ERR_PROXY_CONNECTION_FAILED,
   1098                                          &info, callback2.callback(), NULL,
   1099                                          NULL, BoundNetLog());
   1100   EXPECT_EQ(OK, rv);
   1101 
   1102   // Now we get back the second proxy.
   1103   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
   1104 
   1105   // Fake an error on this proxy as well.
   1106   TestCompletionCallback callback3;
   1107   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1108                                          net::ERR_PROXY_CONNECTION_FAILED,
   1109                                          &info, callback3.callback(), NULL,
   1110                                          NULL, BoundNetLog());
   1111   EXPECT_EQ(OK, rv);
   1112 
   1113   // Finally, we get back DIRECT.
   1114   EXPECT_TRUE(info.is_direct());
   1115 
   1116   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
   1117   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
   1118   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
   1119 
   1120   // Now we tell the proxy service that even DIRECT failed.
   1121   TestCompletionCallback callback4;
   1122   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1123                                          net::ERR_PROXY_CONNECTION_FAILED,
   1124                                          &info, callback4.callback(), NULL,
   1125                                          NULL, BoundNetLog());
   1126   // There was nothing left to try after DIRECT, so we are out of
   1127   // choices.
   1128   EXPECT_EQ(ERR_FAILED, rv);
   1129 }
   1130 
   1131 TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
   1132   // Test proxy failover when new settings are available.
   1133 
   1134   MockProxyConfigService* config_service =
   1135       new MockProxyConfigService("http://foopy/proxy.pac");
   1136 
   1137   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   1138 
   1139   ProxyService service(config_service, resolver, NULL);
   1140 
   1141   GURL url("http://www.google.com/");
   1142 
   1143   // Get the proxy information.
   1144   ProxyInfo info;
   1145   TestCompletionCallback callback1;
   1146   int rv = service.ResolveProxy(
   1147       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
   1148       BoundNetLog());
   1149   EXPECT_EQ(ERR_IO_PENDING, rv);
   1150 
   1151   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   1152             resolver->pending_set_pac_script_request()->script_data()->url());
   1153   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1154 
   1155   ASSERT_EQ(1u, resolver->pending_requests().size());
   1156   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1157 
   1158   // Set the result in proxy resolver.
   1159   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1160       "foopy1:8080;foopy2:9090");
   1161   resolver->pending_requests()[0]->CompleteNow(OK);
   1162 
   1163   // The first item is valid.
   1164   EXPECT_EQ(OK, callback1.WaitForResult());
   1165   EXPECT_FALSE(info.is_direct());
   1166   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1167 
   1168   // Fake an error on the proxy, and also a new configuration on the proxy.
   1169   config_service->SetConfig(
   1170       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
   1171 
   1172   TestCompletionCallback callback2;
   1173   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1174                                          net::ERR_PROXY_CONNECTION_FAILED,
   1175                                          &info, callback2.callback(), NULL,
   1176                                          NULL, BoundNetLog());
   1177   EXPECT_EQ(ERR_IO_PENDING, rv);
   1178 
   1179   EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
   1180             resolver->pending_set_pac_script_request()->script_data()->url());
   1181   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1182 
   1183   ASSERT_EQ(1u, resolver->pending_requests().size());
   1184   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1185 
   1186   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1187       "foopy1:8080;foopy2:9090");
   1188   resolver->pending_requests()[0]->CompleteNow(OK);
   1189 
   1190   // The first proxy is still there since the configuration changed.
   1191   EXPECT_EQ(OK, callback2.WaitForResult());
   1192   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1193 
   1194   // We fake another error. It should now ignore the first one.
   1195   TestCompletionCallback callback3;
   1196   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1197                                          net::ERR_PROXY_CONNECTION_FAILED,
   1198                                          &info, callback3.callback(), NULL,
   1199                                          NULL, BoundNetLog());
   1200   EXPECT_EQ(OK, rv);
   1201   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
   1202 
   1203   // We simulate a new configuration.
   1204   config_service->SetConfig(
   1205       ProxyConfig::CreateFromCustomPacURL(
   1206           GURL("http://foopy-new2/proxy.pac")));
   1207 
   1208   // We fake another error. It should go back to the first proxy.
   1209   TestCompletionCallback callback4;
   1210   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1211                                          net::ERR_PROXY_CONNECTION_FAILED,
   1212                                          &info, callback4.callback(), NULL,
   1213                                          NULL, BoundNetLog());
   1214   EXPECT_EQ(ERR_IO_PENDING, rv);
   1215 
   1216   EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
   1217             resolver->pending_set_pac_script_request()->script_data()->url());
   1218   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1219 
   1220   ASSERT_EQ(1u, resolver->pending_requests().size());
   1221   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1222 
   1223   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1224       "foopy1:8080;foopy2:9090");
   1225   resolver->pending_requests()[0]->CompleteNow(OK);
   1226 
   1227   EXPECT_EQ(OK, callback4.WaitForResult());
   1228   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1229 
   1230   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
   1231   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
   1232   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
   1233 }
   1234 
   1235 TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
   1236   // Test proxy failover when the configuration is bad.
   1237 
   1238   MockProxyConfigService* config_service =
   1239       new MockProxyConfigService("http://foopy/proxy.pac");
   1240 
   1241   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   1242 
   1243   ProxyService service(config_service, resolver, NULL);
   1244 
   1245   GURL url("http://www.google.com/");
   1246 
   1247   // Get the proxy information.
   1248   ProxyInfo info;
   1249   TestCompletionCallback callback1;
   1250   int rv = service.ResolveProxy(
   1251       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
   1252       BoundNetLog());
   1253   EXPECT_EQ(ERR_IO_PENDING, rv);
   1254 
   1255   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   1256             resolver->pending_set_pac_script_request()->script_data()->url());
   1257   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1258   ASSERT_EQ(1u, resolver->pending_requests().size());
   1259   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1260 
   1261   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1262       "foopy1:8080;foopy2:9090");
   1263   resolver->pending_requests()[0]->CompleteNow(OK);
   1264 
   1265   // The first item is valid.
   1266   EXPECT_EQ(OK, callback1.WaitForResult());
   1267   EXPECT_FALSE(info.is_direct());
   1268   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1269 
   1270   // Fake a proxy error.
   1271   TestCompletionCallback callback2;
   1272   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1273                                          net::ERR_PROXY_CONNECTION_FAILED,
   1274                                          &info, callback2.callback(), NULL,
   1275                                          NULL, BoundNetLog());
   1276   EXPECT_EQ(OK, rv);
   1277 
   1278   // The first proxy is ignored, and the second one is selected.
   1279   EXPECT_FALSE(info.is_direct());
   1280   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
   1281 
   1282   // Fake a PAC failure.
   1283   ProxyInfo info2;
   1284   TestCompletionCallback callback3;
   1285   rv = service.ResolveProxy(
   1286       url, net::LOAD_NORMAL, &info2, callback3.callback(), NULL, NULL,
   1287       BoundNetLog());
   1288   EXPECT_EQ(ERR_IO_PENDING, rv);
   1289 
   1290   ASSERT_EQ(1u, resolver->pending_requests().size());
   1291   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1292 
   1293   // This simulates a javascript runtime error in the PAC script.
   1294   resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
   1295 
   1296   // Although the resolver failed, the ProxyService will implicitly fall-back
   1297   // to a DIRECT connection.
   1298   EXPECT_EQ(OK, callback3.WaitForResult());
   1299   EXPECT_TRUE(info2.is_direct());
   1300   EXPECT_FALSE(info2.is_empty());
   1301 
   1302   // The PAC script will work properly next time and successfully return a
   1303   // proxy list. Since we have not marked the configuration as bad, it should
   1304   // "just work" the next time we call it.
   1305   ProxyInfo info3;
   1306   TestCompletionCallback callback4;
   1307   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1308                                          net::ERR_PROXY_CONNECTION_FAILED,
   1309                                          &info3, callback4.callback(),
   1310                                          NULL, NULL, BoundNetLog());
   1311   EXPECT_EQ(ERR_IO_PENDING, rv);
   1312 
   1313   ASSERT_EQ(1u, resolver->pending_requests().size());
   1314   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1315 
   1316   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1317       "foopy1:8080;foopy2:9090");
   1318   resolver->pending_requests()[0]->CompleteNow(OK);
   1319 
   1320   // The first proxy is not there since the it was added to the bad proxies
   1321   // list by the earlier ReconsiderProxyAfterError().
   1322   EXPECT_EQ(OK, callback4.WaitForResult());
   1323   EXPECT_FALSE(info3.is_direct());
   1324   EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
   1325 
   1326   EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
   1327   EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
   1328   EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
   1329 }
   1330 
   1331 TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
   1332   // Test proxy failover when the configuration is bad.
   1333 
   1334   ProxyConfig config(
   1335       ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
   1336 
   1337   config.set_pac_mandatory(true);
   1338   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   1339 
   1340   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   1341 
   1342   ProxyService service(config_service, resolver, NULL);
   1343 
   1344   GURL url("http://www.google.com/");
   1345 
   1346   // Get the proxy information.
   1347   ProxyInfo info;
   1348   TestCompletionCallback callback1;
   1349   int rv = service.ResolveProxy(
   1350       url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
   1351       BoundNetLog());
   1352   EXPECT_EQ(ERR_IO_PENDING, rv);
   1353 
   1354   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   1355             resolver->pending_set_pac_script_request()->script_data()->url());
   1356   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1357   ASSERT_EQ(1u, resolver->pending_requests().size());
   1358   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1359 
   1360   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1361       "foopy1:8080;foopy2:9090");
   1362   resolver->pending_requests()[0]->CompleteNow(OK);
   1363 
   1364   // The first item is valid.
   1365   EXPECT_EQ(OK, callback1.WaitForResult());
   1366   EXPECT_FALSE(info.is_direct());
   1367   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1368 
   1369   // Fake a proxy error.
   1370   TestCompletionCallback callback2;
   1371   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1372                                          net::ERR_PROXY_CONNECTION_FAILED,
   1373                                          &info, callback2.callback(), NULL,
   1374                                          NULL, BoundNetLog());
   1375   EXPECT_EQ(OK, rv);
   1376 
   1377   // The first proxy is ignored, and the second one is selected.
   1378   EXPECT_FALSE(info.is_direct());
   1379   EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
   1380 
   1381   // Fake a PAC failure.
   1382   ProxyInfo info2;
   1383   TestCompletionCallback callback3;
   1384   rv = service.ResolveProxy(
   1385       url, net::LOAD_NORMAL, &info2, callback3.callback(), NULL, NULL,
   1386       BoundNetLog());
   1387   EXPECT_EQ(ERR_IO_PENDING, rv);
   1388 
   1389   ASSERT_EQ(1u, resolver->pending_requests().size());
   1390   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1391 
   1392   // This simulates a javascript runtime error in the PAC script.
   1393   resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
   1394 
   1395   // Although the resolver failed, the ProxyService will NOT fall-back
   1396   // to a DIRECT connection as it is configured as mandatory.
   1397   EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
   1398             callback3.WaitForResult());
   1399   EXPECT_FALSE(info2.is_direct());
   1400   EXPECT_TRUE(info2.is_empty());
   1401 
   1402   // The PAC script will work properly next time and successfully return a
   1403   // proxy list. Since we have not marked the configuration as bad, it should
   1404   // "just work" the next time we call it.
   1405   ProxyInfo info3;
   1406   TestCompletionCallback callback4;
   1407   rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
   1408                                          net::ERR_PROXY_CONNECTION_FAILED,
   1409                                          &info3, callback4.callback(),
   1410                                          NULL, NULL, BoundNetLog());
   1411   EXPECT_EQ(ERR_IO_PENDING, rv);
   1412 
   1413   ASSERT_EQ(1u, resolver->pending_requests().size());
   1414   EXPECT_EQ(url, resolver->pending_requests()[0]->url());
   1415 
   1416   resolver->pending_requests()[0]->results()->UseNamedProxy(
   1417       "foopy1:8080;foopy2:9090");
   1418   resolver->pending_requests()[0]->CompleteNow(OK);
   1419 
   1420   // The first proxy is not there since the it was added to the bad proxies
   1421   // list by the earlier ReconsiderProxyAfterError().
   1422   EXPECT_EQ(OK, callback4.WaitForResult());
   1423   EXPECT_FALSE(info3.is_direct());
   1424   EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
   1425 }
   1426 
   1427 TEST_F(ProxyServiceTest, ProxyBypassList) {
   1428   // Test that the proxy bypass rules are consulted.
   1429 
   1430   TestCompletionCallback callback[2];
   1431   ProxyInfo info[2];
   1432   ProxyConfig config;
   1433   config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
   1434   config.set_auto_detect(false);
   1435   config.proxy_rules().bypass_rules.ParseFromString("*.org");
   1436 
   1437   ProxyService service(
   1438       new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1439 
   1440   int rv;
   1441   GURL url1("http://www.webkit.org");
   1442   GURL url2("http://www.webkit.com");
   1443 
   1444   // Request for a .org domain should bypass proxy.
   1445   rv = service.ResolveProxy(
   1446       url1, net::LOAD_NORMAL, &info[0], callback[0].callback(), NULL, NULL,
   1447       BoundNetLog());
   1448   EXPECT_EQ(OK, rv);
   1449   EXPECT_TRUE(info[0].is_direct());
   1450 
   1451   // Request for a .com domain hits the proxy.
   1452   rv = service.ResolveProxy(
   1453       url2, net::LOAD_NORMAL, &info[1], callback[1].callback(), NULL, NULL,
   1454       BoundNetLog());
   1455   EXPECT_EQ(OK, rv);
   1456   EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
   1457 }
   1458 
   1459 
   1460 TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
   1461   ProxyConfig config;
   1462   config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
   1463   config.set_auto_detect(false);
   1464   {
   1465     ProxyService service(
   1466         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1467     GURL test_url("http://www.msn.com");
   1468     ProxyInfo info;
   1469     TestCompletionCallback callback;
   1470     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1471                                   callback.callback(), NULL, NULL,
   1472                                   BoundNetLog());
   1473     EXPECT_EQ(OK, rv);
   1474     EXPECT_FALSE(info.is_direct());
   1475     EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1476   }
   1477   {
   1478     ProxyService service(
   1479         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1480     GURL test_url("ftp://ftp.google.com");
   1481     ProxyInfo info;
   1482     TestCompletionCallback callback;
   1483     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1484                                   callback.callback(), NULL,
   1485                                   NULL, BoundNetLog());
   1486     EXPECT_EQ(OK, rv);
   1487     EXPECT_TRUE(info.is_direct());
   1488     EXPECT_EQ("direct://", info.proxy_server().ToURI());
   1489   }
   1490   {
   1491     ProxyService service(
   1492         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1493     GURL test_url("https://webbranch.techcu.com");
   1494     ProxyInfo info;
   1495     TestCompletionCallback callback;
   1496     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1497                                   callback.callback(), NULL,
   1498                                   NULL, BoundNetLog());
   1499     EXPECT_EQ(OK, rv);
   1500     EXPECT_FALSE(info.is_direct());
   1501     EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
   1502   }
   1503   {
   1504     config.proxy_rules().ParseFromString("foopy1:8080");
   1505     ProxyService service(
   1506         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1507     GURL test_url("http://www.microsoft.com");
   1508     ProxyInfo info;
   1509     TestCompletionCallback callback;
   1510     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1511                                   callback.callback(), NULL,
   1512                                   NULL, BoundNetLog());
   1513     EXPECT_EQ(OK, rv);
   1514     EXPECT_FALSE(info.is_direct());
   1515     EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1516   }
   1517 }
   1518 
   1519 TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
   1520   // Test that the proxy config source is set correctly when resolving proxies
   1521   // using manual proxy rules. Namely, the config source should only be set if
   1522   // any of the rules were applied.
   1523   {
   1524     ProxyConfig config;
   1525     config.set_source(PROXY_CONFIG_SOURCE_TEST);
   1526     config.proxy_rules().ParseFromString("https=foopy2:8080");
   1527     ProxyService service(
   1528         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1529     GURL test_url("http://www.google.com");
   1530     ProxyInfo info;
   1531     TestCompletionCallback callback;
   1532     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1533                                   callback.callback(), NULL,
   1534                                   NULL, BoundNetLog());
   1535     ASSERT_EQ(OK, rv);
   1536     // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
   1537     EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
   1538   }
   1539   {
   1540     ProxyConfig config;
   1541     config.set_source(PROXY_CONFIG_SOURCE_TEST);
   1542     config.proxy_rules().ParseFromString("https=foopy2:8080");
   1543     ProxyService service(
   1544         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1545     GURL test_url("https://www.google.com");
   1546     ProxyInfo info;
   1547     TestCompletionCallback callback;
   1548     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1549                                   callback.callback(), NULL,
   1550                                   NULL, BoundNetLog());
   1551     ASSERT_EQ(OK, rv);
   1552     // Used the HTTPS proxy. So source should be TEST.
   1553     EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
   1554   }
   1555   {
   1556     ProxyConfig config;
   1557     config.set_source(PROXY_CONFIG_SOURCE_TEST);
   1558     ProxyService service(
   1559         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1560     GURL test_url("http://www.google.com");
   1561     ProxyInfo info;
   1562     TestCompletionCallback callback;
   1563     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1564                                   callback.callback(), NULL,
   1565                                   NULL, BoundNetLog());
   1566     ASSERT_EQ(OK, rv);
   1567     // ProxyConfig is empty. Source should still be TEST.
   1568     EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
   1569   }
   1570 }
   1571 
   1572 // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
   1573 // fall back to the SOCKS proxy.
   1574 TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
   1575   ProxyConfig config;
   1576   config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
   1577   config.set_auto_detect(false);
   1578   EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
   1579             config.proxy_rules().type);
   1580 
   1581   {
   1582     ProxyService service(
   1583         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1584     GURL test_url("http://www.msn.com");
   1585     ProxyInfo info;
   1586     TestCompletionCallback callback;
   1587     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1588                                   callback.callback(), NULL,
   1589                                   NULL, BoundNetLog());
   1590     EXPECT_EQ(OK, rv);
   1591     EXPECT_FALSE(info.is_direct());
   1592     EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   1593   }
   1594   {
   1595     ProxyService service(
   1596         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1597     GURL test_url("ftp://ftp.google.com");
   1598     ProxyInfo info;
   1599     TestCompletionCallback callback;
   1600     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1601                                   callback.callback(), NULL,
   1602                                   NULL, BoundNetLog());
   1603     EXPECT_EQ(OK, rv);
   1604     EXPECT_FALSE(info.is_direct());
   1605     EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
   1606   }
   1607   {
   1608     ProxyService service(
   1609         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1610     GURL test_url("https://webbranch.techcu.com");
   1611     ProxyInfo info;
   1612     TestCompletionCallback callback;
   1613     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1614                                   callback.callback(), NULL,
   1615                                   NULL, BoundNetLog());
   1616     EXPECT_EQ(OK, rv);
   1617     EXPECT_FALSE(info.is_direct());
   1618     EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
   1619   }
   1620   {
   1621     ProxyService service(
   1622         new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
   1623     GURL test_url("unknown://www.microsoft.com");
   1624     ProxyInfo info;
   1625     TestCompletionCallback callback;
   1626     int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
   1627                                   callback.callback(), NULL,
   1628                                   NULL, BoundNetLog());
   1629     EXPECT_EQ(OK, rv);
   1630     EXPECT_FALSE(info.is_direct());
   1631     EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
   1632   }
   1633 }
   1634 
   1635 // Test cancellation of an in-progress request.
   1636 TEST_F(ProxyServiceTest, CancelInProgressRequest) {
   1637   MockProxyConfigService* config_service =
   1638       new MockProxyConfigService("http://foopy/proxy.pac");
   1639 
   1640   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   1641 
   1642   ProxyService service(config_service, resolver, NULL);
   1643 
   1644   // Start 3 requests.
   1645 
   1646   ProxyInfo info1;
   1647   TestCompletionCallback callback1;
   1648   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   1649                                 &info1, callback1.callback(), NULL, NULL,
   1650                                 BoundNetLog());
   1651   EXPECT_EQ(ERR_IO_PENDING, rv);
   1652 
   1653   // Nothing has been sent to the proxy resolver yet, since the proxy
   1654   // resolver has not been configured yet.
   1655   ASSERT_EQ(0u, resolver->pending_requests().size());
   1656 
   1657   // Successfully initialize the PAC script.
   1658   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   1659             resolver->pending_set_pac_script_request()->script_data()->url());
   1660   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1661 
   1662   ASSERT_EQ(1u, resolver->pending_requests().size());
   1663   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   1664 
   1665   ProxyInfo info2;
   1666   TestCompletionCallback callback2;
   1667   ProxyService::PacRequest* request2;
   1668   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   1669                             callback2.callback(), &request2, NULL,
   1670                             BoundNetLog());
   1671   EXPECT_EQ(ERR_IO_PENDING, rv);
   1672   ASSERT_EQ(2u, resolver->pending_requests().size());
   1673   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
   1674 
   1675   ProxyInfo info3;
   1676   TestCompletionCallback callback3;
   1677   rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
   1678                             callback3.callback(), NULL, NULL, BoundNetLog());
   1679   EXPECT_EQ(ERR_IO_PENDING, rv);
   1680   ASSERT_EQ(3u, resolver->pending_requests().size());
   1681   EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
   1682 
   1683   // Cancel the second request
   1684   service.CancelPacRequest(request2);
   1685 
   1686   ASSERT_EQ(2u, resolver->pending_requests().size());
   1687   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   1688   EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
   1689 
   1690   // Complete the two un-cancelled requests.
   1691   // We complete the last one first, just to mix it up a bit.
   1692   resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
   1693   resolver->pending_requests()[1]->CompleteNow(OK);
   1694 
   1695   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   1696   resolver->pending_requests()[0]->CompleteNow(OK);
   1697 
   1698   // Complete and verify that requests ran as expected.
   1699   EXPECT_EQ(OK, callback1.WaitForResult());
   1700   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   1701 
   1702   EXPECT_FALSE(callback2.have_result());  // Cancelled.
   1703   ASSERT_EQ(1u, resolver->cancelled_requests().size());
   1704   EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
   1705 
   1706   EXPECT_EQ(OK, callback3.WaitForResult());
   1707   EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
   1708 }
   1709 
   1710 // Test the initial PAC download for resolver that expects bytes.
   1711 TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
   1712   MockProxyConfigService* config_service =
   1713       new MockProxyConfigService("http://foopy/proxy.pac");
   1714 
   1715   MockAsyncProxyResolverExpectsBytes* resolver =
   1716       new MockAsyncProxyResolverExpectsBytes;
   1717 
   1718   ProxyService service(config_service, resolver, NULL);
   1719 
   1720   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   1721   service.SetProxyScriptFetchers(fetcher,
   1722                                  new DoNothingDhcpProxyScriptFetcher());
   1723 
   1724   // Start 3 requests.
   1725 
   1726   ProxyInfo info1;
   1727   TestCompletionCallback callback1;
   1728   ProxyService::PacRequest* request1;
   1729   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   1730                                 &info1, callback1.callback(), &request1, NULL,
   1731                                 BoundNetLog());
   1732   EXPECT_EQ(ERR_IO_PENDING, rv);
   1733 
   1734   // The first request should have triggered download of PAC script.
   1735   EXPECT_TRUE(fetcher->has_pending_request());
   1736   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   1737 
   1738   ProxyInfo info2;
   1739   TestCompletionCallback callback2;
   1740   ProxyService::PacRequest* request2;
   1741   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   1742                             callback2.callback(), &request2, NULL,
   1743                             BoundNetLog());
   1744   EXPECT_EQ(ERR_IO_PENDING, rv);
   1745 
   1746   ProxyInfo info3;
   1747   TestCompletionCallback callback3;
   1748   ProxyService::PacRequest* request3;
   1749   rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
   1750                             callback3.callback(), &request3, NULL,
   1751                             BoundNetLog());
   1752   EXPECT_EQ(ERR_IO_PENDING, rv);
   1753 
   1754   // Nothing has been sent to the resolver yet.
   1755   EXPECT_TRUE(resolver->pending_requests().empty());
   1756 
   1757   EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
   1758             service.GetLoadState(request1));
   1759   EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
   1760             service.GetLoadState(request2));
   1761   EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
   1762             service.GetLoadState(request3));
   1763 
   1764   // At this point the ProxyService should be waiting for the
   1765   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   1766   // PAC script download completion.
   1767   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   1768 
   1769   // Now that the PAC script is downloaded, it will have been sent to the proxy
   1770   // resolver.
   1771   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   1772             resolver->pending_set_pac_script_request()->script_data()->utf16());
   1773   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1774 
   1775   ASSERT_EQ(3u, resolver->pending_requests().size());
   1776   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   1777   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
   1778   EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
   1779 
   1780   EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1));
   1781   EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2));
   1782   EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3));
   1783 
   1784   // Complete all the requests (in some order).
   1785   // Note that as we complete requests, they shift up in |pending_requests()|.
   1786 
   1787   resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
   1788   resolver->pending_requests()[2]->CompleteNow(OK);
   1789 
   1790   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   1791   resolver->pending_requests()[0]->CompleteNow(OK);
   1792 
   1793   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   1794   resolver->pending_requests()[0]->CompleteNow(OK);
   1795 
   1796   // Complete and verify that requests ran as expected.
   1797   EXPECT_EQ(OK, callback1.WaitForResult());
   1798   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   1799   EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
   1800   EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
   1801   EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
   1802 
   1803   EXPECT_EQ(OK, callback2.WaitForResult());
   1804   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   1805   EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
   1806   EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
   1807   EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
   1808 
   1809   EXPECT_EQ(OK, callback3.WaitForResult());
   1810   EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
   1811   EXPECT_FALSE(info3.proxy_resolve_start_time().is_null());
   1812   EXPECT_FALSE(info3.proxy_resolve_end_time().is_null());
   1813   EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
   1814 }
   1815 
   1816 // Test changing the ProxyScriptFetcher while PAC download is in progress.
   1817 TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
   1818   MockProxyConfigService* config_service =
   1819       new MockProxyConfigService("http://foopy/proxy.pac");
   1820 
   1821   MockAsyncProxyResolverExpectsBytes* resolver =
   1822       new MockAsyncProxyResolverExpectsBytes;
   1823 
   1824   ProxyService service(config_service, resolver, NULL);
   1825 
   1826   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   1827   service.SetProxyScriptFetchers(fetcher,
   1828                                  new DoNothingDhcpProxyScriptFetcher());
   1829 
   1830   // Start 2 requests.
   1831 
   1832   ProxyInfo info1;
   1833   TestCompletionCallback callback1;
   1834   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   1835                                 &info1, callback1.callback(), NULL, NULL,
   1836                                 BoundNetLog());
   1837   EXPECT_EQ(ERR_IO_PENDING, rv);
   1838 
   1839   // The first request should have triggered download of PAC script.
   1840   EXPECT_TRUE(fetcher->has_pending_request());
   1841   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   1842 
   1843   ProxyInfo info2;
   1844   TestCompletionCallback callback2;
   1845   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   1846                             callback2.callback(), NULL, NULL, BoundNetLog());
   1847   EXPECT_EQ(ERR_IO_PENDING, rv);
   1848 
   1849   // At this point the ProxyService should be waiting for the
   1850   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   1851   // PAC script download completion.
   1852 
   1853   // We now change out the ProxyService's script fetcher. We should restart
   1854   // the initialization with the new fetcher.
   1855 
   1856   fetcher = new MockProxyScriptFetcher;
   1857   service.SetProxyScriptFetchers(fetcher,
   1858                                  new DoNothingDhcpProxyScriptFetcher());
   1859 
   1860   // Nothing has been sent to the resolver yet.
   1861   EXPECT_TRUE(resolver->pending_requests().empty());
   1862 
   1863   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   1864 
   1865   // Now that the PAC script is downloaded, it will have been sent to the proxy
   1866   // resolver.
   1867   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   1868             resolver->pending_set_pac_script_request()->script_data()->utf16());
   1869   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1870 
   1871   ASSERT_EQ(2u, resolver->pending_requests().size());
   1872   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   1873   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
   1874 }
   1875 
   1876 // Test cancellation of a request, while the PAC script is being fetched.
   1877 TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
   1878   MockProxyConfigService* config_service =
   1879       new MockProxyConfigService("http://foopy/proxy.pac");
   1880 
   1881   MockAsyncProxyResolverExpectsBytes* resolver =
   1882       new MockAsyncProxyResolverExpectsBytes;
   1883 
   1884   ProxyService service(config_service, resolver, NULL);
   1885 
   1886   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   1887   service.SetProxyScriptFetchers(fetcher,
   1888                                  new DoNothingDhcpProxyScriptFetcher());
   1889 
   1890   // Start 3 requests.
   1891   ProxyInfo info1;
   1892   TestCompletionCallback callback1;
   1893   ProxyService::PacRequest* request1;
   1894   CapturingBoundNetLog log1;
   1895   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   1896                                 &info1, callback1.callback(), &request1, NULL,
   1897                                 log1.bound());
   1898   EXPECT_EQ(ERR_IO_PENDING, rv);
   1899 
   1900   // The first request should have triggered download of PAC script.
   1901   EXPECT_TRUE(fetcher->has_pending_request());
   1902   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   1903 
   1904   ProxyInfo info2;
   1905   TestCompletionCallback callback2;
   1906   ProxyService::PacRequest* request2;
   1907   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   1908                             callback2.callback(), &request2, NULL,
   1909                             BoundNetLog());
   1910   EXPECT_EQ(ERR_IO_PENDING, rv);
   1911 
   1912   ProxyInfo info3;
   1913   TestCompletionCallback callback3;
   1914   rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
   1915                             callback3.callback(), NULL, NULL, BoundNetLog());
   1916   EXPECT_EQ(ERR_IO_PENDING, rv);
   1917 
   1918   // Nothing has been sent to the resolver yet.
   1919   EXPECT_TRUE(resolver->pending_requests().empty());
   1920 
   1921   // Cancel the first 2 requests.
   1922   service.CancelPacRequest(request1);
   1923   service.CancelPacRequest(request2);
   1924 
   1925   // At this point the ProxyService should be waiting for the
   1926   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   1927   // PAC script download completion.
   1928   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   1929 
   1930   // Now that the PAC script is downloaded, it will have been sent to the
   1931   // proxy resolver.
   1932   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   1933             resolver->pending_set_pac_script_request()->script_data()->utf16());
   1934   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   1935 
   1936   ASSERT_EQ(1u, resolver->pending_requests().size());
   1937   EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
   1938 
   1939   // Complete all the requests.
   1940   resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
   1941   resolver->pending_requests()[0]->CompleteNow(OK);
   1942 
   1943   EXPECT_EQ(OK, callback3.WaitForResult());
   1944   EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
   1945 
   1946   EXPECT_TRUE(resolver->cancelled_requests().empty());
   1947 
   1948   EXPECT_FALSE(callback1.have_result());  // Cancelled.
   1949   EXPECT_FALSE(callback2.have_result());  // Cancelled.
   1950 
   1951   CapturingNetLog::CapturedEntryList entries1;
   1952   log1.GetEntries(&entries1);
   1953 
   1954   // Check the NetLog for request 1 (which was cancelled) got filled properly.
   1955   EXPECT_EQ(4u, entries1.size());
   1956   EXPECT_TRUE(LogContainsBeginEvent(
   1957       entries1, 0, NetLog::TYPE_PROXY_SERVICE));
   1958   EXPECT_TRUE(LogContainsBeginEvent(
   1959       entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
   1960   // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
   1961   // the cancellation occured.
   1962   EXPECT_TRUE(LogContainsEvent(
   1963       entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
   1964   EXPECT_TRUE(LogContainsEndEvent(
   1965       entries1, 3, NetLog::TYPE_PROXY_SERVICE));
   1966 }
   1967 
   1968 // Test that if auto-detect fails, we fall-back to the custom pac.
   1969 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
   1970   ProxyConfig config;
   1971   config.set_auto_detect(true);
   1972   config.set_pac_url(GURL("http://foopy/proxy.pac"));
   1973   config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
   1974 
   1975   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   1976   MockAsyncProxyResolverExpectsBytes* resolver =
   1977       new MockAsyncProxyResolverExpectsBytes;
   1978   ProxyService service(config_service, resolver, NULL);
   1979 
   1980   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   1981   service.SetProxyScriptFetchers(fetcher,
   1982                                  new DoNothingDhcpProxyScriptFetcher());
   1983 
   1984   // Start 2 requests.
   1985 
   1986   ProxyInfo info1;
   1987   TestCompletionCallback callback1;
   1988   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   1989                                 &info1, callback1.callback(), NULL, NULL,
   1990                                 BoundNetLog());
   1991   EXPECT_EQ(ERR_IO_PENDING, rv);
   1992 
   1993   ProxyInfo info2;
   1994   TestCompletionCallback callback2;
   1995   ProxyService::PacRequest* request2;
   1996   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   1997                             callback2.callback(), &request2, NULL,
   1998                             BoundNetLog());
   1999   EXPECT_EQ(ERR_IO_PENDING, rv);
   2000 
   2001   // Check that nothing has been sent to the proxy resolver yet.
   2002   ASSERT_EQ(0u, resolver->pending_requests().size());
   2003 
   2004   // It should be trying to auto-detect first -- FAIL the autodetect during
   2005   // the script download.
   2006   EXPECT_TRUE(fetcher->has_pending_request());
   2007   EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
   2008   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   2009 
   2010   // Next it should be trying the custom PAC url.
   2011   EXPECT_TRUE(fetcher->has_pending_request());
   2012   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2013   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2014 
   2015   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2016             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2017   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2018 
   2019   // Now finally, the pending requests should have been sent to the resolver
   2020   // (which was initialized with custom PAC script).
   2021 
   2022   ASSERT_EQ(2u, resolver->pending_requests().size());
   2023   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2024   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
   2025 
   2026   // Complete the pending requests.
   2027   resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
   2028   resolver->pending_requests()[1]->CompleteNow(OK);
   2029   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2030   resolver->pending_requests()[0]->CompleteNow(OK);
   2031 
   2032   // Verify that requests ran as expected.
   2033   EXPECT_EQ(OK, callback1.WaitForResult());
   2034   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2035   EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
   2036   EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
   2037   EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
   2038 
   2039   EXPECT_EQ(OK, callback2.WaitForResult());
   2040   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2041   EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
   2042   EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
   2043   EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
   2044 }
   2045 
   2046 // This is the same test as FallbackFromAutodetectToCustomPac, except
   2047 // the auto-detect script fails parsing rather than downloading.
   2048 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
   2049   ProxyConfig config;
   2050   config.set_auto_detect(true);
   2051   config.set_pac_url(GURL("http://foopy/proxy.pac"));
   2052   config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
   2053 
   2054   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   2055   MockAsyncProxyResolverExpectsBytes* resolver =
   2056       new MockAsyncProxyResolverExpectsBytes;
   2057   ProxyService service(config_service, resolver, NULL);
   2058 
   2059   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2060   service.SetProxyScriptFetchers(fetcher,
   2061                                  new DoNothingDhcpProxyScriptFetcher());
   2062 
   2063   // Start 2 requests.
   2064 
   2065   ProxyInfo info1;
   2066   TestCompletionCallback callback1;
   2067   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   2068                                 &info1, callback1.callback(), NULL, NULL,
   2069                                 BoundNetLog());
   2070   EXPECT_EQ(ERR_IO_PENDING, rv);
   2071 
   2072   ProxyInfo info2;
   2073   TestCompletionCallback callback2;
   2074   ProxyService::PacRequest* request2;
   2075   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   2076                             callback2.callback(), &request2, NULL,
   2077                             BoundNetLog());
   2078   EXPECT_EQ(ERR_IO_PENDING, rv);
   2079 
   2080   // Check that nothing has been sent to the proxy resolver yet.
   2081   ASSERT_EQ(0u, resolver->pending_requests().size());
   2082 
   2083   // It should be trying to auto-detect first -- succeed the download.
   2084   EXPECT_TRUE(fetcher->has_pending_request());
   2085   EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
   2086   fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
   2087 
   2088   // The script contents passed failed basic verification step (since didn't
   2089   // contain token FindProxyForURL), so it was never passed to the resolver.
   2090 
   2091   // Next it should be trying the custom PAC url.
   2092   EXPECT_TRUE(fetcher->has_pending_request());
   2093   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2094   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2095 
   2096   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2097             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2098   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2099 
   2100   // Now finally, the pending requests should have been sent to the resolver
   2101   // (which was initialized with custom PAC script).
   2102 
   2103   ASSERT_EQ(2u, resolver->pending_requests().size());
   2104   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2105   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
   2106 
   2107   // Complete the pending requests.
   2108   resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
   2109   resolver->pending_requests()[1]->CompleteNow(OK);
   2110   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2111   resolver->pending_requests()[0]->CompleteNow(OK);
   2112 
   2113   // Verify that requests ran as expected.
   2114   EXPECT_EQ(OK, callback1.WaitForResult());
   2115   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2116 
   2117   EXPECT_EQ(OK, callback2.WaitForResult());
   2118   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2119 }
   2120 
   2121 // Test that if all of auto-detect, a custom PAC script, and manual settings
   2122 // are given, then we will try them in that order.
   2123 TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
   2124   ProxyConfig config;
   2125   config.set_auto_detect(true);
   2126   config.set_pac_url(GURL("http://foopy/proxy.pac"));
   2127   config.proxy_rules().ParseFromString("http=foopy:80");
   2128 
   2129   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   2130   MockAsyncProxyResolverExpectsBytes* resolver =
   2131       new MockAsyncProxyResolverExpectsBytes;
   2132   ProxyService service(config_service, resolver, NULL);
   2133 
   2134   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2135   service.SetProxyScriptFetchers(fetcher,
   2136                                  new DoNothingDhcpProxyScriptFetcher());
   2137 
   2138   // Start 2 requests.
   2139 
   2140   ProxyInfo info1;
   2141   TestCompletionCallback callback1;
   2142   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   2143                                 &info1, callback1.callback(), NULL, NULL,
   2144                                 BoundNetLog());
   2145   EXPECT_EQ(ERR_IO_PENDING, rv);
   2146 
   2147   ProxyInfo info2;
   2148   TestCompletionCallback callback2;
   2149   ProxyService::PacRequest* request2;
   2150   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   2151                             callback2.callback(), &request2, NULL,
   2152                             BoundNetLog());
   2153   EXPECT_EQ(ERR_IO_PENDING, rv);
   2154 
   2155   // Check that nothing has been sent to the proxy resolver yet.
   2156   ASSERT_EQ(0u, resolver->pending_requests().size());
   2157 
   2158   // It should be trying to auto-detect first -- fail the download.
   2159   EXPECT_TRUE(fetcher->has_pending_request());
   2160   EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
   2161   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   2162 
   2163   // Next it should be trying the custom PAC url -- fail the download.
   2164   EXPECT_TRUE(fetcher->has_pending_request());
   2165   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2166   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   2167 
   2168   // Since we never managed to initialize a ProxyResolver, nothing should have
   2169   // been sent to it.
   2170   ASSERT_EQ(0u, resolver->pending_requests().size());
   2171 
   2172   // Verify that requests ran as expected -- they should have fallen back to
   2173   // the manual proxy configuration for HTTP urls.
   2174   EXPECT_EQ(OK, callback1.WaitForResult());
   2175   EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
   2176 
   2177   EXPECT_EQ(OK, callback2.WaitForResult());
   2178   EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
   2179 }
   2180 
   2181 // Test that the bypass rules are NOT applied when using autodetect.
   2182 TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
   2183   ProxyConfig config;
   2184   config.set_auto_detect(true);
   2185   config.set_pac_url(GURL("http://foopy/proxy.pac"));
   2186   config.proxy_rules().ParseFromString("http=foopy:80");  // Not used.
   2187   config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
   2188 
   2189   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   2190   MockAsyncProxyResolverExpectsBytes* resolver =
   2191       new MockAsyncProxyResolverExpectsBytes;
   2192   ProxyService service(config_service, resolver, NULL);
   2193 
   2194   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2195   service.SetProxyScriptFetchers(fetcher,
   2196                                  new DoNothingDhcpProxyScriptFetcher());
   2197 
   2198   // Start 1 requests.
   2199 
   2200   ProxyInfo info1;
   2201   TestCompletionCallback callback1;
   2202   int rv = service.ResolveProxy(
   2203       GURL("http://www.google.com"), net::LOAD_NORMAL, &info1,
   2204       callback1.callback(), NULL, NULL, BoundNetLog());
   2205   EXPECT_EQ(ERR_IO_PENDING, rv);
   2206 
   2207   // Check that nothing has been sent to the proxy resolver yet.
   2208   ASSERT_EQ(0u, resolver->pending_requests().size());
   2209 
   2210   // It should be trying to auto-detect first -- succeed the download.
   2211   EXPECT_TRUE(fetcher->has_pending_request());
   2212   EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
   2213   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2214 
   2215   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2216             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2217   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2218 
   2219   ASSERT_EQ(1u, resolver->pending_requests().size());
   2220   EXPECT_EQ(GURL("http://www.google.com"),
   2221             resolver->pending_requests()[0]->url());
   2222 
   2223   // Complete the pending request.
   2224   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2225   resolver->pending_requests()[0]->CompleteNow(OK);
   2226 
   2227   // Verify that request ran as expected.
   2228   EXPECT_EQ(OK, callback1.WaitForResult());
   2229   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2230 
   2231   // Start another request, it should pickup the bypass item.
   2232   ProxyInfo info2;
   2233   TestCompletionCallback callback2;
   2234   rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
   2235                             &info2, callback2.callback(), NULL, NULL,
   2236                             BoundNetLog());
   2237   EXPECT_EQ(ERR_IO_PENDING, rv);
   2238 
   2239   ASSERT_EQ(1u, resolver->pending_requests().size());
   2240   EXPECT_EQ(GURL("http://www.google.com"),
   2241             resolver->pending_requests()[0]->url());
   2242 
   2243   // Complete the pending request.
   2244   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   2245   resolver->pending_requests()[0]->CompleteNow(OK);
   2246 
   2247   EXPECT_EQ(OK, callback2.WaitForResult());
   2248   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2249 }
   2250 
   2251 // Delete the ProxyService while InitProxyResolver has an outstanding
   2252 // request to the script fetcher. When run under valgrind, should not
   2253 // have any memory errors (used to be that the ProxyScriptFetcher was
   2254 // being deleted prior to the InitProxyResolver).
   2255 TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
   2256   ProxyConfig config =
   2257     ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
   2258 
   2259   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   2260   MockAsyncProxyResolverExpectsBytes* resolver =
   2261       new MockAsyncProxyResolverExpectsBytes;
   2262   ProxyService service(config_service, resolver, NULL);
   2263 
   2264   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2265   service.SetProxyScriptFetchers(fetcher,
   2266                                  new DoNothingDhcpProxyScriptFetcher());
   2267 
   2268   // Start 1 request.
   2269 
   2270   ProxyInfo info1;
   2271   TestCompletionCallback callback1;
   2272   int rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
   2273                                 &info1, callback1.callback(), NULL, NULL,
   2274                                 BoundNetLog());
   2275   EXPECT_EQ(ERR_IO_PENDING, rv);
   2276 
   2277   // Check that nothing has been sent to the proxy resolver yet.
   2278   ASSERT_EQ(0u, resolver->pending_requests().size());
   2279 
   2280   // InitProxyResolver should have issued a request to the ProxyScriptFetcher
   2281   // and be waiting on that to complete.
   2282   EXPECT_TRUE(fetcher->has_pending_request());
   2283   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2284 }
   2285 
   2286 // Delete the ProxyService while InitProxyResolver has an outstanding
   2287 // request to the proxy resolver. When run under valgrind, should not
   2288 // have any memory errors (used to be that the ProxyResolver was
   2289 // being deleted prior to the InitProxyResolver).
   2290 TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
   2291   MockProxyConfigService* config_service =
   2292       new MockProxyConfigService("http://foopy/proxy.pac");
   2293 
   2294   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   2295 
   2296   ProxyService service(config_service, resolver, NULL);
   2297 
   2298   GURL url("http://www.google.com/");
   2299 
   2300   ProxyInfo info;
   2301   TestCompletionCallback callback;
   2302   int rv = service.ResolveProxy(
   2303       url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
   2304       BoundNetLog());
   2305   EXPECT_EQ(ERR_IO_PENDING, rv);
   2306 
   2307   EXPECT_EQ(GURL("http://foopy/proxy.pac"),
   2308             resolver->pending_set_pac_script_request()->script_data()->url());
   2309 }
   2310 
   2311 TEST_F(ProxyServiceTest, ResetProxyConfigService) {
   2312   ProxyConfig config1;
   2313   config1.proxy_rules().ParseFromString("foopy1:8080");
   2314   config1.set_auto_detect(false);
   2315   ProxyService service(
   2316       new MockProxyConfigService(config1),
   2317       new MockAsyncProxyResolverExpectsBytes, NULL);
   2318 
   2319   ProxyInfo info;
   2320   TestCompletionCallback callback1;
   2321   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   2322                                 &info, callback1.callback(), NULL, NULL,
   2323                                 BoundNetLog());
   2324   EXPECT_EQ(OK, rv);
   2325   EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
   2326 
   2327   ProxyConfig config2;
   2328   config2.proxy_rules().ParseFromString("foopy2:8080");
   2329   config2.set_auto_detect(false);
   2330   service.ResetConfigService(new MockProxyConfigService(config2));
   2331   TestCompletionCallback callback2;
   2332   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info,
   2333                             callback2.callback(), NULL, NULL, BoundNetLog());
   2334   EXPECT_EQ(OK, rv);
   2335   EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
   2336 }
   2337 
   2338 // Test that when going from a configuration that required PAC to one
   2339 // that does NOT, we unset the variable |should_use_proxy_resolver_|.
   2340 TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
   2341   ProxyConfig config = ProxyConfig::CreateAutoDetect();
   2342 
   2343   MockProxyConfigService* config_service = new MockProxyConfigService(config);
   2344   MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
   2345   ProxyService service(config_service, resolver, NULL);
   2346 
   2347   // Start 1 request.
   2348 
   2349   ProxyInfo info1;
   2350   TestCompletionCallback callback1;
   2351   int rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
   2352                                 &info1, callback1.callback(), NULL, NULL,
   2353                                 BoundNetLog());
   2354   EXPECT_EQ(ERR_IO_PENDING, rv);
   2355 
   2356   // Check that nothing has been sent to the proxy resolver yet.
   2357   ASSERT_EQ(0u, resolver->pending_requests().size());
   2358 
   2359   // Successfully set the autodetect script.
   2360   EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
   2361             resolver->pending_set_pac_script_request()->script_data()->type());
   2362   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2363 
   2364   // Complete the pending request.
   2365   ASSERT_EQ(1u, resolver->pending_requests().size());
   2366   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2367   resolver->pending_requests()[0]->CompleteNow(OK);
   2368 
   2369   // Verify that request ran as expected.
   2370   EXPECT_EQ(OK, callback1.WaitForResult());
   2371   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2372 
   2373   // Force the ProxyService to pull down a new proxy configuration.
   2374   // (Even though the configuration isn't old/bad).
   2375   //
   2376   // This new configuration no longer has auto_detect set, so
   2377   // requests should complete synchronously now as direct-connect.
   2378   config_service->SetConfig(ProxyConfig::CreateDirect());
   2379 
   2380   // Start another request -- the effective configuration has changed.
   2381   ProxyInfo info2;
   2382   TestCompletionCallback callback2;
   2383   rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
   2384                             &info2, callback2.callback(), NULL, NULL,
   2385                             BoundNetLog());
   2386   EXPECT_EQ(OK, rv);
   2387 
   2388   EXPECT_TRUE(info2.is_direct());
   2389 }
   2390 
   2391 TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
   2392   MockProxyConfigService* config_service =
   2393       new MockProxyConfigService("http://foopy/proxy.pac");
   2394 
   2395   MockAsyncProxyResolverExpectsBytes* resolver =
   2396       new MockAsyncProxyResolverExpectsBytes;
   2397 
   2398   CapturingNetLog log;
   2399 
   2400   ProxyService service(config_service, resolver, &log);
   2401 
   2402   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2403   service.SetProxyScriptFetchers(fetcher,
   2404                                  new DoNothingDhcpProxyScriptFetcher());
   2405 
   2406   // Disable the "wait after IP address changes" hack, so this unit-test can
   2407   // complete quickly.
   2408   service.set_stall_proxy_auto_config_delay(base::TimeDelta());
   2409 
   2410   // Start 1 request.
   2411 
   2412   ProxyInfo info1;
   2413   TestCompletionCallback callback1;
   2414   int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
   2415                                 &info1, callback1.callback(), NULL, NULL,
   2416                                 BoundNetLog());
   2417   EXPECT_EQ(ERR_IO_PENDING, rv);
   2418 
   2419   // The first request should have triggered initial download of PAC script.
   2420   EXPECT_TRUE(fetcher->has_pending_request());
   2421   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2422 
   2423   // Nothing has been sent to the resolver yet.
   2424   EXPECT_TRUE(resolver->pending_requests().empty());
   2425 
   2426   // At this point the ProxyService should be waiting for the
   2427   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   2428   // PAC script download completion.
   2429   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2430 
   2431   // Now that the PAC script is downloaded, the request will have been sent to
   2432   // the proxy resolver.
   2433   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2434             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2435   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2436 
   2437   ASSERT_EQ(1u, resolver->pending_requests().size());
   2438   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2439 
   2440   // Complete the pending request.
   2441   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2442   resolver->pending_requests()[0]->CompleteNow(OK);
   2443 
   2444   // Wait for completion callback, and verify that the request ran as expected.
   2445   EXPECT_EQ(OK, callback1.WaitForResult());
   2446   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2447 
   2448   // Now simluate a change in the network. The ProxyConfigService is still
   2449   // going to return the same PAC URL as before, but this URL needs to be
   2450   // refetched on the new network.
   2451   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
   2452   base::MessageLoop::current()->RunUntilIdle();  // Notification happens async.
   2453 
   2454   // Start a second request.
   2455   ProxyInfo info2;
   2456   TestCompletionCallback callback2;
   2457   rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
   2458                             callback2.callback(), NULL, NULL, BoundNetLog());
   2459   EXPECT_EQ(ERR_IO_PENDING, rv);
   2460 
   2461   // This second request should have triggered the re-download of the PAC
   2462   // script (since we marked the network as having changed).
   2463   EXPECT_TRUE(fetcher->has_pending_request());
   2464   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2465 
   2466   // Nothing has been sent to the resolver yet.
   2467   EXPECT_TRUE(resolver->pending_requests().empty());
   2468 
   2469   // Simulate the PAC script fetch as having completed (this time with
   2470   // different data).
   2471   fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
   2472 
   2473   // Now that the PAC script is downloaded, the second request will have been
   2474   // sent to the proxy resolver.
   2475   EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
   2476             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2477   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2478 
   2479   ASSERT_EQ(1u, resolver->pending_requests().size());
   2480   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
   2481 
   2482   // Complete the pending second request.
   2483   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   2484   resolver->pending_requests()[0]->CompleteNow(OK);
   2485 
   2486   // Wait for completion callback, and verify that the request ran as expected.
   2487   EXPECT_EQ(OK, callback2.WaitForResult());
   2488   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2489 
   2490   // Check that the expected events were output to the log stream. In particular
   2491   // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
   2492   // setup), and NOT a second time when the IP address changed.
   2493   CapturingNetLog::CapturedEntryList entries;
   2494   log.GetEntries(&entries);
   2495 
   2496   EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
   2497                                        NetLog::TYPE_PROXY_CONFIG_CHANGED));
   2498   ASSERT_EQ(9u, entries.size());
   2499   for (size_t i = 1; i < entries.size(); ++i)
   2500     EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
   2501 }
   2502 
   2503 // This test verifies that the PAC script specified by the settings is
   2504 // periodically polled for changes. Specifically, if the initial fetch fails due
   2505 // to a network error, we will eventually re-configure the service to use the
   2506 // script once it becomes available.
   2507 TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
   2508   // Change the retry policy to wait a mere 1 ms before retrying, so the test
   2509   // runs quickly.
   2510   ImmediatePollPolicy poll_policy;
   2511   ProxyService::set_pac_script_poll_policy(&poll_policy);
   2512 
   2513   MockProxyConfigService* config_service =
   2514       new MockProxyConfigService("http://foopy/proxy.pac");
   2515 
   2516   MockAsyncProxyResolverExpectsBytes* resolver =
   2517       new MockAsyncProxyResolverExpectsBytes;
   2518 
   2519   ProxyService service(config_service, resolver, NULL);
   2520 
   2521   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2522   service.SetProxyScriptFetchers(fetcher,
   2523                                  new DoNothingDhcpProxyScriptFetcher());
   2524 
   2525   // Start 1 request.
   2526 
   2527   ProxyInfo info1;
   2528   TestCompletionCallback callback1;
   2529   int rv = service.ResolveProxy(
   2530       GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
   2531       NULL, NULL, BoundNetLog());
   2532   EXPECT_EQ(ERR_IO_PENDING, rv);
   2533 
   2534   // The first request should have triggered initial download of PAC script.
   2535   EXPECT_TRUE(fetcher->has_pending_request());
   2536   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2537 
   2538   // Nothing has been sent to the resolver yet.
   2539   EXPECT_TRUE(resolver->pending_requests().empty());
   2540 
   2541   // At this point the ProxyService should be waiting for the
   2542   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   2543   // PAC script download completion.
   2544   //
   2545   // We simulate a failed download attempt, the proxy service should now
   2546   // fall-back to DIRECT connections.
   2547   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   2548 
   2549   ASSERT_TRUE(resolver->pending_requests().empty());
   2550 
   2551   // Wait for completion callback, and verify it used DIRECT.
   2552   EXPECT_EQ(OK, callback1.WaitForResult());
   2553   EXPECT_TRUE(info1.is_direct());
   2554 
   2555   // At this point we have initialized the proxy service using a PAC script,
   2556   // however it failed and fell-back to DIRECT.
   2557   //
   2558   // A background task to periodically re-check the PAC script for validity will
   2559   // have been started. We will now wait for the next download attempt to start.
   2560   //
   2561   // Note that we shouldn't have to wait long here, since our test enables a
   2562   // special unit-test mode.
   2563   fetcher->WaitUntilFetch();
   2564 
   2565   ASSERT_TRUE(resolver->pending_requests().empty());
   2566 
   2567   // Make sure that our background checker is trying to download the expected
   2568   // PAC script (same one as before). This time we will simulate a successful
   2569   // download of the script.
   2570   EXPECT_TRUE(fetcher->has_pending_request());
   2571   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2572   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2573 
   2574   base::MessageLoop::current()->RunUntilIdle();
   2575 
   2576   // Now that the PAC script is downloaded, it should be used to initialize the
   2577   // ProxyResolver. Simulate a successful parse.
   2578   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2579             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2580   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2581 
   2582   // At this point the ProxyService should have re-configured itself to use the
   2583   // PAC script (thereby recovering from the initial fetch failure). We will
   2584   // verify that the next Resolve request uses the resolver rather than
   2585   // DIRECT.
   2586 
   2587   // Start a second request.
   2588   ProxyInfo info2;
   2589   TestCompletionCallback callback2;
   2590   rv = service.ResolveProxy(
   2591       GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
   2592       NULL, NULL, BoundNetLog());
   2593   EXPECT_EQ(ERR_IO_PENDING, rv);
   2594 
   2595   // Check that it was sent to the resolver.
   2596   ASSERT_EQ(1u, resolver->pending_requests().size());
   2597   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
   2598 
   2599   // Complete the pending second request.
   2600   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   2601   resolver->pending_requests()[0]->CompleteNow(OK);
   2602 
   2603   // Wait for completion callback, and verify that the request ran as expected.
   2604   EXPECT_EQ(OK, callback2.WaitForResult());
   2605   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2606 }
   2607 
   2608 // This test verifies that the PAC script specified by the settings is
   2609 // periodically polled for changes. Specifically, if the initial fetch succeeds,
   2610 // however at a later time its *contents* change, we will eventually
   2611 // re-configure the service to use the new script.
   2612 TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
   2613   // Change the retry policy to wait a mere 1 ms before retrying, so the test
   2614   // runs quickly.
   2615   ImmediatePollPolicy poll_policy;
   2616   ProxyService::set_pac_script_poll_policy(&poll_policy);
   2617 
   2618   MockProxyConfigService* config_service =
   2619       new MockProxyConfigService("http://foopy/proxy.pac");
   2620 
   2621   MockAsyncProxyResolverExpectsBytes* resolver =
   2622       new MockAsyncProxyResolverExpectsBytes;
   2623 
   2624   ProxyService service(config_service, resolver, NULL);
   2625 
   2626   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2627   service.SetProxyScriptFetchers(fetcher,
   2628                                  new DoNothingDhcpProxyScriptFetcher());
   2629 
   2630   // Start 1 request.
   2631 
   2632   ProxyInfo info1;
   2633   TestCompletionCallback callback1;
   2634   int rv = service.ResolveProxy(
   2635       GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
   2636       NULL, NULL, BoundNetLog());
   2637   EXPECT_EQ(ERR_IO_PENDING, rv);
   2638 
   2639   // The first request should have triggered initial download of PAC script.
   2640   EXPECT_TRUE(fetcher->has_pending_request());
   2641   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2642 
   2643   // Nothing has been sent to the resolver yet.
   2644   EXPECT_TRUE(resolver->pending_requests().empty());
   2645 
   2646   // At this point the ProxyService should be waiting for the
   2647   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   2648   // PAC script download completion.
   2649   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2650 
   2651   // Now that the PAC script is downloaded, the request will have been sent to
   2652   // the proxy resolver.
   2653   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2654             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2655   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2656 
   2657   ASSERT_EQ(1u, resolver->pending_requests().size());
   2658   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2659 
   2660   // Complete the pending request.
   2661   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2662   resolver->pending_requests()[0]->CompleteNow(OK);
   2663 
   2664   // Wait for completion callback, and verify that the request ran as expected.
   2665   EXPECT_EQ(OK, callback1.WaitForResult());
   2666   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2667 
   2668   // At this point we have initialized the proxy service using a PAC script.
   2669   //
   2670   // A background task to periodically re-check the PAC script for validity will
   2671   // have been started. We will now wait for the next download attempt to start.
   2672   //
   2673   // Note that we shouldn't have to wait long here, since our test enables a
   2674   // special unit-test mode.
   2675   fetcher->WaitUntilFetch();
   2676 
   2677   ASSERT_TRUE(resolver->pending_requests().empty());
   2678 
   2679   // Make sure that our background checker is trying to download the expected
   2680   // PAC script (same one as before). This time we will simulate a successful
   2681   // download of a DIFFERENT script.
   2682   EXPECT_TRUE(fetcher->has_pending_request());
   2683   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2684   fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
   2685 
   2686   base::MessageLoop::current()->RunUntilIdle();
   2687 
   2688   // Now that the PAC script is downloaded, it should be used to initialize the
   2689   // ProxyResolver. Simulate a successful parse.
   2690   EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
   2691             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2692   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2693 
   2694   // At this point the ProxyService should have re-configured itself to use the
   2695   // new PAC script.
   2696 
   2697   // Start a second request.
   2698   ProxyInfo info2;
   2699   TestCompletionCallback callback2;
   2700   rv = service.ResolveProxy(
   2701       GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
   2702       NULL, NULL, BoundNetLog());
   2703   EXPECT_EQ(ERR_IO_PENDING, rv);
   2704 
   2705   // Check that it was sent to the resolver.
   2706   ASSERT_EQ(1u, resolver->pending_requests().size());
   2707   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
   2708 
   2709   // Complete the pending second request.
   2710   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   2711   resolver->pending_requests()[0]->CompleteNow(OK);
   2712 
   2713   // Wait for completion callback, and verify that the request ran as expected.
   2714   EXPECT_EQ(OK, callback2.WaitForResult());
   2715   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2716 }
   2717 
   2718 // This test verifies that the PAC script specified by the settings is
   2719 // periodically polled for changes. Specifically, if the initial fetch succeeds
   2720 // and so does the next poll, however the contents of the downloaded script
   2721 // have NOT changed, then we do not bother to re-initialize the proxy resolver.
   2722 TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
   2723   // Change the retry policy to wait a mere 1 ms before retrying, so the test
   2724   // runs quickly.
   2725   ImmediatePollPolicy poll_policy;
   2726   ProxyService::set_pac_script_poll_policy(&poll_policy);
   2727 
   2728   MockProxyConfigService* config_service =
   2729       new MockProxyConfigService("http://foopy/proxy.pac");
   2730 
   2731   MockAsyncProxyResolverExpectsBytes* resolver =
   2732       new MockAsyncProxyResolverExpectsBytes;
   2733 
   2734   ProxyService service(config_service, resolver, NULL);
   2735 
   2736   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2737   service.SetProxyScriptFetchers(fetcher,
   2738                                  new DoNothingDhcpProxyScriptFetcher());
   2739 
   2740   // Start 1 request.
   2741 
   2742   ProxyInfo info1;
   2743   TestCompletionCallback callback1;
   2744   int rv = service.ResolveProxy(
   2745       GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
   2746       NULL, NULL, BoundNetLog());
   2747   EXPECT_EQ(ERR_IO_PENDING, rv);
   2748 
   2749   // The first request should have triggered initial download of PAC script.
   2750   EXPECT_TRUE(fetcher->has_pending_request());
   2751   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2752 
   2753   // Nothing has been sent to the resolver yet.
   2754   EXPECT_TRUE(resolver->pending_requests().empty());
   2755 
   2756   // At this point the ProxyService should be waiting for the
   2757   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   2758   // PAC script download completion.
   2759   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2760 
   2761   // Now that the PAC script is downloaded, the request will have been sent to
   2762   // the proxy resolver.
   2763   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2764             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2765   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2766 
   2767   ASSERT_EQ(1u, resolver->pending_requests().size());
   2768   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2769 
   2770   // Complete the pending request.
   2771   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2772   resolver->pending_requests()[0]->CompleteNow(OK);
   2773 
   2774   // Wait for completion callback, and verify that the request ran as expected.
   2775   EXPECT_EQ(OK, callback1.WaitForResult());
   2776   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2777 
   2778   // At this point we have initialized the proxy service using a PAC script.
   2779   //
   2780   // A background task to periodically re-check the PAC script for validity will
   2781   // have been started. We will now wait for the next download attempt to start.
   2782   //
   2783   // Note that we shouldn't have to wait long here, since our test enables a
   2784   // special unit-test mode.
   2785   fetcher->WaitUntilFetch();
   2786 
   2787   ASSERT_TRUE(resolver->pending_requests().empty());
   2788 
   2789   // Make sure that our background checker is trying to download the expected
   2790   // PAC script (same one as before). We will simulate the same response as
   2791   // last time (i.e. the script is unchanged).
   2792   EXPECT_TRUE(fetcher->has_pending_request());
   2793   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2794   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2795 
   2796   base::MessageLoop::current()->RunUntilIdle();
   2797 
   2798   ASSERT_FALSE(resolver->has_pending_set_pac_script_request());
   2799 
   2800   // At this point the ProxyService is still running the same PAC script as
   2801   // before.
   2802 
   2803   // Start a second request.
   2804   ProxyInfo info2;
   2805   TestCompletionCallback callback2;
   2806   rv = service.ResolveProxy(
   2807       GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
   2808       NULL, NULL, BoundNetLog());
   2809   EXPECT_EQ(ERR_IO_PENDING, rv);
   2810 
   2811   // Check that it was sent to the resolver.
   2812   ASSERT_EQ(1u, resolver->pending_requests().size());
   2813   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
   2814 
   2815   // Complete the pending second request.
   2816   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   2817   resolver->pending_requests()[0]->CompleteNow(OK);
   2818 
   2819   // Wait for completion callback, and verify that the request ran as expected.
   2820   EXPECT_EQ(OK, callback2.WaitForResult());
   2821   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   2822 }
   2823 
   2824 // This test verifies that the PAC script specified by the settings is
   2825 // periodically polled for changes. Specifically, if the initial fetch succeeds,
   2826 // however at a later time it starts to fail, we should re-configure the
   2827 // ProxyService to stop using that PAC script.
   2828 TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
   2829   // Change the retry policy to wait a mere 1 ms before retrying, so the test
   2830   // runs quickly.
   2831   ImmediatePollPolicy poll_policy;
   2832   ProxyService::set_pac_script_poll_policy(&poll_policy);
   2833 
   2834   MockProxyConfigService* config_service =
   2835       new MockProxyConfigService("http://foopy/proxy.pac");
   2836 
   2837   MockAsyncProxyResolverExpectsBytes* resolver =
   2838       new MockAsyncProxyResolverExpectsBytes;
   2839 
   2840   ProxyService service(config_service, resolver, NULL);
   2841 
   2842   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2843   service.SetProxyScriptFetchers(fetcher,
   2844                                  new DoNothingDhcpProxyScriptFetcher());
   2845 
   2846   // Start 1 request.
   2847 
   2848   ProxyInfo info1;
   2849   TestCompletionCallback callback1;
   2850   int rv = service.ResolveProxy(
   2851       GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
   2852       NULL, NULL, BoundNetLog());
   2853   EXPECT_EQ(ERR_IO_PENDING, rv);
   2854 
   2855   // The first request should have triggered initial download of PAC script.
   2856   EXPECT_TRUE(fetcher->has_pending_request());
   2857   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2858 
   2859   // Nothing has been sent to the resolver yet.
   2860   EXPECT_TRUE(resolver->pending_requests().empty());
   2861 
   2862   // At this point the ProxyService should be waiting for the
   2863   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   2864   // PAC script download completion.
   2865   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   2866 
   2867   // Now that the PAC script is downloaded, the request will have been sent to
   2868   // the proxy resolver.
   2869   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   2870             resolver->pending_set_pac_script_request()->script_data()->utf16());
   2871   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   2872 
   2873   ASSERT_EQ(1u, resolver->pending_requests().size());
   2874   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   2875 
   2876   // Complete the pending request.
   2877   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   2878   resolver->pending_requests()[0]->CompleteNow(OK);
   2879 
   2880   // Wait for completion callback, and verify that the request ran as expected.
   2881   EXPECT_EQ(OK, callback1.WaitForResult());
   2882   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   2883 
   2884   // At this point we have initialized the proxy service using a PAC script.
   2885   //
   2886   // A background task to periodically re-check the PAC script for validity will
   2887   // have been started. We will now wait for the next download attempt to start.
   2888   //
   2889   // Note that we shouldn't have to wait long here, since our test enables a
   2890   // special unit-test mode.
   2891   fetcher->WaitUntilFetch();
   2892 
   2893   ASSERT_TRUE(resolver->pending_requests().empty());
   2894 
   2895   // Make sure that our background checker is trying to download the expected
   2896   // PAC script (same one as before). This time we will simulate a failure
   2897   // to download the script.
   2898   EXPECT_TRUE(fetcher->has_pending_request());
   2899   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   2900   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   2901 
   2902   base::MessageLoop::current()->RunUntilIdle();
   2903 
   2904   // At this point the ProxyService should have re-configured itself to use
   2905   // DIRECT connections rather than the given proxy resolver.
   2906 
   2907   // Start a second request.
   2908   ProxyInfo info2;
   2909   TestCompletionCallback callback2;
   2910   rv = service.ResolveProxy(
   2911       GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
   2912       NULL, NULL, BoundNetLog());
   2913   EXPECT_EQ(OK, rv);
   2914   EXPECT_TRUE(info2.is_direct());
   2915 }
   2916 
   2917 // Tests that the code which decides at what times to poll the PAC
   2918 // script follows the expected policy.
   2919 TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
   2920   // Retrieve the internal polling policy implementation used by ProxyService.
   2921   scoped_ptr<ProxyService::PacPollPolicy> policy =
   2922       ProxyService::CreateDefaultPacPollPolicy();
   2923 
   2924   int error;
   2925   ProxyService::PacPollPolicy::Mode mode;
   2926   const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
   2927   base::TimeDelta delay = initial_delay;
   2928 
   2929   // --------------------------------------------------
   2930   // Test the poll sequence in response to a failure.
   2931   // --------------------------------------------------
   2932   error = ERR_NAME_NOT_RESOLVED;
   2933 
   2934   // Poll #0
   2935   mode = policy->GetNextDelay(error, initial_delay, &delay);
   2936   EXPECT_EQ(8, delay.InSeconds());
   2937   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
   2938 
   2939   // Poll #1
   2940   mode = policy->GetNextDelay(error, delay, &delay);
   2941   EXPECT_EQ(32, delay.InSeconds());
   2942   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2943 
   2944   // Poll #2
   2945   mode = policy->GetNextDelay(error, delay, &delay);
   2946   EXPECT_EQ(120, delay.InSeconds());
   2947   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2948 
   2949   // Poll #3
   2950   mode = policy->GetNextDelay(error, delay, &delay);
   2951   EXPECT_EQ(14400, delay.InSeconds());
   2952   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2953 
   2954   // Poll #4
   2955   mode = policy->GetNextDelay(error, delay, &delay);
   2956   EXPECT_EQ(14400, delay.InSeconds());
   2957   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2958 
   2959   // --------------------------------------------------
   2960   // Test the poll sequence in response to a success.
   2961   // --------------------------------------------------
   2962   error = OK;
   2963 
   2964   // Poll #0
   2965   mode = policy->GetNextDelay(error, initial_delay, &delay);
   2966   EXPECT_EQ(43200, delay.InSeconds());
   2967   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2968 
   2969   // Poll #1
   2970   mode = policy->GetNextDelay(error, delay, &delay);
   2971   EXPECT_EQ(43200, delay.InSeconds());
   2972   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2973 
   2974   // Poll #2
   2975   mode = policy->GetNextDelay(error, delay, &delay);
   2976   EXPECT_EQ(43200, delay.InSeconds());
   2977   EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
   2978 }
   2979 
   2980 // This tests the polling of the PAC script. Specifically, it tests that
   2981 // polling occurs in response to user activity.
   2982 TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
   2983   ImmediateAfterActivityPollPolicy poll_policy;
   2984   ProxyService::set_pac_script_poll_policy(&poll_policy);
   2985 
   2986   MockProxyConfigService* config_service =
   2987       new MockProxyConfigService("http://foopy/proxy.pac");
   2988 
   2989   MockAsyncProxyResolverExpectsBytes* resolver =
   2990       new MockAsyncProxyResolverExpectsBytes;
   2991 
   2992   ProxyService service(config_service, resolver, NULL);
   2993 
   2994   MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
   2995   service.SetProxyScriptFetchers(fetcher,
   2996                                  new DoNothingDhcpProxyScriptFetcher());
   2997 
   2998   // Start 1 request.
   2999 
   3000   ProxyInfo info1;
   3001   TestCompletionCallback callback1;
   3002   int rv = service.ResolveProxy(
   3003       GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
   3004       NULL, NULL, BoundNetLog());
   3005   EXPECT_EQ(ERR_IO_PENDING, rv);
   3006 
   3007   // The first request should have triggered initial download of PAC script.
   3008   EXPECT_TRUE(fetcher->has_pending_request());
   3009   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   3010 
   3011   // Nothing has been sent to the resolver yet.
   3012   EXPECT_TRUE(resolver->pending_requests().empty());
   3013 
   3014   // At this point the ProxyService should be waiting for the
   3015   // ProxyScriptFetcher to invoke its completion callback, notifying it of
   3016   // PAC script download completion.
   3017   fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
   3018 
   3019   // Now that the PAC script is downloaded, the request will have been sent to
   3020   // the proxy resolver.
   3021   EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
   3022             resolver->pending_set_pac_script_request()->script_data()->utf16());
   3023   resolver->pending_set_pac_script_request()->CompleteNow(OK);
   3024 
   3025   ASSERT_EQ(1u, resolver->pending_requests().size());
   3026   EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
   3027 
   3028   // Complete the pending request.
   3029   resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
   3030   resolver->pending_requests()[0]->CompleteNow(OK);
   3031 
   3032   // Wait for completion callback, and verify that the request ran as expected.
   3033   EXPECT_EQ(OK, callback1.WaitForResult());
   3034   EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
   3035 
   3036   // At this point we have initialized the proxy service using a PAC script.
   3037   // Our PAC poller is set to update ONLY in response to network activity,
   3038   // (i.e. another call to ResolveProxy()).
   3039 
   3040   ASSERT_FALSE(fetcher->has_pending_request());
   3041   ASSERT_TRUE(resolver->pending_requests().empty());
   3042 
   3043   // Start a second request.
   3044   ProxyInfo info2;
   3045   TestCompletionCallback callback2;
   3046   rv = service.ResolveProxy(
   3047       GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
   3048       NULL, NULL, BoundNetLog());
   3049   EXPECT_EQ(ERR_IO_PENDING, rv);
   3050 
   3051   // This request should have sent work to the resolver; complete it.
   3052   ASSERT_EQ(1u, resolver->pending_requests().size());
   3053   EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
   3054   resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
   3055   resolver->pending_requests()[0]->CompleteNow(OK);
   3056 
   3057   EXPECT_EQ(OK, callback2.WaitForResult());
   3058   EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
   3059 
   3060   // In response to getting that resolve request, the poller should have
   3061   // started the next poll, and made it as far as to request the download.
   3062 
   3063   EXPECT_TRUE(fetcher->has_pending_request());
   3064   EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
   3065 
   3066   // This time we will fail the download, to simulate a PAC script change.
   3067   fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
   3068 
   3069   // Drain the message loop, so ProxyService is notified of the change
   3070   // and has a chance to re-configure itself.
   3071   base::MessageLoop::current()->RunUntilIdle();
   3072 
   3073   // Start a third request -- this time we expect to get a direct connection
   3074   // since the PAC script poller experienced a failure.
   3075   ProxyInfo info3;
   3076   TestCompletionCallback callback3;
   3077   rv = service.ResolveProxy(
   3078       GURL("http://request3"), net::LOAD_NORMAL, &info3, callback3.callback(),
   3079       NULL, NULL, BoundNetLog());
   3080   EXPECT_EQ(OK, rv);
   3081   EXPECT_TRUE(info3.is_direct());
   3082 }
   3083 
   3084 }  // namespace net
   3085