172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_service.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector>
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/format_macros.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_errors.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h"
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/test_completion_callback.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/mock_proxy_resolver.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_config_service.h"
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_resolver.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/proxy/proxy_script_fetcher.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(eroman): Write a test which exercises
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//              ProxyService::SuspendAllPendingRequests().
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockProxyConfigService: public ProxyConfigService {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit MockProxyConfigService(const ProxyConfig& config)
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : availability_(CONFIG_VALID),
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        config_(config) {
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit MockProxyConfigService(const std::string& pac_url)
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : availability_(CONFIG_VALID),
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void AddObserver(Observer* observer) {
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    observers_.AddObserver(observer);
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void RemoveObserver(Observer* observer) {
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    observers_.RemoveObserver(observer);
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* results) {
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (availability_ == CONFIG_VALID)
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      *results = config_;
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return availability_;
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void SetConfig(const ProxyConfig& config) {
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    availability_ = CONFIG_VALID;
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    config_ = config;
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FOR_EACH_OBSERVER(Observer, observers_,
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      OnProxyConfigChanged(config_, availability_));
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfigAvailability availability_;
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ProxyConfig config_;
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ObserverList<Observer, true> observers_;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A mock ProxyScriptFetcher. No result will be returned to the fetch client
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// until we call NotifyFetchCompletion() to set the results.
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockProxyScriptFetcher : public ProxyScriptFetcher {
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher()
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : pending_request_callback_(NULL), pending_request_text_(NULL) {
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyScriptFetcher implementation.
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int Fetch(const GURL& url,
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    string16* text,
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    CompletionCallback* callback) {
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(!has_pending_request());
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Save the caller's information, and have them wait.
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pending_request_url_ = url;
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pending_request_callback_ = callback;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_request_text_ = text;
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ERR_IO_PENDING;
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void NotifyFetchCompletion(int result, const std::string& ascii_text) {
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(has_pending_request());
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *pending_request_text_ = ASCIIToUTF16(ascii_text);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CompletionCallback* callback = pending_request_callback_;
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pending_request_callback_ = NULL;
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    callback->Run(result);
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Cancel() {}
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual URLRequestContext* GetRequestContext() { return NULL; }
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const GURL& pending_request_url() const {
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return pending_request_url_;
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool has_pending_request() const {
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return pending_request_callback_ != NULL;
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL pending_request_url_;
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CompletionCallback* pending_request_callback_;
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16* pending_request_text_;
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, Direct) {
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new ProxyService(new MockProxyConfigService(
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ProxyConfig::CreateDirect()), resolver, NULL));
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback, NULL, log.bound());
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_direct());
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check the NetLog was filled correctly.
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CapturingNetLog::EntryList entries;
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(3u, entries.size());
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsBeginEvent(
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_PROXY_SERVICE));
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(LogContainsEvent(
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NetLog::PHASE_NONE));
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEndEvent(
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_PROXY_SERVICE));
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, PAC) {
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback, NULL, log.bound());
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback.WaitForResult());
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check the NetLog was filled correctly.
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CapturingNetLog::EntryList entries;
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(5u, entries.size());
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsBeginEvent(
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_PROXY_SERVICE));
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEndEvent(
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 4, NetLog::TYPE_PROXY_SERVICE));
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that the proxy resolver does not see the URL's username/password
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// or its reference section.
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, PAC_NoIdentityOrHash) {
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://username:password@www.google.com/?ref#hash#hash");
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback, NULL, BoundNetLog());
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The URL should have been simplified, stripping the username/password/hash.
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://www.google.com/?ref"),
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 resolver->pending_requests()[0]->url());
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We end here without ever completing the request -- destruction of
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyService will cancel the outstanding request.
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, PAC_FailoverWithoutDirect) {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now, imagine that connecting to foopy:8080 fails: there is nothing
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // left to fallback to, since our proxy list was NOT terminated by
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // DIRECT.
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ReconsiderProxyAfterError returns error indicating nothing left.
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, rv);
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_empty());
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The proxy list could potentially contain the DIRECT fallback choice
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in a location other than the very end of the list, and could even
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// specify it multiple times.
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is not a typical usage, but we will obey it.
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (If we wanted to disallow this type of input, the right place to
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// enforce it would be in parsing the PAC result string).
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test will use the PAC result string:
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// then foobar:20, and then give up and error.
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The important check of this test is to make sure that DIRECT is not somehow
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cached as being a bad proxy.
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, PAC_FailoverAfterDirect) {
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UsePacString(
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_direct());
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fallback 1.
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fallback 2.
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback3, NULL,
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_direct());
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fallback 3.
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback4;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL,
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fallback 4 -- Nothing to fall back to!
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback5;
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback5, NULL,
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, rv);
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_empty());
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyResolverFails) {
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test what happens when the ProxyResolver fails. The download and setting
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // of the PAC script have already succeeded, so this corresponds with a
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // javascript runtime error while calling FindProxyForURL().
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start first resolve request.
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fail the first resolve request in MockAsyncProxyResolver.
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Although the proxy resolver failed the request, ProxyService implicitly
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // falls-back to DIRECT.
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback1.WaitForResult());
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(info.is_direct());
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The second resolve request will try to run through the proxy resolver,
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // regardless of whether the first request failed in it.
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ResolveProxy(url, &info, &callback2, NULL, BoundNetLog());
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This time we will have the resolver succeed (perhaps the PAC script has
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // a dependency on the current time).
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyFallback) {
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test what happens when we specify multiple proxy servers and some of them
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // are bad.
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the proxy information.
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first item is valid.
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake an error on the proxy.
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The second proxy should be specified.
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ResolveProxy(url, &info, &callback3, NULL, BoundNetLog());
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver -- the second result is already known
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to be bad, so we will not try to use it initially.
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy3:7070;foopy1:8080;foopy2:9090");
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback3.WaitForResult());
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We fake another error. It should now try the third one.
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback4;
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL,
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We fake another error. At this point we have tried all of the
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // proxy servers we thought were valid; next we try the proxy server
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // that was in our bad proxies map (foopy1:8080).
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback5;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback5, NULL,
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake another error, the last proxy is gone, the list should now be empty,
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // so there is nothing left to try.
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback6;
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback6, NULL,
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, rv);
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_empty());
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(nsylvain): Test that the proxy can be retried after the delay.
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test is similar to ProxyFallback, but this time we have an explicit
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// fallback choice to DIRECT.
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyFallbackToDirect) {
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the proxy information.
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UsePacString(
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the first result.
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake an error on the proxy.
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we get back the second proxy.
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake an error on this proxy as well.
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback3, NULL,
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Finally, we get back DIRECT.
543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info.is_direct());
544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now we tell the proxy service that even DIRECT failed.
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback4;
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL,
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // There was nothing left to try after DIRECT, so we are out of
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // choices.
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_FAILED, rv);
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyFallback_NewSettings) {
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test proxy failover when new settings are available.
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the proxy information.
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Set the result in proxy resolver.
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first item is valid.
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake an error on the proxy, and also a new configuration on the proxy.
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  config_service->SetConfig(
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first proxy is still there since the configuration changed.
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We fake another error. It should now ignore the first one.
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback3, NULL,
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We simulate a new configuration.
6223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  config_service->SetConfig(
6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ProxyConfig::CreateFromCustomPacURL(
6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          GURL("http://foopy-new2/proxy.pac")));
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We fake another error. It should go back to the first proxy.
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback4;
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback4, NULL,
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback4.WaitForResult());
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyFallback_BadConfig) {
648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Test proxy failover when the configuration is bad.
649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the proxy information.
661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback1, NULL, BoundNetLog());
664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first item is valid.
677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake a proxy error.
682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info, &callback2, NULL,
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first proxy is ignored, and the second one is selected.
688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info.is_direct());
689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fake a PAC failure.
692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ResolveProxy(url, &info2, &callback3, NULL, BoundNetLog());
695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This simulates a javascript runtime error in the PAC script.
701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Although the resolver failed, the ProxyService will implicitly fall-back
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to a DIRECT connection.
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback3.WaitForResult());
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(info2.is_direct());
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(info2.is_empty());
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The PAC script will work properly next time and successfully return a
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // proxy list. Since we have not marked the configuration as bad, it should
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // "just work" the next time we call it.
712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info3;
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback4;
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ReconsiderProxyAfterError(url, &info3, &callback4, NULL,
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          BoundNetLog());
716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy(
722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      "foopy1:8080;foopy2:9090");
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first proxy is not there since the it was added to the bad proxies
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // list by the earlier ReconsiderProxyAfterError().
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback4.WaitForResult());
728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(info3.is_direct());
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ProxyBypassList) {
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test that the proxy bypass rules are consulted.
734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback[2];
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProxyInfo info[2];
737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(false);
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().bypass_rules.ParseFromString("*.org");
741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<ProxyService> service(new ProxyService(
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv;
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url1("http://www.webkit.org");
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url2("http://www.webkit.com");
748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Request for a .org domain should bypass proxy.
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ResolveProxy(url1, &info[0], &callback[0], NULL, BoundNetLog());
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, rv);
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(info[0].is_direct());
753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Request for a .com domain hits the proxy.
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = service->ResolveProxy(url2, &info[1], &callback[1], NULL, BoundNetLog());
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, rv);
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, PerProtocolProxyTests) {
762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(false);
765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("http://www.msn.com");
769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("ftp://ftp.google.com");
781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_TRUE(info.is_direct());
787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("direct://", info.proxy_server().ToURI());
788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("https://webbranch.techcu.com");
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    config.proxy_rules().ParseFromString("foopy1:8080");
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("http://www.microsoft.com");
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// fall back to the SOCKS proxy.
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(false);
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            config.proxy_rules().type);
824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("http://www.msn.com");
829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("ftp://ftp.google.com");
841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("https://webbranch.techcu.com");
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_refptr<ProxyService> service(new ProxyService(
863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GURL test_url("unknown://www.microsoft.com");
865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ProxyInfo info;
866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestCompletionCallback callback;
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = service->ResolveProxy(test_url, &info, &callback, NULL,
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   BoundNetLog());
869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(OK, rv);
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_FALSE(info.is_direct());
871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test cancellation of an in-progress request.
876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, CancelInProgressRequest) {
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 3 requests.
886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the proxy resolver yet, since the proxy
894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // resolver has not been configured yet.
895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Successfully initialize the PAC script.
898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request2;
908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, &request2, BoundNetLog());
910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2u, resolver->pending_requests().size());
912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info3;
915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request3"), &info3, &callback3, NULL, BoundNetLog());
918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(3u, resolver->pending_requests().size());
920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel the second request
923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->CancelPacRequest(request2);
924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2u, resolver->pending_requests().size());
926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the two un-cancelled requests.
930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We complete the last one first, just to mix it up a bit.
931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->CompleteNow(OK);
933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete and verify that requests ran as expected.
938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(callback2.have_result());  // Cancelled.
942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->cancelled_requests().size());
943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback3.WaitForResult());
946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test the initial PAC download for resolver that expects bytes.
950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, InitialPACScriptDownload) {
951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 3 requests.
964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should have triggered download of PAC script.
972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, NULL, BoundNetLog());
979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info3;
982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request3"), &info3, &callback3, NULL, BoundNetLog());
985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the resolver yet.
988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point the ProxyService should be waiting for the
991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyScriptFetcher to invoke its completion callback, notifying it of
992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // PAC script download completion.
993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "pac-v1");
994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now that the PAC script is downloaded, it will have been sent to the proxy
996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // resolver.
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("pac-v1"),
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(3u, resolver->pending_requests().size());
1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete all the requests (in some order).
1007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Note that as we complete requests, they shift up in |pending_requests()|.
1008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[2]->CompleteNow(OK);
1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete and verify that requests ran as expected.
1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback3.WaitForResult());
1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test changing the ProxyScriptFetcher while PAC download is in progress.
1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 2 requests.
1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should have triggered download of PAC script.
1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, NULL, BoundNetLog());
1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point the ProxyService should be waiting for the
1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyScriptFetcher to invoke its completion callback, notifying it of
1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // PAC script download completion.
1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We now change out the ProxyService's script fetcher. We should restart
1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the initialization with the new fetcher.
1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher = new MockProxyScriptFetcher;
1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the resolver yet.
1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "pac-v1");
1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now that the PAC script is downloaded, it will have been sent to the proxy
1077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // resolver.
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("pac-v1"),
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2u, resolver->pending_requests().size());
1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test cancellation of a request, while the PAC script is being fetched.
1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, CancelWhilePACFetching) {
1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 3 requests.
1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request1;
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log1(CapturingNetLog::kUnbounded);
1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, &request1, log1.bound());
1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should have triggered download of PAC script.
1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request2;
1117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, &request2, BoundNetLog());
1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info3;
1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback3;
1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request3"), &info3, &callback3, NULL, BoundNetLog());
1125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the resolver yet.
1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel the first 2 requests.
1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->CancelPacRequest(request1);
1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->CancelPacRequest(request2);
1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point the ProxyService should be waiting for the
1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyScriptFetcher to invoke its completion callback, notifying it of
1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // PAC script download completion.
1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "pac-v1");
1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now that the PAC script is downloaded, it will have been sent to the
1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // proxy resolver.
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("pac-v1"),
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete all the requests.
1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback3.WaitForResult());
1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->cancelled_requests().empty());
1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(callback1.have_result());  // Cancelled.
1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(callback2.have_result());  // Cancelled.
1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
116072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CapturingNetLog::EntryList entries1;
116121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log1.GetEntries(&entries1);
116221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check the NetLog for request 1 (which was cancelled) got filled properly.
116421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(4u, entries1.size());
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsBeginEvent(
116621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries1, 0, NetLog::TYPE_PROXY_SERVICE));
1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
116821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the cancellation occured.
1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEvent(
117221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEndEvent(
117421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries1, 3, NetLog::TYPE_PROXY_SERVICE));
1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that if auto-detect fails, we fall-back to the custom pac.
1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(true);
1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_pac_url(GURL("http://foopy/proxy.pac"));
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 2 requests.
1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
1199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request2;
1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, &request2, BoundNetLog());
1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // It should be trying to auto-detect first -- FAIL the autodetect during
1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the script download.
1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next it should be trying the custom PAC url.
1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "custom-pac-script");
1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("custom-pac-script"),
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now finally, the pending requests should have been sent to the resolver
1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (which was initialized with custom PAC script).
1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2u, resolver->pending_requests().size());
1230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending requests.
1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->CompleteNow(OK);
1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that requests ran as expected.
1240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is the same test as FallbackFromAutodetectToCustomPac, except
1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the auto-detect script fails parsing rather than downloading.
1249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
1250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(true);
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_pac_url(GURL("http://foopy/proxy.pac"));
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 2 requests.
1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request2;
1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, &request2, BoundNetLog());
1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // It should be trying to auto-detect first -- succeed the download.
1283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Simulate a parse error.
1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("invalid-script-contents"),
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(
1291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ERR_PAC_SCRIPT_FAILED);
1292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next it should be trying the custom PAC url.
1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "custom-pac-script");
1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("custom-pac-script"),
1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now finally, the pending requests should have been sent to the resolver
1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (which was initialized with custom PAC script).
1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2u, resolver->pending_requests().size());
1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending requests.
1310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[1]->CompleteNow(OK);
1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that requests ran as expected.
1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that if all of auto-detect, a custom PAC script, and manual settings
1324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// are given, then we will try them in that order.
1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
1327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(true);
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_pac_url(GURL("http://foopy/proxy.pac"));
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy:80");
1330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 2 requests.
1341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
1346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyService::PacRequest* request2;
1351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, &request2, BoundNetLog());
1353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // It should be trying to auto-detect first -- fail the download.
1359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next it should be trying the custom PAC url -- fail the download.
1364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
1367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Since we never managed to initialize a ProxyResolver, nothing should have
1369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // been sent to it.
1370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that requests ran as expected -- they should have fallen back to
1373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the manual proxy configuration for HTTP urls.
1374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
1376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that the bypass rules are NOT applied when using autodetect.
1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, BypassDoesntApplyToPac) {
1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config;
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_auto_detect(true);
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.set_pac_url(GURL("http://foopy/proxy.pac"));
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().ParseFromString("http=foopy:80");  // Not used.
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 1 requests.
1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.google.com"), &info1, &callback1, NULL, BoundNetLog());
1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // It should be trying to auto-detect first -- succeed the download.
1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "auto-detect");
1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("auto-detect"),
1415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://www.google.com"),
1420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            resolver->pending_requests()[0]->url());
1421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending request.
1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that request ran as expected.
1427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start another request, it should pickup the bypass item.
1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.google.com"), &info2, &callback2, NULL, BoundNetLog());
1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://www.google.com"),
1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            resolver->pending_requests()[0]->url());
1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending request.
1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Delete the ProxyService while InitProxyResolver has an outstanding
1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// request to the script fetcher. When run under valgrind, should not
1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// have any memory errors (used to be that the ProxyScriptFetcher was
1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// being deleted prior to the InitProxyResolver).
1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
14543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ProxyConfig config =
14553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 1 request.
1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.google.com"), &info1, &callback1, NULL, BoundNetLog());
1472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // InitProxyResolver should have issued a request to the ProxyScriptFetcher
1478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and be waiting on that to complete.
1479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Delete the ProxyService
1483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service = NULL;
1484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Delete the ProxyService while InitProxyResolver has an outstanding
1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// request to the proxy resolver. When run under valgrind, should not
1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// have any memory errors (used to be that the ProxyResolver was
1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// being deleted prior to the InitProxyResolver).
1490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
1492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
1493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
1495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GURL url("http://www.google.com/");
1500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
1502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
1503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = service->ResolveProxy(url, &info, &callback, NULL, BoundNetLog());
1504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
1507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->url());
1508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Delete the ProxyService.
1510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service = NULL;
1511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, ResetProxyConfigService) {
1514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config1;
1515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config1.proxy_rules().ParseFromString("foopy1:8080");
1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config1.set_auto_detect(false);
1517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(new ProxyService(
1518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService(config1),
1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new MockAsyncProxyResolverExpectsBytes, NULL));
1520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info;
1522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info, &callback1, NULL, BoundNetLog());
1525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
1526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
1527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyConfig config2;
1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config2.proxy_rules().ParseFromString("foopy2:8080");
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  config2.set_auto_detect(false);
1531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->ResetConfigService(new MockProxyConfigService(config2));
1532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info, &callback2, NULL, BoundNetLog());
1535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
1536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
1537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Test that when going from a configuration that required PAC to one
1540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that does NOT, we unset the variable |should_use_proxy_resolver_|.
1541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, UpdateConfigFromPACToDirect) {
15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ProxyConfig config = ProxyConfig::CreateAutoDetect();
1543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service = new MockProxyConfigService(config);
1545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
1546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
1547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new ProxyService(config_service, resolver, NULL));
1548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 1 request.
1550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.google.com"), &info1, &callback1, NULL, BoundNetLog());
1555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check that nothing has been sent to the proxy resolver yet.
1558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(0u, resolver->pending_requests().size());
1559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Successfully set the autodetect script.
1561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->type());
1563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending request.
1566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Verify that request ran as expected.
1571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Force the ProxyService to pull down a new proxy configuration.
1575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (Even though the configuration isn't old/bad).
1576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
1577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This new configuration no longer has auto_detect set, so
1578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requests should complete synchronously now as direct-connect.
15793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  config_service->SetConfig(ProxyConfig::CreateDirect());
1580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start another request -- the effective configuration has changed.
1582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.google.com"), &info2, &callback2, NULL, BoundNetLog());
1586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
1587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(info2.is_direct());
1589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
1592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyConfigService* config_service =
1593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockProxyConfigService("http://foopy/proxy.pac");
1594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockAsyncProxyResolverExpectsBytes* resolver =
1596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new MockAsyncProxyResolverExpectsBytes;
1597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CapturingNetLog log(CapturingNetLog::kUnbounded);
15993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_refptr<ProxyService> service(
16013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new ProxyService(config_service, resolver, &log));
1602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
1604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  service->SetProxyScriptFetcher(fetcher);
1605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Disable the "wait after IP address changes" hack, so this unit-test can
16073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // complete quickly.
16083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service->set_stall_proxy_auto_config_delay(base::TimeDelta());
16093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start 1 request.
1611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info1;
1613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback1;
1614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rv = service->ResolveProxy(
1615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request1"), &info1, &callback1, NULL, BoundNetLog());
1616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The first request should have triggered initial download of PAC script.
1619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the resolver yet.
1623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
1624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point the ProxyService should be waiting for the
1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ProxyScriptFetcher to invoke its completion callback, notifying it of
1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // PAC script download completion.
1628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "pac-v1");
1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now that the PAC script is downloaded, the request will have been sent to
1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the proxy resolver.
1632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("pac-v1"),
1633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending request.
1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Wait for completion callback, and verify that the request ran as expected.
1644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback1.WaitForResult());
1645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
1646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now simluate a change in the network. The ProxyConfigService is still
1648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // going to return the same PAC URL as before, but this URL needs to be
1649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // refetched on the new network.
1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
1651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();  // Notification happens async.
1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start a second request.
1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ProxyInfo info2;
1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rv = service->ResolveProxy(
1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://request2"), &info2, &callback2, NULL, BoundNetLog());
1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This second request should have triggered the re-download of the PAC
1661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // script (since we marked the network as having changed).
1662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(fetcher->has_pending_request());
1663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
1664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Nothing has been sent to the resolver yet.
1666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(resolver->pending_requests().empty());
1667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Simulate the PAC script fetch as having completed (this time with
1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // different data).
1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  fetcher->NotifyFetchCompletion(OK, "pac-v2");
1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now that the PAC script is downloaded, the second request will have been
1673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // sent to the proxy resolver.
1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ASCIIToUTF16("pac-v2"),
1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            resolver->pending_set_pac_script_request()->script_data()->utf16());
1676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_set_pac_script_request()->CompleteNow(OK);
1677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(1u, resolver->pending_requests().size());
1679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
1680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Complete the pending second request.
1682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  resolver->pending_requests()[0]->CompleteNow(OK);
1684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Wait for completion callback, and verify that the request ran as expected.
1686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
16883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check that the expected events were outputted to the log stream.
16903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // In particular, PROXY_CONFIG_CHANGED should have only been emitted once
16913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // (for the initial setup), and NOT a second time when the IP address
16923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // changed.
169372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CapturingNetLog::EntryList entries;
169421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
169521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
169621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
16973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       NetLog::TYPE_PROXY_CONFIG_CHANGED));
169821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_EQ(13u, entries.size());
169921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  for (size_t i = 1; i < entries.size(); ++i)
170021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
1704