This source file includes following definitions.
- GetNextDelay
- GetNextDelay
- GetNextDelay
- SetUp
- TearDown
- config_
- config_
- AddObserver
- RemoveObserver
- GetLatestProxyConfig
- SetConfig
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#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/net_errors.h"
#include "net/base/net_log.h"
#include "net/base/net_log_unittest.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;
namespace net {
namespace {
class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
public:
ImmediatePollPolicy() {}
virtual 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);
};
class NeverPollPolicy : public ProxyService::PacPollPolicy {
public:
NeverPollPolicy() {}
virtual 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);
};
class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
public:
ImmediateAfterActivityPollPolicy() {}
virtual 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);
};
class ProxyServiceTest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE {
testing::Test::SetUp();
previous_policy_ =
ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
}
virtual void TearDown() OVERRIDE {
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))) {
}
virtual void AddObserver(Observer* observer) OVERRIDE {
observers_.AddObserver(observer);
}
virtual void RemoveObserver(Observer* observer) OVERRIDE {
observers_.RemoveObserver(observer);
}
virtual 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_;
};
}
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, &info, callback.callback(), 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());
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, 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, &info, callback.callback(), &request, 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());
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());
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_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, &info, callback.callback(), 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(GURL("http://www.google.com/?ref"),
resolver->pending_requests()[0]->url());
}
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, &info, callback1.callback(), 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("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());
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(
url, &info, callback2.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_FAILED, rv);
EXPECT_TRUE(info.is_empty());
}
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, &info, callback1.callback(), 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]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
EXPECT_EQ(OK, callback1.WaitForResult());
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());
}
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, &info, callback1.callback(), 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()->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());
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
TestCompletionCallback callback3;
rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(info.is_direct());
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
TestCompletionCallback callback5;
rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_FAILED, rv);
EXPECT_TRUE(info.is_empty());
}
TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
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);
GURL url("http://www.google.com/");
ProxyInfo info;
TestCompletionCallback callback;
int rv = service.ResolveProxy(
url, &info, callback.callback(), NULL, BoundNetLog());
ASSERT_EQ(ERR_IO_PENDING, rv);
resolver->pending_set_pac_script_request()->CompleteNow(OK);
ASSERT_EQ(1u, resolver->pending_requests().size());
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) {
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, &info, callback1.callback(), 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]->CompleteNow(ERR_FAILED);
EXPECT_EQ(OK, callback1.WaitForResult());
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());
TestCompletionCallback callback2;
rv = service.ResolveProxy(
url, &info, callback2.callback(), 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("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) {
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/");
ProxyInfo info;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
url, &info, callback1.callback(), 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());
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
TestCompletionCallback callback2;
rv = service.ResolveProxy(
url, &info, callback2.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
EXPECT_FALSE(info.is_direct());
}
TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
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);
GURL url("http://www.google.com/");
ProxyInfo info;
TestCompletionCallback callback;
int rv = service.ResolveProxy(
url, &info, callback.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
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());
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
callback.WaitForResult());
EXPECT_FALSE(info.is_direct());
}
TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
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/");
ProxyInfo info;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
url, &info, callback1.callback(), 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]->CompleteNow(ERR_FAILED);
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
TestCompletionCallback callback2;
rv = service.ResolveProxy(
url, &info, callback2.callback(), 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("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) {
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, &info, callback1.callback(), 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);
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();
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
service.ReportSuccess(info);
TestCompletionCallback callback3;
rv = service.ResolveProxy(
url, &info, callback3.callback(), 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(
"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());
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();
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
TestCompletionCallback callback5;
rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
TestCompletionCallback callback6;
rv = service.ReconsiderProxyAfterError(url, &info, callback6.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_FAILED, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_TRUE(info.is_empty());
EXPECT_EQ(proxy_resolve_start_time, info.proxy_resolve_start_time());
EXPECT_EQ(proxy_resolve_end_time, info.proxy_resolve_end_time());
TestCompletionCallback callback7;
rv = service.ResolveProxy(url, &info, callback7.callback(), 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;foopy3:7070;foopy2:9090;foopy4:9091");
resolver->pending_requests()[0]->CompleteNow(OK);
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());
}
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/");
ProxyInfo info;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
url, &info, callback1.callback(), 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()->UsePacString(
"PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
TestCompletionCallback callback3;
rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
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());
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_FAILED, rv);
}
TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
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, &info, callback1.callback(), 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);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
config_service->SetConfig(
ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), 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);
EXPECT_EQ(OK, callback2.WaitForResult());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
TestCompletionCallback callback3;
rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
config_service->SetConfig(
ProxyConfig::CreateFromCustomPacURL(
GURL("http://foopy-new2/proxy.pac")));
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), 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) {
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, &info, callback1.callback(), 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);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
ProxyInfo info2;
TestCompletionCallback callback3;
rv = service.ResolveProxy(
url, &info2, callback3.callback(), 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]->CompleteNow(ERR_FAILED);
EXPECT_EQ(OK, callback3.WaitForResult());
EXPECT_TRUE(info2.is_direct());
EXPECT_FALSE(info2.is_empty());
ProxyInfo info3;
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
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);
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) {
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/");
ProxyInfo info;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
url, &info, callback1.callback(), 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);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
TestCompletionCallback callback2;
rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
ProxyInfo info2;
TestCompletionCallback callback3;
rv = service.ResolveProxy(
url, &info2, callback3.callback(), 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]->CompleteNow(ERR_FAILED);
EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
callback3.WaitForResult());
EXPECT_FALSE(info2.is_direct());
EXPECT_TRUE(info2.is_empty());
ProxyInfo info3;
TestCompletionCallback callback4;
rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
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);
EXPECT_EQ(OK, callback4.WaitForResult());
EXPECT_FALSE(info3.is_direct());
EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
}
TEST_F(ProxyServiceTest, ProxyBypassList) {
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");
rv = service.ResolveProxy(
url1, &info[0], callback[0].callback(), NULL, BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(info[0].is_direct());
rv = service.ResolveProxy(
url2, &info[1], callback[1].callback(), 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, &info, callback.callback(), 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, &info, callback.callback(), 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, &info, callback.callback(), 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, &info, callback.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
}
}
TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
{
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, &info, callback.callback(), NULL,
BoundNetLog());
ASSERT_EQ(OK, rv);
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, &info, callback.callback(), NULL,
BoundNetLog());
ASSERT_EQ(OK, rv);
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, &info, callback.callback(), NULL,
BoundNetLog());
ASSERT_EQ(OK, rv);
EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
}
}
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, &info, callback.callback(), 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, &info, callback.callback(), 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, &info, callback.callback(), 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, &info, callback.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
}
}
TEST_F(ProxyServiceTest, CancelInProgressRequest) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
ProxyService service(config_service, resolver, NULL);
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
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"), &info2,
callback2.callback(), &request2, 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"), &info3,
callback3.callback(), 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());
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());
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);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
EXPECT_FALSE(callback2.have_result());
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_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());
ProxyInfo info1;
TestCompletionCallback callback1;
ProxyService::PacRequest* request1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), &request1, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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"), &info2,
callback2.callback(), &request2, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ProxyInfo info3;
TestCompletionCallback callback3;
ProxyService::PacRequest* request3;
rv = service.ResolveProxy(GURL("http://request3"), &info3,
callback3.callback(), &request3, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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));
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(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));
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);
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_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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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"), &info2,
callback2.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
fetcher = new MockProxyScriptFetcher;
service.SetProxyScriptFetchers(fetcher,
new DoNothingDhcpProxyScriptFetcher());
EXPECT_TRUE(resolver->pending_requests().empty());
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(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_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());
ProxyInfo info1;
TestCompletionCallback callback1;
ProxyService::PacRequest* request1;
CapturingBoundNetLog log1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), &request1, log1.bound());
EXPECT_EQ(ERR_IO_PENDING, rv);
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"), &info2,
callback2.callback(), &request2, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ProxyInfo info3;
TestCompletionCallback callback3;
rv = service.ResolveProxy(GURL("http://request3"), &info3,
callback3.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(resolver->pending_requests().empty());
service.CancelPacRequest(request1);
service.CancelPacRequest(request2);
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://request3"), resolver->pending_requests()[0]->url());
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());
EXPECT_FALSE(callback2.have_result());
CapturingNetLog::CapturedEntryList entries1;
log1.GetEntries(&entries1);
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));
EXPECT_TRUE(LogContainsEvent(
entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
EXPECT_TRUE(LogContainsEndEvent(
entries1, 3, NetLog::TYPE_PROXY_SERVICE));
}
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");
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ProxyInfo info2;
TestCompletionCallback callback2;
ProxyService::PacRequest* request2;
rv = service.ResolveProxy(GURL("http://request2"), &info2,
callback2.callback(), &request2, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
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);
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());
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);
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());
}
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");
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ProxyInfo info2;
TestCompletionCallback callback2;
ProxyService::PacRequest* request2;
rv = service.ResolveProxy(GURL("http://request2"), &info2,
callback2.callback(), &request2, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
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);
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());
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);
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_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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ProxyInfo info2;
TestCompletionCallback callback2;
ProxyService::PacRequest* request2;
rv = service.ResolveProxy(GURL("http://request2"), &info2,
callback2.callback(), &request2, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
ASSERT_EQ(0u, resolver->pending_requests().size());
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_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");
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://www.google.com"), &info1, callback1.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
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());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
callback2.callback(), 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());
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());
}
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
}
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, &info, callback.callback(), 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"), &info,
callback1.callback(), 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"), &info,
callback2.callback(), NULL, BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
}
TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
ProxyConfig config = ProxyConfig::CreateAutoDetect();
MockProxyConfigService* config_service = new MockProxyConfigService(config);
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
ProxyService service(config_service, resolver, NULL);
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(0u, resolver->pending_requests().size());
EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
resolver->pending_set_pac_script_request()->script_data()->type());
resolver->pending_set_pac_script_request()->CompleteNow(OK);
ASSERT_EQ(1u, resolver->pending_requests().size());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
config_service->SetConfig(ProxyConfig::CreateDirect());
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
callback2.callback(), 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());
service.set_stall_proxy_auto_config_delay(base::TimeDelta());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(GURL("http://request1"), &info1,
callback1.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
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://request1"), resolver->pending_requests()[0]->url());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
base::MessageLoop::current()->RunUntilIdle();
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(GURL("http://request2"), &info2,
callback2.callback(), NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
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());
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());
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);
}
TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://request1"), &info1, callback1.callback(),
NULL, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
fetcher->NotifyFetchCompletion(ERR_FAILED, std::string());
ASSERT_TRUE(resolver->pending_requests().empty());
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_TRUE(info1.is_direct());
fetcher->WaitUntilFetch();
ASSERT_TRUE(resolver->pending_requests().empty());
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();
EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
resolver->pending_set_pac_script_request()->script_data()->utf16());
resolver->pending_set_pac_script_request()->CompleteNow(OK);
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(
GURL("http://request2"), &info2, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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());
}
TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://request1"), &info1, callback1.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
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://request1"), resolver->pending_requests()[0]->url());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
fetcher->WaitUntilFetch();
ASSERT_TRUE(resolver->pending_requests().empty());
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();
EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
resolver->pending_set_pac_script_request()->script_data()->utf16());
resolver->pending_set_pac_script_request()->CompleteNow(OK);
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(
GURL("http://request2"), &info2, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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());
}
TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://request1"), &info1, callback1.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
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://request1"), resolver->pending_requests()[0]->url());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
fetcher->WaitUntilFetch();
ASSERT_TRUE(resolver->pending_requests().empty());
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());
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(
GURL("http://request2"), &info2, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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());
}
TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://request1"), &info1, callback1.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
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://request1"), resolver->pending_requests()[0]->url());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
fetcher->WaitUntilFetch();
ASSERT_TRUE(resolver->pending_requests().empty());
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();
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(
GURL("http://request2"), &info2, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(info2.is_direct());
}
TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
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;
error = ERR_NAME_NOT_RESOLVED;
mode = policy->GetNextDelay(error, initial_delay, &delay);
EXPECT_EQ(8, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(32, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(120, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(14400, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(14400, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
error = OK;
mode = policy->GetNextDelay(error, initial_delay, &delay);
EXPECT_EQ(43200, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(43200, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
mode = policy->GetNextDelay(error, delay, &delay);
EXPECT_EQ(43200, delay.InSeconds());
EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
}
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());
ProxyInfo info1;
TestCompletionCallback callback1;
int rv = service.ResolveProxy(
GURL("http://request1"), &info1, callback1.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
EXPECT_TRUE(fetcher->has_pending_request());
EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
EXPECT_TRUE(resolver->pending_requests().empty());
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://request1"), resolver->pending_requests()[0]->url());
resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
resolver->pending_requests()[0]->CompleteNow(OK);
EXPECT_EQ(OK, callback1.WaitForResult());
EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
ASSERT_FALSE(fetcher->has_pending_request());
ASSERT_TRUE(resolver->pending_requests().empty());
ProxyInfo info2;
TestCompletionCallback callback2;
rv = service.ResolveProxy(
GURL("http://request2"), &info2, callback2.callback(), NULL,
BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
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());
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();
ProxyInfo info3;
TestCompletionCallback callback3;
rv = service.ResolveProxy(
GURL("http://request3"), &info3, callback3.callback(), NULL,
BoundNetLog());
EXPECT_EQ(OK, rv);
EXPECT_TRUE(info3.is_direct());
}
}