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

Unified Diff: net/proxy/proxy_service_unittest.cc

Issue 502068: Remove the implicit fallback to DIRECT when proxies fail. This better matches... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fix a comment typo Created 10 years, 12 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
« net/proxy/proxy_service.cc ('K') | « net/proxy/proxy_service.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/proxy/proxy_service_unittest.cc
===================================================================
--- net/proxy/proxy_service_unittest.cc (revision 35522)
+++ net/proxy/proxy_service_unittest.cc (working copy)
@@ -185,7 +185,7 @@
// ProxyService will cancel the outstanding request.
}
-TEST(ProxyServiceTest, PAC_FailoverToDirect) {
+TEST(ProxyServiceTest, PAC_FailoverWithoutDirect) {
MockProxyConfigService* config_service =
new MockProxyConfigService("http://foopy/proxy.pac");
MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
@@ -215,18 +215,94 @@
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
- // Now, imagine that connecting to foopy:8080 fails.
+ // Now, imagine that connecting to foopy:8080 fails: there is nothing
+ // left to fallback to, since our proxy list was NOT terminated by
+ // DIRECT.
TestCompletionCallback callback2;
rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL, NULL);
+ // ReconsiderProxyAfterError returns error indicating nothing left.
+ EXPECT_EQ(ERR_FAILED, rv);
+ EXPECT_TRUE(info.is_empty());
+}
+
+// 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(ProxyServiceTest, PAC_FailoverAfterDirect) {
+ MockProxyConfigService* config_service =
+ new MockProxyConfigService("http://foopy/proxy.pac");
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+ scoped_refptr<ProxyService> service(
+ new ProxyService(config_service, resolver));
+
+ GURL url("http://www.google.com/");
+
+ ProxyInfo info;
+ TestCompletionCallback callback1;
+ int rv = service->ResolveProxy(url, &info, &callback1, NULL, NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ resolver->pending_set_pac_script_request()->pac_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, &info, &callback2, NULL, NULL);
EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
+
+ // Fallback 2.
+ TestCompletionCallback callback3;
+ rv = service->ReconsiderProxyAfterError(url, &info, &callback3, NULL, NULL);
+ EXPECT_EQ(OK, rv);
EXPECT_TRUE(info.is_direct());
+
+ // Fallback 3.
+ TestCompletionCallback callback4;
+ rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
+
+ // Fallback 4 -- Nothing to fall back to!
+ TestCompletionCallback callback5;
+ rv = service->ReconsiderProxyAfterError(url, &info, &callback5, NULL, NULL);
+ EXPECT_EQ(ERR_FAILED, rv);
+ EXPECT_TRUE(info.is_empty());
}
TEST(ProxyServiceTest, ProxyResolverFails) {
- // Test what happens when the ProxyResolver fails (this could represent
- // a failure to download the PAC script in the case of ProxyResolvers which
- // do the fetch internally.)
- // TODO(eroman): change this comment.
+ // 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");
@@ -255,28 +331,21 @@
EXPECT_EQ(ERR_FAILED, callback1.WaitForResult());
- // The second resolve request will automatically select direct connect,
- // because it has cached the configuration as being bad.
+ // 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, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- EXPECT_TRUE(resolver->pending_requests().empty());
-
- // But, if that fails, then we should give the proxy config another shot
- // since we have never tried it with this URL before.
- TestCompletionCallback callback3;
- rv = service->ReconsiderProxyAfterError(url, &info, &callback3, NULL, NULL);
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.
+ // 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, callback3.WaitForResult());
+ EXPECT_EQ(OK, callback2.WaitForResult());
EXPECT_FALSE(info.is_direct());
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
}
@@ -349,20 +418,77 @@
EXPECT_EQ(OK, rv);
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
- // Fake another error, the last proxy is gone, the list should now be empty.
+ // Fake another error, the last proxy is gone, the list should now be empty,
+ // so there is nothing left to try.
TestCompletionCallback callback5;
rv = service->ReconsiderProxyAfterError(url, &info, &callback5, NULL, NULL);
- EXPECT_EQ(OK, rv); // We try direct.
- EXPECT_TRUE(info.is_direct());
-
- // If it fails again, we don't have anything else to try.
- TestCompletionCallback callback6;
- rv = service->ReconsiderProxyAfterError(url, &info, &callback6, NULL, NULL);
EXPECT_EQ(ERR_FAILED, rv);
+ EXPECT_FALSE(info.is_direct());
+ EXPECT_TRUE(info.is_empty());
// 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(ProxyServiceTest, ProxyFallbackToDirect) {
+ MockProxyConfigService* config_service =
+ new MockProxyConfigService("http://foopy/proxy.pac");
+
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+ scoped_refptr<ProxyService> service(
+ new ProxyService(config_service, resolver));
+
+ GURL url("http://www.google.com/");
+
+ // Get the proxy information.
+ ProxyInfo info;
+ TestCompletionCallback callback1;
+ int rv = service->ResolveProxy(url, &info, &callback1, NULL, NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+ resolver->pending_set_pac_script_request()->pac_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, &info, &callback2, NULL, NULL);
+ 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, &info, &callback3, NULL, NULL);
+ EXPECT_EQ(OK, rv);
+
+ // Finally, we get back DIRECT.
+ EXPECT_TRUE(info.is_direct());
+
+ // Now we tell the proxy service that even DIRECT failed.
+ TestCompletionCallback callback4;
+ rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL, NULL);
+ // There was nothing left to try after DIRECT, so we are out of
+ // choices.
+ EXPECT_EQ(ERR_FAILED, rv);
+}
+
TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
// Test proxy failover when new settings are available.
@@ -504,28 +630,20 @@
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);
- // No proxy servers are returned. It's a direct connection.
+ // No proxy servers are returned, since we failed.
EXPECT_EQ(ERR_FAILED, callback3.WaitForResult());
- EXPECT_TRUE(info2.is_direct());
+ EXPECT_FALSE(info2.is_direct());
+ EXPECT_TRUE(info2.is_empty());
- // The PAC will now be fixed and will return a proxy server.
- // It should also clear the list of bad proxies.
-
- // Try to resolve, it will still return "direct" because we have no reason
- // to check the config since everything works.
+ // 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->ResolveProxy(url, &info3, &callback4, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info3.is_direct());
-
- // But if the direct connection fails, we check if the ProxyInfo tried to
- // resolve the proxy before, and if not (like in this case), we give the
- // PAC another try.
- TestCompletionCallback callback5;
- rv = service->ReconsiderProxyAfterError(url, &info3, &callback5, NULL, NULL);
+ rv = service->ReconsiderProxyAfterError(url, &info3, &callback4, NULL, NULL);
EXPECT_EQ(ERR_IO_PENDING, rv);
ASSERT_EQ(1u, resolver->pending_requests().size());
@@ -535,8 +653,9 @@
"foopy1:8080;foopy2:9090");
resolver->pending_requests()[0]->CompleteNow(OK);
- // The first proxy is still there since the list of bad proxies got cleared.
- EXPECT_EQ(OK, callback5.WaitForResult());
+ // 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());
}
« net/proxy/proxy_service.cc ('K') | « net/proxy/proxy_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698