diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-06 09:31:56 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-06 09:31:56 +0000 |
commit | 1df57a559a81831936cf531976f7ad4609840e23 (patch) | |
tree | 1c27084cbbee0e96dae88273d28121028f526c4f /net/proxy | |
parent | a8e64523fca941d1f0bd1806e6b567fb0b62ed8a (diff) | |
download | chromium_src-1df57a559a81831936cf531976f7ad4609840e23.zip chromium_src-1df57a559a81831936cf531976f7ad4609840e23.tar.gz chromium_src-1df57a559a81831936cf531976f7ad4609840e23.tar.bz2 |
Implemented unit tests for ProxyService and fixed a bug
BUG=81368
TEST=execute net_unittests --gtest_filter='ProxyServiceTest.*'
Review URL: http://codereview.chromium.org/6932041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84422 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy')
-rw-r--r-- | net/proxy/init_proxy_resolver.cc | 6 | ||||
-rw-r--r-- | net/proxy/init_proxy_resolver.h | 6 | ||||
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 237 |
3 files changed, 247 insertions, 2 deletions
diff --git a/net/proxy/init_proxy_resolver.cc b/net/proxy/init_proxy_resolver.cc index 9091168..d9d55ea 100644 --- a/net/proxy/init_proxy_resolver.cc +++ b/net/proxy/init_proxy_resolver.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -39,6 +39,7 @@ InitProxyResolver::InitProxyResolver(ProxyResolver* resolver, this, &InitProxyResolver::OnIOCompletion)), user_callback_(NULL), current_pac_url_index_(0u), + pac_mandatory_(false), next_state_(STATE_NONE), net_log_(BoundNetLog::Make( net_log, NetLog::SOURCE_INIT_PROXY_RESOLVER)), @@ -67,6 +68,8 @@ int InitProxyResolver::Init(const ProxyConfig& config, effective_config_ = effective_config; + pac_mandatory_ = config.pac_mandatory(); + pac_urls_ = BuildPacUrlsFallbackList(config); DCHECK(!pac_urls_.empty()); @@ -243,6 +246,7 @@ int InitProxyResolver::DoSetPacScriptComplete(int result) { } else { *effective_config_ = ProxyConfig::CreateFromCustomPacURL(current_pac_url().url); + effective_config_->set_pac_mandatory(pac_mandatory_); } } diff --git a/net/proxy/init_proxy_resolver.h b/net/proxy/init_proxy_resolver.h index fd656427..67cf1cb 100644 --- a/net/proxy/init_proxy_resolver.h +++ b/net/proxy/init_proxy_resolver.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -126,6 +126,10 @@ class InitProxyResolver { // Filled when the PAC script fetch completes. string16 pac_script_; + // Flag indicating whether the caller requested a mandatory pac script + // (i.e. fallback to direct connections are prohibited). + bool pac_mandatory_; + UrlList pac_urls_; State next_state_; diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc index 4e6d38a..f5ae3d7 100644 --- a/net/proxy/proxy_service_unittest.cc +++ b/net/proxy/proxy_service_unittest.cc @@ -391,6 +391,155 @@ TEST(ProxyServiceTest, ProxyResolverFails) { EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI()); } +TEST(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, &info, &callback1, 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, &info, &callback2, NULL, BoundNetLog()); + EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv); + EXPECT_FALSE(info.is_direct()); +} + +TEST(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; + service.SetProxyScriptFetcher(fetcher); + + // Start resolve request. + GURL url("http://www.google.com/"); + ProxyInfo info; + TestCompletionCallback callback; + int rv = service.ResolveProxy(url, &info, &callback, 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"); + + // Simulate a parse error. + EXPECT_EQ(ASCIIToUTF16("invalid-script-contents"), + resolver->pending_set_pac_script_request()->script_data()->utf16()); + resolver->pending_set_pac_script_request()->CompleteNow( + ERR_PAC_SCRIPT_FAILED); + + EXPECT_FALSE(fetcher->has_pending_request()); + 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, + callback.WaitForResult()); + EXPECT_FALSE(info.is_direct()); +} + +TEST(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, &info, &callback1, 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, &info, &callback2, 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(ProxyServiceTest, ProxyFallback) { // Test what happens when we specify multiple proxy servers and some of them // are bad. @@ -719,6 +868,94 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) { EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI()); } +TEST(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, &info, &callback1, 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, &info, &callback2, 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, &info2, &callback3, 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, &info3, &callback4, 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(ProxyServiceTest, ProxyBypassList) { // Test that the proxy bypass rules are consulted. |