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