| Index: net/proxy/proxy_service_unittest.cc
|
| diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
|
| index 84ce1010207699e6444ec9743d9e904eef5bf73d..9f7b4065d2983400b340bbcbeb8fafd161de8c54 100644
|
| --- a/net/proxy/proxy_service_unittest.cc
|
| +++ b/net/proxy/proxy_service_unittest.cc
|
| @@ -3083,6 +3083,149 @@ TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
|
| EXPECT_TRUE(info3.is_direct());
|
| }
|
|
|
| +// This tests the re-fetching and application of the PAC script after the proxy
|
| +// resolver returns with a ERR_PAC_SCRIPT_TERMINATED error. This is for
|
| +// out-of-process v8 resolver which returns that error if the resolver process
|
| +// crashes.
|
| +TEST_F(ProxyServiceTest, PACScriptRefetchAfterTerminatedResolveProxy) {
|
| + 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.SetProxyScriptFetchers(fetcher,
|
| + new DoNothingDhcpProxyScriptFetcher());
|
| +
|
| + // Start 1 request.
|
| + ProxyInfo info1;
|
| + TestCompletionCallback callback1;
|
| + int rv =
|
| + service.ResolveProxy(GURL("http://request1"), net::LOAD_NORMAL, &info1,
|
| + callback1.callback(), NULL, NULL, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + // The first request should have triggered initial download of PAC script.
|
| + EXPECT_TRUE(fetcher->has_pending_request());
|
| + EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
|
| +
|
| + // Nothing has been sent to the resolver yet.
|
| + EXPECT_TRUE(resolver->pending_requests().empty());
|
| +
|
| + // At this point the ProxyService should be waiting for the
|
| + // ProxyScriptFetcher to invoke its completion callback, notifying it of
|
| + // PAC script download completion.
|
| + fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
|
| +
|
| + // Now that the PAC script is downloaded, the request will have been sent to
|
| + // the proxy resolver.
|
| + EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
|
| + resolver->pending_set_pac_script_request()->script_data()->utf16());
|
| + resolver->pending_set_pac_script_request()->CompleteNow(OK);
|
| +
|
| + ASSERT_EQ(1u, resolver->pending_requests().size());
|
| + EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
|
| +
|
| + // Complete the pending request.
|
| + resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
|
| + resolver->pending_requests()[0]->CompleteNow(OK);
|
| +
|
| + // Wait for completion callback, and verify that the request ran as expected.
|
| + EXPECT_EQ(OK, callback1.WaitForResult());
|
| + EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
|
| +
|
| + // At this point we have initialized the proxy service using a PAC script.
|
| + // Our PAC poller is set to update ONLY in response to network activity,
|
| + // (i.e. another call to ResolveProxy()).
|
| +
|
| + ASSERT_FALSE(fetcher->has_pending_request());
|
| + ASSERT_TRUE(resolver->pending_requests().empty());
|
| +
|
| + // Start a second request and third request.
|
| + ProxyInfo info2;
|
| + TestCompletionCallback callback2;
|
| + rv = service.ResolveProxy(GURL("http://request2"), net::LOAD_NORMAL, &info2,
|
| + callback2.callback(), NULL, NULL, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + ProxyInfo info3;
|
| + TestCompletionCallback callback3;
|
| + rv = service.ResolveProxy(GURL("http://request3"), net::LOAD_NORMAL, &info3,
|
| + callback3.callback(), NULL, NULL, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| +
|
| + // Fail request 2 with ERR_PAC_SCRIPT_TERMINATED, which indicates the PAC
|
| + // script has terminated fatally and needs to be reloaded. Request 3's resolve
|
| + // request should be cancelled, but ProxyService keeps it and retries it
|
| + // later.
|
| + ASSERT_EQ(2u, resolver->pending_requests().size());
|
| + EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
|
| + EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
|
| + resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);
|
| + EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
|
| + callback2.WaitForResult());
|
| +
|
| + ASSERT_EQ(0u, resolver->pending_requests().size());
|
| + ASSERT_EQ(1u, resolver->cancelled_requests().size());
|
| +
|
| + // Since there's an active request, the proxy script should automatically be
|
| + // re-fetched.
|
| + EXPECT_TRUE(fetcher->has_pending_request());
|
| + 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());
|
| +
|
| + // Do another request which fails with ERR_PAC_SCRIPT_TERMINATED. This time,
|
| + // there are no pending requests, so don't re-fetch the script until the next
|
| + // request comes in.
|
| + ProxyInfo info4;
|
| + TestCompletionCallback callback4;
|
| + rv = service.ResolveProxy(GURL("http://request4"), net::LOAD_NORMAL, &info4,
|
| + callback4.callback(), NULL, NULL, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + ASSERT_EQ(1u, resolver->pending_requests().size());
|
| + resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_TERMINATED);
|
| +
|
| + // There should be no automatic fetch request this time.
|
| + EXPECT_FALSE(fetcher->has_pending_request());
|
| +
|
| + // Now, the next request should cause a fetch.
|
| + ProxyInfo info5;
|
| + TestCompletionCallback callback5;
|
| + rv = service.ResolveProxy(GURL("http://request5"), net::LOAD_NORMAL, &info5,
|
| + callback5.callback(), NULL, NULL, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + // No pending requests to the resolver since a script fetch is in progress.
|
| + EXPECT_TRUE(resolver->pending_requests().empty());
|
| +
|
| + // Now there should be a PAC script fetch.
|
| + EXPECT_TRUE(fetcher->has_pending_request());
|
| +
|
| + // Finish and verify.
|
| + 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://request5"), resolver->pending_requests()[0]->url());
|
| + resolver->pending_requests()[0]->results()->UseNamedProxy("request5:80");
|
| + resolver->pending_requests()[0]->CompleteNow(OK);
|
| + EXPECT_EQ(OK, callback5.WaitForResult());
|
| + EXPECT_EQ("request5:80", info5.proxy_server().ToURI());
|
| +}
|
| +
|
| // Test that the synchronous resolution fails when a PAC script is active.
|
| TEST_F(ProxyServiceTest, SynchronousWithPAC) {
|
| MockProxyConfigService* config_service =
|
|
|