Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(595)

Unified Diff: net/proxy/proxy_service_unittest.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/proxy/proxy_service.cc ('k') | net/proxy/proxy_service_v8.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/proxy_service_unittest.cc
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
deleted file mode 100644
index 84ce1010207699e6444ec9743d9e904eef5bf73d..0000000000000000000000000000000000000000
--- a/net/proxy/proxy_service_unittest.cc
+++ /dev/null
@@ -1,3138 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/proxy/proxy_service.h"
-
-#include <vector>
-
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/base/net_log_unittest.h"
-#include "net/base/network_delegate_impl.h"
-#include "net/base/test_completion_callback.h"
-#include "net/proxy/dhcp_proxy_script_fetcher.h"
-#include "net/proxy/mock_proxy_resolver.h"
-#include "net/proxy/mock_proxy_script_fetcher.h"
-#include "net/proxy/proxy_config_service.h"
-#include "net/proxy/proxy_resolver.h"
-#include "net/proxy/proxy_script_fetcher.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using base::ASCIIToUTF16;
-
-// TODO(eroman): Write a test which exercises
-// ProxyService::SuspendAllPendingRequests().
-namespace net {
-namespace {
-
-// This polling policy will decide to poll every 1 ms.
-class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
- public:
- ImmediatePollPolicy() {}
-
- Mode GetNextDelay(int error,
- base::TimeDelta current_delay,
- base::TimeDelta* next_delay) const override {
- *next_delay = base::TimeDelta::FromMilliseconds(1);
- return MODE_USE_TIMER;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
-};
-
-// This polling policy chooses a fantastically large delay. In other words, it
-// will never trigger a poll
-class NeverPollPolicy : public ProxyService::PacPollPolicy {
- public:
- NeverPollPolicy() {}
-
- Mode GetNextDelay(int error,
- base::TimeDelta current_delay,
- base::TimeDelta* next_delay) const override {
- *next_delay = base::TimeDelta::FromDays(60);
- return MODE_USE_TIMER;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
-};
-
-// This polling policy starts a poll immediately after network activity.
-class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
- public:
- ImmediateAfterActivityPollPolicy() {}
-
- Mode GetNextDelay(int error,
- base::TimeDelta current_delay,
- base::TimeDelta* next_delay) const override {
- *next_delay = base::TimeDelta();
- return MODE_START_AFTER_ACTIVITY;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
-};
-
-// This test fixture is used to partially disable the background polling done by
-// the ProxyService (which it uses to detect whenever its PAC script contents or
-// WPAD results have changed).
-//
-// We disable the feature by setting the poll interval to something really
-// large, so it will never actually be reached even on the slowest bots that run
-// these tests.
-//
-// We disable the polling in order to avoid any timing dependencies in the
-// tests. If the bot were to run the tests very slowly and we hadn't disabled
-// polling, then it might start a background re-try in the middle of our test
-// and confuse our expectations leading to flaky failures.
-//
-// The tests which verify the polling code re-enable the polling behavior but
-// are careful to avoid timing problems.
-class ProxyServiceTest : public testing::Test {
- protected:
- void SetUp() override {
- testing::Test::SetUp();
- previous_policy_ =
- ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
- }
-
- void TearDown() override {
- // Restore the original policy.
- ProxyService::set_pac_script_poll_policy(previous_policy_);
- testing::Test::TearDown();
- }
-
- private:
- NeverPollPolicy never_poll_policy_;
- const ProxyService::PacPollPolicy* previous_policy_;
-};
-
-const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
-const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";
-
-class MockProxyConfigService: public ProxyConfigService {
- public:
- explicit MockProxyConfigService(const ProxyConfig& config)
- : availability_(CONFIG_VALID),
- config_(config) {
- }
-
- explicit MockProxyConfigService(const std::string& pac_url)
- : availability_(CONFIG_VALID),
- config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
- }
-
- void AddObserver(Observer* observer) override {
- observers_.AddObserver(observer);
- }
-
- void RemoveObserver(Observer* observer) override {
- observers_.RemoveObserver(observer);
- }
-
- ConfigAvailability GetLatestProxyConfig(ProxyConfig* results) override {
- if (availability_ == CONFIG_VALID)
- *results = config_;
- return availability_;
- }
-
- void SetConfig(const ProxyConfig& config) {
- availability_ = CONFIG_VALID;
- config_ = config;
- FOR_EACH_OBSERVER(Observer, observers_,
- OnProxyConfigChanged(config_, availability_));
- }
-
- private:
- ConfigAvailability availability_;
- ProxyConfig config_;
- ObserverList<Observer, true> observers_;
-};
-
-// A test network delegate that exercises the OnResolveProxy callback.
-class TestResolveProxyNetworkDelegate : public NetworkDelegateImpl {
- public:
- TestResolveProxyNetworkDelegate()
- : on_resolve_proxy_called_(false),
- add_proxy_(false),
- remove_proxy_(false),
- proxy_service_(NULL) {
- }
-
- void OnResolveProxy(const GURL& url,
- int load_flags,
- const ProxyService& proxy_service,
- ProxyInfo* result) override {
- on_resolve_proxy_called_ = true;
- proxy_service_ = &proxy_service;
- DCHECK(!add_proxy_ || !remove_proxy_);
- if (add_proxy_) {
- result->UseNamedProxy("delegate_proxy.com");
- } else if (remove_proxy_) {
- result->UseDirect();
- }
- }
-
- bool on_resolve_proxy_called() const {
- return on_resolve_proxy_called_;
- }
-
- void set_add_proxy(bool add_proxy) {
- add_proxy_ = add_proxy;
- }
-
- void set_remove_proxy(bool remove_proxy) {
- remove_proxy_ = remove_proxy;
- }
-
- const ProxyService* proxy_service() const {
- return proxy_service_;
- }
-
- private:
- bool on_resolve_proxy_called_;
- bool add_proxy_;
- bool remove_proxy_;
- const ProxyService* proxy_service_;
-};
-
-// A test network delegate that exercises the OnProxyFallback callback.
-class TestProxyFallbackNetworkDelegate : public NetworkDelegateImpl {
- public:
- TestProxyFallbackNetworkDelegate()
- : on_proxy_fallback_called_(false),
- proxy_fallback_net_error_(OK) {
- }
-
- void OnProxyFallback(const ProxyServer& proxy_server,
- int net_error) override {
- proxy_server_ = proxy_server;
- proxy_fallback_net_error_ = net_error;
- on_proxy_fallback_called_ = true;
- }
-
- bool on_proxy_fallback_called() const {
- return on_proxy_fallback_called_;
- }
-
- const ProxyServer& proxy_server() const {
- return proxy_server_;
- }
-
- int proxy_fallback_net_error() const {
- return proxy_fallback_net_error_;
- }
-
- private:
- bool on_proxy_fallback_called_;
- ProxyServer proxy_server_;
- int proxy_fallback_net_error_;
-};
-
-} // namespace
-
-TEST_F(ProxyServiceTest, Direct) {
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
- ProxyService service(new MockProxyConfigService(
- ProxyConfig::CreateDirect()), resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- CapturingBoundNetLog log;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- log.bound());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- EXPECT_TRUE(info.is_direct());
- EXPECT_TRUE(info.proxy_resolve_start_time().is_null());
- EXPECT_TRUE(info.proxy_resolve_end_time().is_null());
-
- // Check the NetLog was filled correctly.
- CapturingNetLog::CapturedEntryList entries;
- log.GetEntries(&entries);
-
- EXPECT_EQ(3u, entries.size());
- EXPECT_TRUE(LogContainsBeginEvent(
- entries, 0, NetLog::TYPE_PROXY_SERVICE));
- EXPECT_TRUE(LogContainsEvent(
- entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
- NetLog::PHASE_NONE));
- EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLog::TYPE_PROXY_SERVICE));
-}
-
-TEST_F(ProxyServiceTest, OnResolveProxyCallbackAddProxy) {
- ProxyConfig config;
- config.proxy_rules().ParseFromString("foopy1:8080");
- config.set_auto_detect(false);
- config.proxy_rules().bypass_rules.ParseFromString("*.org");
-
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
-
- GURL url("http://www.google.com/");
- GURL bypass_url("http://internet.org");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- CapturingBoundNetLog log;
-
- // First, warm up the ProxyService.
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- log.bound());
- EXPECT_EQ(OK, rv);
-
- // Verify that network delegate is invoked.
- TestResolveProxyNetworkDelegate delegate;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
- log.bound());
- EXPECT_TRUE(delegate.on_resolve_proxy_called());
- EXPECT_EQ(&service, delegate.proxy_service());
-
- // Verify that the NetworkDelegate's behavior is stateless across
- // invocations of ResolveProxy. Start by having the callback add a proxy
- // and checking that subsequent requests are not affected.
- delegate.set_add_proxy(true);
-
- // Callback should interpose:
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
- log.bound());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ(info.proxy_server().host_port_pair().host(), "delegate_proxy.com");
- delegate.set_add_proxy(false);
-
- // Check non-bypassed URL:
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
- log.bound());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
-
- // Check bypassed URL:
- rv = service.ResolveProxy(
- bypass_url, net::LOAD_NORMAL, &info, callback.callback(), NULL,
- &delegate, log.bound());
- EXPECT_TRUE(info.is_direct());
-}
-
-TEST_F(ProxyServiceTest, OnResolveProxyCallbackRemoveProxy) {
- // Same as OnResolveProxyCallbackAddProxy, but verify that the
- // NetworkDelegate's behavior is stateless across invocations after it
- // *removes* a proxy.
- ProxyConfig config;
- config.proxy_rules().ParseFromString("foopy1:8080");
- config.set_auto_detect(false);
- config.proxy_rules().bypass_rules.ParseFromString("*.org");
-
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
-
- GURL url("http://www.google.com/");
- GURL bypass_url("http://internet.org");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- CapturingBoundNetLog log;
-
- // First, warm up the ProxyService.
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- log.bound());
- EXPECT_EQ(OK, rv);
-
- TestResolveProxyNetworkDelegate delegate;
- delegate.set_remove_proxy(true);
-
- // Callback should interpose:
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
- log.bound());
- EXPECT_TRUE(info.is_direct());
- delegate.set_remove_proxy(false);
-
- // Check non-bypassed URL:
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, &delegate,
- log.bound());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ(info.proxy_server().host_port_pair().host(), "foopy1");
-
- // Check bypassed URL:
- rv = service.ResolveProxy(
- bypass_url, net::LOAD_NORMAL, &info, callback.callback(), NULL,
- &delegate, log.bound());
- EXPECT_TRUE(info.is_direct());
-}
-
-TEST_F(ProxyServiceTest, PAC) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- ProxyService::PacRequest* request;
- CapturingBoundNetLog log;
-
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), &request, NULL,
- log.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request));
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
- EXPECT_TRUE(info.did_use_pac_script());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-
- // Check the NetLog was filled correctly.
- CapturingNetLog::CapturedEntryList entries;
- log.GetEntries(&entries);
-
- EXPECT_EQ(5u, entries.size());
- EXPECT_TRUE(LogContainsBeginEvent(
- entries, 0, NetLog::TYPE_PROXY_SERVICE));
- EXPECT_TRUE(LogContainsBeginEvent(
- entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
- EXPECT_TRUE(LogContainsEndEvent(
- entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
- EXPECT_TRUE(LogContainsEndEvent(
- entries, 4, NetLog::TYPE_PROXY_SERVICE));
-}
-
-// Test that the proxy resolver does not see the URL's username/password
-// or its reference section.
-TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://username:password@www.google.com/?ref#hash#hash");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- // The URL should have been simplified, stripping the username/password/hash.
- EXPECT_EQ(GURL("http://www.google.com/?ref"),
- resolver->pending_requests()[0]->url());
-
- // We end here without ever completing the request -- destruction of
- // ProxyService will cancel the outstanding request.
-}
-
-TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
- EXPECT_TRUE(info.did_use_pac_script());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-
- // Now, imagine that connecting to foopy:8080 fails: there is nothing
- // left to fallback to, since our proxy list was NOT terminated by
- // DIRECT.
- NetworkDelegateImpl network_delegate;
- TestCompletionCallback callback2;
- ProxyServer expected_proxy_server = info.proxy_server();
- rv = service.ReconsiderProxyAfterError(
- url, net::LOAD_NORMAL, net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL, &network_delegate, BoundNetLog());
- // ReconsiderProxyAfterError returns error indicating nothing left.
- EXPECT_EQ(ERR_FAILED, rv);
- EXPECT_TRUE(info.is_empty());
-}
-
-// Test that if the execution of the PAC script fails (i.e. javascript runtime
-// error), and the PAC settings are non-mandatory, that we fall-back to direct.
-TEST_F(ProxyServiceTest, PAC_RuntimeError) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://this-causes-js-error/");
-
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Simulate a failure in the PAC executor.
- resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
-
- EXPECT_EQ(OK, callback1.WaitForResult());
-
- // Since the PAC script was non-mandatory, we should have fallen-back to
- // DIRECT.
- EXPECT_TRUE(info.is_direct());
- EXPECT_TRUE(info.did_use_pac_script());
- EXPECT_EQ(1, info.config_id());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-}
-
-// The proxy list could potentially contain the DIRECT fallback choice
-// in a location other than the very end of the list, and could even
-// specify it multiple times.
-//
-// This is not a typical usage, but we will obey it.
-// (If we wanted to disallow this type of input, the right place to
-// enforce it would be in parsing the PAC result string).
-//
-// This test will use the PAC result string:
-//
-// "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
-//
-// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
-// then foobar:20, and then give up and error.
-//
-// The important check of this test is to make sure that DIRECT is not somehow
-// cached as being a bad proxy.
-TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UsePacString(
- "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_TRUE(info.is_direct());
-
- // Fallback 1.
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
-
- // Fallback 2.
- NetworkDelegateImpl network_delegate;
- ProxyServer expected_proxy_server3 = info.proxy_server();
- TestCompletionCallback callback3;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback3.callback(), NULL,
- &network_delegate, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
-
- // Fallback 3.
- ProxyServer expected_proxy_server4 = info.proxy_server();
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback4.callback(), NULL,
- &network_delegate, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
-
- // Fallback 4 -- Nothing to fall back to!
- ProxyServer expected_proxy_server5 = info.proxy_server();
- TestCompletionCallback callback5;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback5.callback(), NULL,
- &network_delegate, BoundNetLog());
- EXPECT_EQ(ERR_FAILED, rv);
- EXPECT_TRUE(info.is_empty());
-}
-
-TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
- // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
- // to ProxyInfo after the proxy is resolved via a PAC script.
- ProxyConfig config =
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
- ProxyService service(config_service, resolver, NULL);
-
- // Resolve something.
- GURL url("http://www.google.com/");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- BoundNetLog());
- ASSERT_EQ(ERR_IO_PENDING, rv);
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
- ASSERT_EQ(1u, resolver->pending_requests().size());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback.WaitForResult());
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
- EXPECT_TRUE(info.did_use_pac_script());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-}
-
-TEST_F(ProxyServiceTest, ProxyResolverFails) {
- // Test what happens when the ProxyResolver fails. The download and setting
- // of the PAC script have already succeeded, so this corresponds with a
- // javascript runtime error while calling FindProxyForURL().
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- // Start first resolve request.
- GURL url("http://www.google.com/");
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Fail the first resolve request in MockAsyncProxyResolver.
- resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
-
- // Although the proxy resolver failed the request, ProxyService implicitly
- // falls-back to DIRECT.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_TRUE(info.is_direct());
-
- // Failed PAC executions still have proxy resolution times.
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-
- // The second resolve request will try to run through the proxy resolver,
- // regardless of whether the first request failed in it.
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // This time we will have the resolver succeed (perhaps the PAC script has
- // a dependency on the current time).
- resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
-}
-
-TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
- // Test what happens when the ProxyScriptResolver fails to download a
- // mandatory PAC script.
-
- ProxyConfig config(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
- config.set_pac_mandatory(true);
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- // Start first resolve request.
- GURL url("http://www.google.com/");
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
-
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // As the proxy resolver failed the request and is configured for a mandatory
- // PAC script, ProxyService must not implicitly fall-back to DIRECT.
- EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
- callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
-
- // As the proxy resolver failed the request and is configured for a mandatory
- // PAC script, ProxyService must not implicitly fall-back to DIRECT.
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
- EXPECT_FALSE(info.is_direct());
-}
-
-TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
- // Test what happens when the ProxyResolver fails that is configured to use a
- // mandatory PAC script. The download of the PAC script has already
- // succeeded but the PAC script contains no valid javascript.
-
- ProxyConfig config(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
- config.set_pac_mandatory(true);
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
- service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);
-
- // Start resolve request.
- GURL url("http://www.google.com/");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // Downloading the PAC script succeeds.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
-
- EXPECT_FALSE(fetcher->has_pending_request());
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
- // mandatory for this configuration, the ProxyService must not implicitly
- // fall-back to DIRECT.
- EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
- callback.WaitForResult());
- EXPECT_FALSE(info.is_direct());
-}
-
-TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
- // Test what happens when the ProxyResolver fails that is configured to use a
- // mandatory PAC script. The download and setting of the PAC script have
- // already succeeded, so this corresponds with a javascript runtime error
- // while calling FindProxyForURL().
-
- ProxyConfig config(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
- config.set_pac_mandatory(true);
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- // Start first resolve request.
- GURL url("http://www.google.com/");
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Fail the first resolve request in MockAsyncProxyResolver.
- resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
-
- // As the proxy resolver failed the request and is configured for a mandatory
- // PAC script, ProxyService must not implicitly fall-back to DIRECT.
- EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
- callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
-
- // The second resolve request will try to run through the proxy resolver,
- // regardless of whether the first request failed in it.
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback2.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // This time we will have the resolver succeed (perhaps the PAC script has
- // a dependency on the current time).
- resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
-}
-
-TEST_F(ProxyServiceTest, ProxyFallback) {
- // Test what happens when we specify multiple proxy servers and some of them
- // are bad.
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- // Get the proxy information.
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first item is valid.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
- base::TimeTicks proxy_resolve_start_time = info.proxy_resolve_start_time();
- base::TimeTicks proxy_resolve_end_time = info.proxy_resolve_end_time();
-
- // Fake an error on the proxy.
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- // Proxy times should not have been modified by fallback.
- EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
- EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
-
- // The second proxy should be specified.
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
- // Report back that the second proxy worked. This will globally mark the
- // first proxy as bad.
- TestProxyFallbackNetworkDelegate test_delegate;
- service.ReportSuccess(info, &test_delegate);
- EXPECT_EQ("foopy1:8080", test_delegate.proxy_server().ToURI());
- EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED,
- test_delegate.proxy_fallback_net_error());
-
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback3.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver -- the second result is already known
- // to be bad, so we will not try to use it initially.
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy3:7070;foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
-
- // Proxy times should have been updated, so get them again.
- EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
- proxy_resolve_start_time = info.proxy_resolve_start_time();
- proxy_resolve_end_time = info.proxy_resolve_end_time();
-
- // We fake another error. It should now try the third one.
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback4.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
-
- // We fake another error. At this point we have tried all of the
- // proxy servers we thought were valid; next we try the proxy server
- // that was in our bad proxies map (foopy1:8080).
- TestCompletionCallback callback5;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback5.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // Fake another error, the last proxy is gone, the list should now be empty,
- // so there is nothing left to try.
- TestCompletionCallback callback6;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback6.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(ERR_FAILED, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_TRUE(info.is_empty());
-
- // Proxy times should not have been modified by fallback.
- EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
- EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
-
- // Look up proxies again
- TestCompletionCallback callback7;
- rv = service.ResolveProxy(url, net::LOAD_NORMAL, &info, callback7.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // This time, the first 3 results have been found to be bad, but only the
- // first proxy has been confirmed ...
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // ... therefore, we should see the second proxy first.
- EXPECT_EQ(OK, callback7.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
-
- EXPECT_LE(proxy_resolve_end_time, info.proxy_resolve_start_time());
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- // TODO(nsylvain): Test that the proxy can be retried after the delay.
-}
-
-// This test is similar to ProxyFallback, but this time we have an explicit
-// fallback choice to DIRECT.
-TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- // Get the proxy information.
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UsePacString(
- "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Get the first result.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // Fake an error on the proxy.
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- // Now we get back the second proxy.
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
-
- // Fake an error on this proxy as well.
- TestCompletionCallback callback3;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback3.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- // Finally, we get back DIRECT.
- EXPECT_TRUE(info.is_direct());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-
- // Now we tell the proxy service that even DIRECT failed.
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback4.callback(), NULL,
- NULL, BoundNetLog());
- // There was nothing left to try after DIRECT, so we are out of
- // choices.
- EXPECT_EQ(ERR_FAILED, rv);
-}
-
-TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
- // Test proxy failover when new settings are available.
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- // Get the proxy information.
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // Set the result in proxy resolver.
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first item is valid.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // Fake an error on the proxy, and also a new configuration on the proxy.
- config_service->SetConfig(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
-
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first proxy is still there since the configuration changed.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // We fake another error. It should now ignore the first one.
- TestCompletionCallback callback3;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback3.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
-
- // We simulate a new configuration.
- config_service->SetConfig(
- ProxyConfig::CreateFromCustomPacURL(
- GURL("http://foopy-new2/proxy.pac")));
-
- // We fake another error. It should go back to the first proxy.
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback4.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback4.WaitForResult());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-}
-
-TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
- // Test proxy failover when the configuration is bad.
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- // Get the proxy information.
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first item is valid.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // Fake a proxy error.
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- // The first proxy is ignored, and the second one is selected.
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
-
- // Fake a PAC failure.
- ProxyInfo info2;
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info2, callback3.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // This simulates a javascript runtime error in the PAC script.
- resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
-
- // Although the resolver failed, the ProxyService will implicitly fall-back
- // to a DIRECT connection.
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_TRUE(info2.is_direct());
- EXPECT_FALSE(info2.is_empty());
-
- // The PAC script will work properly next time and successfully return a
- // proxy list. Since we have not marked the configuration as bad, it should
- // "just work" the next time we call it.
- ProxyInfo info3;
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info3, callback4.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first proxy is not there since the it was added to the bad proxies
- // list by the earlier ReconsiderProxyAfterError().
- EXPECT_EQ(OK, callback4.WaitForResult());
- EXPECT_FALSE(info3.is_direct());
- EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
-
- EXPECT_FALSE(info.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info.proxy_resolve_end_time().is_null());
- EXPECT_LE(info.proxy_resolve_start_time(), info.proxy_resolve_end_time());
-}
-
-TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
- // Test proxy failover when the configuration is bad.
-
- ProxyConfig config(
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
-
- config.set_pac_mandatory(true);
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- // Get the proxy information.
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first item is valid.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- // Fake a proxy error.
- TestCompletionCallback callback2;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info, callback2.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- // The first proxy is ignored, and the second one is selected.
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
-
- // Fake a PAC failure.
- ProxyInfo info2;
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info2, callback3.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- // This simulates a javascript runtime error in the PAC script.
- resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
-
- // Although the resolver failed, the ProxyService will NOT fall-back
- // to a DIRECT connection as it is configured as mandatory.
- EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
- callback3.WaitForResult());
- EXPECT_FALSE(info2.is_direct());
- EXPECT_TRUE(info2.is_empty());
-
- // The PAC script will work properly next time and successfully return a
- // proxy list. Since we have not marked the configuration as bad, it should
- // "just work" the next time we call it.
- ProxyInfo info3;
- TestCompletionCallback callback4;
- rv = service.ReconsiderProxyAfterError(url, net::LOAD_NORMAL,
- net::ERR_PROXY_CONNECTION_FAILED,
- &info3, callback4.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(url, resolver->pending_requests()[0]->url());
-
- resolver->pending_requests()[0]->results()->UseNamedProxy(
- "foopy1:8080;foopy2:9090");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // The first proxy is not there since the it was added to the bad proxies
- // list by the earlier ReconsiderProxyAfterError().
- EXPECT_EQ(OK, callback4.WaitForResult());
- EXPECT_FALSE(info3.is_direct());
- EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
-}
-
-TEST_F(ProxyServiceTest, ProxyBypassList) {
- // Test that the proxy bypass rules are consulted.
-
- TestCompletionCallback callback[2];
- ProxyInfo info[2];
- ProxyConfig config;
- config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
- config.set_auto_detect(false);
- config.proxy_rules().bypass_rules.ParseFromString("*.org");
-
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
-
- int rv;
- GURL url1("http://www.webkit.org");
- GURL url2("http://www.webkit.com");
-
- // Request for a .org domain should bypass proxy.
- rv = service.ResolveProxy(
- url1, net::LOAD_NORMAL, &info[0], callback[0].callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info[0].is_direct());
-
- // Request for a .com domain hits the proxy.
- rv = service.ResolveProxy(
- url2, net::LOAD_NORMAL, &info[1], callback[1].callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
-}
-
-
-TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
- ProxyConfig config;
- config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
- config.set_auto_detect(false);
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("http://www.msn.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
- }
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("ftp://ftp.google.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- EXPECT_EQ("direct://", info.proxy_server().ToURI());
- }
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("https://webbranch.techcu.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
- }
- {
- config.proxy_rules().ParseFromString("foopy1:8080");
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("http://www.microsoft.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
- }
-}
-
-TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
- // Test that the proxy config source is set correctly when resolving proxies
- // using manual proxy rules. Namely, the config source should only be set if
- // any of the rules were applied.
- {
- ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
- config.proxy_rules().ParseFromString("https=foopy2:8080");
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("http://www.google.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- ASSERT_EQ(OK, rv);
- // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
- }
- {
- ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
- config.proxy_rules().ParseFromString("https=foopy2:8080");
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("https://www.google.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- ASSERT_EQ(OK, rv);
- // Used the HTTPS proxy. So source should be TEST.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
- }
- {
- ProxyConfig config;
- config.set_source(PROXY_CONFIG_SOURCE_TEST);
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("http://www.google.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- ASSERT_EQ(OK, rv);
- // ProxyConfig is empty. Source should still be TEST.
- EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
- }
-}
-
-// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
-// fall back to the SOCKS proxy.
-TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
- ProxyConfig config;
- config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
- config.set_auto_detect(false);
- EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
- config.proxy_rules().type);
-
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("http://www.msn.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
- }
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("ftp://ftp.google.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
- }
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("https://webbranch.techcu.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
- }
- {
- ProxyService service(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
- GURL test_url("unknown://www.microsoft.com");
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(test_url, net::LOAD_NORMAL, &info,
- callback.callback(), NULL,
- NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
- }
-}
-
-// Test cancellation of an in-progress request.
-TEST_F(ProxyServiceTest, CancelInProgressRequest) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- // Start 3 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Nothing has been sent to the proxy resolver yet, since the proxy
- // resolver has not been configured yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // Successfully initialize the PAC script.
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- ASSERT_EQ(2u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
-
- ProxyInfo info3;
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
- callback3.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- ASSERT_EQ(3u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
-
- // Cancel the second request
- service.CancelPacRequest(request2);
-
- ASSERT_EQ(2u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
- EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
-
- // Complete the two un-cancelled requests.
- // We complete the last one first, just to mix it up a bit.
- resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
- resolver->pending_requests()[1]->CompleteNow(OK);
-
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Complete and verify that requests ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- EXPECT_FALSE(callback2.have_result()); // Cancelled.
- ASSERT_EQ(1u, resolver->cancelled_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
-
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
-}
-
-// Test the initial PAC download for resolver that expects bytes.
-TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 3 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- ProxyService::PacRequest* request1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), &request1, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyInfo info3;
- TestCompletionCallback callback3;
- ProxyService::PacRequest* request3;
- rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
- callback3.callback(), &request3, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request1));
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request2));
- EXPECT_EQ(LOAD_STATE_DOWNLOADING_PROXY_SCRIPT,
- service.GetLoadState(request3));
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, it will have been sent to the proxy
- // resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(3u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
- EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
-
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request1));
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request2));
- EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, service.GetLoadState(request3));
-
- // Complete all the requests (in some order).
- // Note that as we complete requests, they shift up in |pending_requests()|.
-
- resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
- resolver->pending_requests()[2]->CompleteNow(OK);
-
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Complete and verify that requests ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
- EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
- EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
- EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
- EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
-
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
- EXPECT_FALSE(info3.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info3.proxy_resolve_end_time().is_null());
- EXPECT_LE(info3.proxy_resolve_start_time(), info3.proxy_resolve_end_time());
-}
-
-// Test changing the ProxyScriptFetcher while PAC download is in progress.
-TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 2 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
-
- // We now change out the ProxyService's script fetcher. We should restart
- // the initialization with the new fetcher.
-
- fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, it will have been sent to the proxy
- // resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(2u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
-}
-
-// Test cancellation of a request, while the PAC script is being fetched.
-TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 3 requests.
- ProxyInfo info1;
- TestCompletionCallback callback1;
- ProxyService::PacRequest* request1;
- CapturingBoundNetLog log1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), &request1, NULL,
- log1.bound());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyInfo info3;
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
- callback3.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // Cancel the first 2 requests.
- service.CancelPacRequest(request1);
- service.CancelPacRequest(request2);
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, it will have been sent to the
- // proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
-
- // Complete all the requests.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
-
- EXPECT_TRUE(resolver->cancelled_requests().empty());
-
- EXPECT_FALSE(callback1.have_result()); // Cancelled.
- EXPECT_FALSE(callback2.have_result()); // Cancelled.
-
- CapturingNetLog::CapturedEntryList entries1;
- log1.GetEntries(&entries1);
-
- // Check the NetLog for request 1 (which was cancelled) got filled properly.
- EXPECT_EQ(4u, entries1.size());
- EXPECT_TRUE(LogContainsBeginEvent(
- entries1, 0, NetLog::TYPE_PROXY_SERVICE));
- EXPECT_TRUE(LogContainsBeginEvent(
- entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
- // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
- // the cancellation occured.
- EXPECT_TRUE(LogContainsEvent(
- entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
- EXPECT_TRUE(LogContainsEndEvent(
- entries1, 3, NetLog::TYPE_PROXY_SERVICE));
-}
-
-// Test that if auto-detect fails, we fall-back to the custom pac.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
- ProxyConfig config;
- config.set_auto_detect(true);
- config.set_pac_url(GURL("http://foopy/proxy.pac"));
- config.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 2 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // It should be trying to auto-detect first -- FAIL the autodetect during
- // the script download.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- // Next it should be trying the custom PAC url.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- // Now finally, the pending requests should have been sent to the resolver
- // (which was initialized with custom PAC script).
-
- ASSERT_EQ(2u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
-
- // Complete the pending requests.
- resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[1]->CompleteNow(OK);
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Verify that requests ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
- EXPECT_FALSE(info1.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info1.proxy_resolve_end_time().is_null());
- EXPECT_LE(info1.proxy_resolve_start_time(), info1.proxy_resolve_end_time());
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
- EXPECT_FALSE(info2.proxy_resolve_start_time().is_null());
- EXPECT_FALSE(info2.proxy_resolve_end_time().is_null());
- EXPECT_LE(info2.proxy_resolve_start_time(), info2.proxy_resolve_end_time());
-}
-
-// This is the same test as FallbackFromAutodetectToCustomPac, except
-// the auto-detect script fails parsing rather than downloading.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
- ProxyConfig config;
- config.set_auto_detect(true);
- config.set_pac_url(GURL("http://foopy/proxy.pac"));
- config.proxy_rules().ParseFromString("http=foopy:80"); // Won't be used.
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 2 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // It should be trying to auto-detect first -- succeed the download.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
-
- // The script contents passed failed basic verification step (since didn't
- // contain token FindProxyForURL), so it was never passed to the resolver.
-
- // Next it should be trying the custom PAC url.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- // Now finally, the pending requests should have been sent to the resolver
- // (which was initialized with custom PAC script).
-
- ASSERT_EQ(2u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
-
- // Complete the pending requests.
- resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[1]->CompleteNow(OK);
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Verify that requests ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-}
-
-// Test that if all of auto-detect, a custom PAC script, and manual settings
-// are given, then we will try them in that order.
-TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
- ProxyConfig config;
- config.set_auto_detect(true);
- config.set_pac_url(GURL("http://foopy/proxy.pac"));
- config.proxy_rules().ParseFromString("http=foopy:80");
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 2 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ProxyInfo info2;
- TestCompletionCallback callback2;
- ProxyService::PacRequest* request2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), &request2, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // It should be trying to auto-detect first -- fail the download.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- // Next it should be trying the custom PAC url -- fail the download.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- // Since we never managed to initialize a ProxyResolver, nothing should have
- // been sent to it.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // Verify that requests ran as expected -- they should have fallen back to
- // the manual proxy configuration for HTTP urls.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
-}
-
-// Test that the bypass rules are NOT applied when using autodetect.
-TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
- ProxyConfig config;
- config.set_auto_detect(true);
- config.set_pac_url(GURL("http://foopy/proxy.pac"));
- config.proxy_rules().ParseFromString("http=foopy:80"); // Not used.
- config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 requests.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://www.google.com"), net::LOAD_NORMAL, &info1,
- callback1.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // It should be trying to auto-detect first -- succeed the download.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://www.google.com"),
- resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Verify that request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // Start another request, it should pickup the bypass item.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
- &info2, callback2.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://www.google.com"),
- resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-}
-
-// Delete the ProxyService while InitProxyResolver has an outstanding
-// request to the script fetcher. When run under valgrind, should not
-// have any memory errors (used to be that the ProxyScriptFetcher was
-// being deleted prior to the InitProxyResolver).
-TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
- ProxyConfig config =
- ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // InitProxyResolver should have issued a request to the ProxyScriptFetcher
- // and be waiting on that to complete.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-}
-
-// Delete the ProxyService while InitProxyResolver has an outstanding
-// request to the proxy resolver. When run under valgrind, should not
-// have any memory errors (used to be that the ProxyResolver was
-// being deleted prior to the InitProxyResolver).
-TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- TestCompletionCallback callback;
- int rv = service.ResolveProxy(
- url, net::LOAD_NORMAL, &info, callback.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- EXPECT_EQ(GURL("http://foopy/proxy.pac"),
- resolver->pending_set_pac_script_request()->script_data()->url());
-}
-
-TEST_F(ProxyServiceTest, ResetProxyConfigService) {
- ProxyConfig config1;
- config1.proxy_rules().ParseFromString("foopy1:8080");
- config1.set_auto_detect(false);
- ProxyService service(
- new MockProxyConfigService(config1),
- new MockAsyncProxyResolverExpectsBytes, NULL);
-
- ProxyInfo info;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
-
- ProxyConfig config2;
- config2.proxy_rules().ParseFromString("foopy2:8080");
- config2.set_auto_detect(false);
- service.ResetConfigService(new MockProxyConfigService(config2));
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info,
- callback2.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
-}
-
-// Test that when going from a configuration that required PAC to one
-// that does NOT, we unset the variable |should_use_proxy_resolver_|.
-TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
- ProxyConfig config = ProxyConfig::CreateAutoDetect();
-
- MockProxyConfigService* config_service = new MockProxyConfigService(config);
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
- ProxyService service(config_service, resolver, NULL);
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that nothing has been sent to the proxy resolver yet.
- ASSERT_EQ(0u, resolver->pending_requests().size());
-
- // Successfully set the autodetect script.
- EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
- resolver->pending_set_pac_script_request()->script_data()->type());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- // Complete the pending request.
- ASSERT_EQ(1u, resolver->pending_requests().size());
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Verify that request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // Force the ProxyService to pull down a new proxy configuration.
- // (Even though the configuration isn't old/bad).
- //
- // This new configuration no longer has auto_detect set, so
- // requests should complete synchronously now as direct-connect.
- config_service->SetConfig(ProxyConfig::CreateDirect());
-
- // Start another request -- the effective configuration has changed.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(GURL("http://www.google.com"), net::LOAD_NORMAL,
- &info2, callback2.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(OK, rv);
-
- EXPECT_TRUE(info2.is_direct());
-}
-
-TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- CapturingNetLog log;
-
- ProxyService service(config_service, resolver, &log);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Disable the "wait after IP address changes" hack, so this unit-test can
- // complete quickly.
- service.set_stall_proxy_auto_config_delay(base::TimeDelta());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL,
- &info1, callback1.callback(), NULL, NULL,
- BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, the request will have been sent to
- // the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // Now simluate a change in the network. The ProxyConfigService is still
- // going to return the same PAC URL as before, but this URL needs to be
- // refetched on the new network.
- NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
- base::MessageLoop::current()->RunUntilIdle(); // Notification happens async.
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
- callback2.callback(), NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // This second request should have triggered the re-download of the PAC
- // script (since we marked the network as having changed).
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // Simulate the PAC script fetch as having completed (this time with
- // different data).
- fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
-
- // Now that the PAC script is downloaded, the second request will have been
- // sent to the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
-
- // Complete the pending second request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-
- // Check that the expected events were output to the log stream. In particular
- // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
- // setup), and NOT a second time when the IP address changed.
- CapturingNetLog::CapturedEntryList entries;
- log.GetEntries(&entries);
-
- EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
- NetLog::TYPE_PROXY_CONFIG_CHANGED));
- ASSERT_EQ(9u, entries.size());
- for (size_t i = 1; i < entries.size(); ++i)
- EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
-}
-
-// This test verifies that the PAC script specified by the settings is
-// periodically polled for changes. Specifically, if the initial fetch fails due
-// to a network error, we will eventually re-configure the service to use the
-// script once it becomes available.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
- // Change the retry policy to wait a mere 1 ms before retrying, so the test
- // runs quickly.
- ImmediatePollPolicy poll_policy;
- ProxyService::set_pac_script_poll_policy(&poll_policy);
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- //
- // We simulate a failed download attempt, the proxy service should now
- // fall-back to DIRECT connections.
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Wait for completion callback, and verify it used DIRECT.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_TRUE(info1.is_direct());
-
- // At this point we have initialized the proxy service using a PAC script,
- // however it failed and fell-back to DIRECT.
- //
- // A background task to periodically re-check the PAC script for validity will
- // have been started. We will now wait for the next download attempt to start.
- //
- // Note that we shouldn't have to wait long here, since our test enables a
- // special unit-test mode.
- fetcher->WaitUntilFetch();
-
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Make sure that our background checker is trying to download the expected
- // PAC script (same one as before). This time we will simulate a successful
- // download of the script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- base::MessageLoop::current()->RunUntilIdle();
-
- // Now that the PAC script is downloaded, it should be used to initialize the
- // ProxyResolver. Simulate a successful parse.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- // At this point the ProxyService should have re-configured itself to use the
- // PAC script (thereby recovering from the initial fetch failure). We will
- // verify that the next Resolve request uses the resolver rather than
- // DIRECT.
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that it was sent to the resolver.
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
-
- // Complete the pending second request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-}
-
-// This test verifies that the PAC script specified by the settings is
-// periodically polled for changes. Specifically, if the initial fetch succeeds,
-// however at a later time its *contents* change, we will eventually
-// re-configure the service to use the new script.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
- // Change the retry policy to wait a mere 1 ms before retrying, so the test
- // runs quickly.
- ImmediatePollPolicy poll_policy;
- ProxyService::set_pac_script_poll_policy(&poll_policy);
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, the request will have been sent to
- // the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // At this point we have initialized the proxy service using a PAC script.
- //
- // A background task to periodically re-check the PAC script for validity will
- // have been started. We will now wait for the next download attempt to start.
- //
- // Note that we shouldn't have to wait long here, since our test enables a
- // special unit-test mode.
- fetcher->WaitUntilFetch();
-
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Make sure that our background checker is trying to download the expected
- // PAC script (same one as before). This time we will simulate a successful
- // download of a DIFFERENT script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
-
- base::MessageLoop::current()->RunUntilIdle();
-
- // Now that the PAC script is downloaded, it should be used to initialize the
- // ProxyResolver. Simulate a successful parse.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- // At this point the ProxyService should have re-configured itself to use the
- // new PAC script.
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that it was sent to the resolver.
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
-
- // Complete the pending second request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-}
-
-// This test verifies that the PAC script specified by the settings is
-// periodically polled for changes. Specifically, if the initial fetch succeeds
-// and so does the next poll, however the contents of the downloaded script
-// have NOT changed, then we do not bother to re-initialize the proxy resolver.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
- // Change the retry policy to wait a mere 1 ms before retrying, so the test
- // runs quickly.
- ImmediatePollPolicy poll_policy;
- ProxyService::set_pac_script_poll_policy(&poll_policy);
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, the request will have been sent to
- // the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // At this point we have initialized the proxy service using a PAC script.
- //
- // A background task to periodically re-check the PAC script for validity will
- // have been started. We will now wait for the next download attempt to start.
- //
- // Note that we shouldn't have to wait long here, since our test enables a
- // special unit-test mode.
- fetcher->WaitUntilFetch();
-
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Make sure that our background checker is trying to download the expected
- // PAC script (same one as before). We will simulate the same response as
- // last time (i.e. the script is unchanged).
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- base::MessageLoop::current()->RunUntilIdle();
-
- ASSERT_FALSE(resolver->has_pending_set_pac_script_request());
-
- // At this point the ProxyService is still running the same PAC script as
- // before.
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // Check that it was sent to the resolver.
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
-
- // Complete the pending second request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-}
-
-// This test verifies that the PAC script specified by the settings is
-// periodically polled for changes. Specifically, if the initial fetch succeeds,
-// however at a later time it starts to fail, we should re-configure the
-// ProxyService to stop using that PAC script.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
- // Change the retry policy to wait a mere 1 ms before retrying, so the test
- // runs quickly.
- ImmediatePollPolicy poll_policy;
- ProxyService::set_pac_script_poll_policy(&poll_policy);
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, the request will have been sent to
- // the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // At this point we have initialized the proxy service using a PAC script.
- //
- // A background task to periodically re-check the PAC script for validity will
- // have been started. We will now wait for the next download attempt to start.
- //
- // Note that we shouldn't have to wait long here, since our test enables a
- // special unit-test mode.
- fetcher->WaitUntilFetch();
-
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Make sure that our background checker is trying to download the expected
- // PAC script (same one as before). This time we will simulate a failure
- // to download the script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- base::MessageLoop::current()->RunUntilIdle();
-
- // At this point the ProxyService should have re-configured itself to use
- // DIRECT connections rather than the given proxy resolver.
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info2.is_direct());
-}
-
-// Tests that the code which decides at what times to poll the PAC
-// script follows the expected policy.
-TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
- // Retrieve the internal polling policy implementation used by ProxyService.
- scoped_ptr<ProxyService::PacPollPolicy> policy =
- ProxyService::CreateDefaultPacPollPolicy();
-
- int error;
- ProxyService::PacPollPolicy::Mode mode;
- const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
- base::TimeDelta delay = initial_delay;
-
- // --------------------------------------------------
- // Test the poll sequence in response to a failure.
- // --------------------------------------------------
- error = ERR_NAME_NOT_RESOLVED;
-
- // Poll #0
- mode = policy->GetNextDelay(error, initial_delay, &delay);
- EXPECT_EQ(8, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
-
- // Poll #1
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(32, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // Poll #2
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(120, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // Poll #3
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(14400, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // Poll #4
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(14400, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // --------------------------------------------------
- // Test the poll sequence in response to a success.
- // --------------------------------------------------
- error = OK;
-
- // Poll #0
- mode = policy->GetNextDelay(error, initial_delay, &delay);
- EXPECT_EQ(43200, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // Poll #1
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(43200, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-
- // Poll #2
- mode = policy->GetNextDelay(error, delay, &delay);
- EXPECT_EQ(43200, delay.InSeconds());
- EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
-}
-
-// This tests the polling of the PAC script. Specifically, it tests that
-// polling occurs in response to user activity.
-TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
- ImmediateAfterActivityPollPolicy poll_policy;
- ProxyService::set_pac_script_poll_policy(&poll_policy);
-
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolverExpectsBytes* resolver =
- new MockAsyncProxyResolverExpectsBytes;
-
- ProxyService service(config_service, resolver, NULL);
-
- MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
- service.SetProxyScriptFetchers(fetcher,
- new DoNothingDhcpProxyScriptFetcher());
-
- // Start 1 request.
-
- ProxyInfo info1;
- TestCompletionCallback callback1;
- int rv = service.ResolveProxy(
- GURL("http://request1"), net::LOAD_NORMAL, &info1, callback1.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // The first request should have triggered initial download of PAC script.
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // Nothing has been sent to the resolver yet.
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // At this point the ProxyService should be waiting for the
- // ProxyScriptFetcher to invoke its completion callback, notifying it of
- // PAC script download completion.
- fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
-
- // Now that the PAC script is downloaded, the request will have been sent to
- // the proxy resolver.
- EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
- resolver->pending_set_pac_script_request()->script_data()->utf16());
- resolver->pending_set_pac_script_request()->CompleteNow(OK);
-
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
-
- // Complete the pending request.
- resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- // Wait for completion callback, and verify that the request ran as expected.
- EXPECT_EQ(OK, callback1.WaitForResult());
- EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
-
- // At this point we have initialized the proxy service using a PAC script.
- // Our PAC poller is set to update ONLY in response to network activity,
- // (i.e. another call to ResolveProxy()).
-
- ASSERT_FALSE(fetcher->has_pending_request());
- ASSERT_TRUE(resolver->pending_requests().empty());
-
- // Start a second request.
- ProxyInfo info2;
- TestCompletionCallback callback2;
- rv = service.ResolveProxy(
- GURL("http://request2"), net::LOAD_NORMAL, &info2, callback2.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- // This request should have sent work to the resolver; complete it.
- ASSERT_EQ(1u, resolver->pending_requests().size());
- EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
- resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
- resolver->pending_requests()[0]->CompleteNow(OK);
-
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
-
- // In response to getting that resolve request, the poller should have
- // started the next poll, and made it as far as to request the download.
-
- EXPECT_TRUE(fetcher->has_pending_request());
- EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
-
- // This time we will fail the download, to simulate a PAC script change.
- fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
-
- // Drain the message loop, so ProxyService is notified of the change
- // and has a chance to re-configure itself.
- base::MessageLoop::current()->RunUntilIdle();
-
- // Start a third request -- this time we expect to get a direct connection
- // since the PAC script poller experienced a failure.
- ProxyInfo info3;
- TestCompletionCallback callback3;
- rv = service.ResolveProxy(
- GURL("http://request3"), net::LOAD_NORMAL, &info3, callback3.callback(),
- NULL, NULL, BoundNetLog());
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info3.is_direct());
-}
-
-// Test that the synchronous resolution fails when a PAC script is active.
-TEST_F(ProxyServiceTest, SynchronousWithPAC) {
- MockProxyConfigService* config_service =
- new MockProxyConfigService("http://foopy/proxy.pac");
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver();
-
- ProxyService service(config_service, resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- info.UseDirect();
- CapturingBoundNetLog log;
-
- bool synchronous_success = service.TryResolveProxySynchronously(
- url, net::LOAD_NORMAL, &info, NULL, log.bound());
- EXPECT_FALSE(synchronous_success);
-
- // No request should have been queued.
- EXPECT_EQ(0u, resolver->pending_requests().size());
-
- // |info| should not have been modified.
- EXPECT_TRUE(info.is_direct());
-}
-
-// Test that synchronous results are returned correctly if a fixed proxy
-// configuration is active.
-TEST_F(ProxyServiceTest, SynchronousWithFixedConfiguration) {
- ProxyConfig config;
- config.proxy_rules().ParseFromString("foopy1:8080");
- config.set_auto_detect(false);
-
- MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver();
-
- ProxyService service(new MockProxyConfigService(config), resolver, NULL);
-
- GURL url("http://www.google.com/");
-
- ProxyInfo info;
- CapturingBoundNetLog log;
-
- bool synchronous_success = service.TryResolveProxySynchronously(
- url, net::LOAD_NORMAL, &info, NULL, log.bound());
- EXPECT_TRUE(synchronous_success);
- EXPECT_FALSE(info.is_direct());
- EXPECT_EQ("foopy1", info.proxy_server().host_port_pair().host());
-
- // No request should have been queued.
- EXPECT_EQ(0u, resolver->pending_requests().size());
-}
-
-} // namespace net
« no previous file with comments | « net/proxy/proxy_service.cc ('k') | net/proxy/proxy_service_v8.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698