Index: net/proxy/proxy_service_unittest.cc |
=================================================================== |
--- net/proxy/proxy_service_unittest.cc (revision 21631) |
+++ net/proxy/proxy_service_unittest.cc (working copy) |
@@ -2,14 +2,16 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "base/compiler_specific.h" |
+#include <vector> |
+ |
+#include "base/logging.h" |
#include "googleurl/src/gurl.h" |
#include "net/base/net_errors.h" |
+#include "net/base/test_completion_callback.h" |
#include "net/proxy/proxy_config_service.h" |
#include "net/proxy/proxy_resolver.h" |
#include "net/proxy/proxy_script_fetcher.h" |
#include "net/proxy/proxy_service.h" |
-#include "net/proxy/single_threaded_proxy_resolver.h" |
#include "testing/gtest/include/gtest/gtest.h" |
namespace { |
@@ -30,469 +32,160 @@ |
net::ProxyConfig config; |
}; |
-class SyncMockProxyResolver : public net::ProxyResolver { |
+// Asynchronous mock proxy resolver. All requests complete asynchronously, |
+// user must call Request::CompleteNow() on a pending request to signal it. |
+class MockAsyncProxyResolverBase : public net::ProxyResolver { |
public: |
- SyncMockProxyResolver() : net::ProxyResolver(false /*expects_pac_bytes*/), |
- fail_get_proxy_for_url(false) { |
- } |
- |
- // ProxyResolver implementation: |
- virtual int GetProxyForURL(const GURL& query_url, |
- net::ProxyInfo* results, |
- net::CompletionCallback* callback, |
- RequestHandle* request) { |
- if (fail_get_proxy_for_url) |
- return net::ERR_FAILED; |
- if (GURL(query_url).host() == info_predicate_query_host) { |
- results->Use(info); |
- } else { |
- results->UseDirect(); |
+ class Request : public base::RefCounted<Request> { |
+ public: |
+ Request(MockAsyncProxyResolverBase* resolver, |
+ const GURL& url, |
+ net::ProxyInfo* results, |
+ net::CompletionCallback* callback) |
+ : resolver_(resolver), |
+ url_(url), |
+ results_(results), |
+ callback_(callback), |
+ origin_loop_(MessageLoop::current()) { |
} |
- return net::OK; |
- } |
- virtual void CancelRequest(RequestHandle request) { |
- NOTREACHED(); |
- } |
+ const GURL& url() const { return url_; } |
+ net::ProxyInfo* results() const { return results_; } |
+ net::CompletionCallback* callback() const { return callback_; } |
- virtual void SetPacScriptByUrlInternal(const GURL& pac_url) {} |
+ void CompleteNow(int rv) { |
+ net::CompletionCallback* callback = callback_; |
+ // May delete |this|. |
+ resolver_->RemovePendingRequest(this); |
- net::ProxyInfo info; |
- |
- // info is only returned if query_url in GetProxyForURL matches this: |
- std::string info_predicate_query_host; |
- |
- // If true, then GetProxyForURL will fail, which simulates failure to |
- // download or execute the PAC file. |
- bool fail_get_proxy_for_url; |
-}; |
- |
-class MockProxyResolver : public net::SingleThreadedProxyResolver { |
- public: |
- MockProxyResolver() |
- : net::SingleThreadedProxyResolver(new SyncMockProxyResolver) { |
- x = reinterpret_cast<SyncMockProxyResolver*>(resolver()); |
- } |
- |
- // TODO(eroman): cleanup. |
- SyncMockProxyResolver* x; |
-}; |
- |
-// ResultFuture is a handle to get at the result from |
-// ProxyService::ResolveProxyForURL() that ran on another thread. |
-class ResultFuture : public base::RefCountedThreadSafe<ResultFuture> { |
- public: |
- // |service| is the ProxyService to issue requests on, and |io_message_loop| |
- // is the message loop where ProxyService lives. |
- ResultFuture(MessageLoop* io_message_loop, |
- net::ProxyService* service) |
- : io_message_loop_(io_message_loop), |
- service_(service), |
- request_(NULL), |
- ALLOW_THIS_IN_INITIALIZER_LIST( |
- callback_(this, &ResultFuture::OnCompletion)), |
- completion_(true, false), |
- cancelled_(false, false), |
- started_(false, false), |
- did_complete_(false) { |
- } |
- |
- // Block until the request has completed, then return the result. |
- int GetResultCode() { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- WaitUntilCompleted(); |
- return result_code_; |
- } |
- |
- // Block until the request has completed, then return the result. |
- const net::ProxyInfo& GetProxyInfo() { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- WaitUntilCompleted(); |
- return proxy_info_; |
- } |
- |
- // Cancel this request (wait until the cancel has been issued before |
- // returning). |
- void Cancel() { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
- this, &ResultFuture::DoCancel)); |
- cancelled_.Wait(); |
- } |
- |
- // Return true if the request has already completed. |
- bool IsCompleted() { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- return did_complete_; |
- } |
- |
- // Wait until the ProxyService completes this request. |
- void WaitUntilCompleted() { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- completion_.Wait(); |
- DCHECK(did_complete_); |
- } |
- |
- private: |
- friend class ProxyServiceWithFutures; |
- |
- typedef int (net::ProxyService::*RequestMethod)(const GURL&, net::ProxyInfo*, |
- net::CompletionCallback*, net::ProxyService::PacRequest**); |
- |
- void StartResolve(const GURL& url) { |
- StartRequest(url, &net::ProxyService::ResolveProxy); |
- } |
- |
- // |proxy_info| is the *previous* result (that we are reconsidering). |
- void StartReconsider(const GURL& url, const net::ProxyInfo& proxy_info) { |
- proxy_info_ = proxy_info; |
- StartRequest(url, &net::ProxyService::ReconsiderProxyAfterError); |
- } |
- |
- // Start the request. Return once ProxyService::GetProxyForURL() or |
- // ProxyService::ReconsiderProxyAfterError() returns. |
- void StartRequest(const GURL& url, RequestMethod method) { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
- this, &ResultFuture::DoStartRequest, url, method)); |
- started_.Wait(); |
- } |
- |
- void StartResetConfigService( |
- net::ProxyConfigService* new_proxy_config_service) { |
- DCHECK(MessageLoop::current() != io_message_loop_); |
- io_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
- this, &ResultFuture::DoResetConfigService, new_proxy_config_service)); |
- started_.Wait(); |
- } |
- |
- // Called on |io_message_loop_|. |
- void DoStartRequest(const GURL& url, RequestMethod method) { |
- DCHECK(MessageLoop::current() == io_message_loop_); |
- int rv = (service_->*method)(url, &proxy_info_, &callback_, &request_); |
- if (rv != net::ERR_IO_PENDING) { |
- // Completed synchronously. |
- OnCompletion(rv); |
+ callback->Run(rv); |
} |
- started_.Signal(); |
- } |
- // Called on |io_message_loop_|. |
- void DoResetConfigService(net::ProxyConfigService* new_proxy_config_service) { |
- DCHECK(MessageLoop::current() == io_message_loop_); |
- service_->ResetConfigService(new_proxy_config_service); |
- started_.Signal(); |
- OnCompletion(0); |
- } |
+ private: |
+ MockAsyncProxyResolverBase* resolver_; |
+ const GURL url_; |
+ net::ProxyInfo* results_; |
+ net::CompletionCallback* callback_; |
+ MessageLoop* origin_loop_; |
+ }; |
- // Called on |io_message_loop_|. |
- void DoCancel() { |
- DCHECK(MessageLoop::current() == io_message_loop_); |
- if (!did_complete_) |
- service_->CancelPacRequest(request_); |
- cancelled_.Signal(); |
- } |
+ typedef std::vector<scoped_refptr<Request> > RequestsList; |
- // Called on |io_message_loop_|. |
- void OnCompletion(int result) { |
- DCHECK(MessageLoop::current() == io_message_loop_); |
- DCHECK(!did_complete_); |
- did_complete_ = true; |
- result_code_ = result; |
- request_ = NULL; |
- completion_.Signal(); |
- } |
+ // ProxyResolver implementation: |
+ virtual int GetProxyForURL(const GURL& url, |
+ net::ProxyInfo* results, |
+ net::CompletionCallback* callback, |
+ RequestHandle* request_handle) { |
+ scoped_refptr<Request> request = new Request(this, url, results, callback); |
+ pending_requests_.push_back(request); |
- // The message loop where the ProxyService lives. |
- MessageLoop* io_message_loop_; |
+ if (request_handle) |
+ *request_handle = reinterpret_cast<RequestHandle>(request.get()); |
- // The proxy service that started this request. |
- net::ProxyService* service_; |
- |
- // The in-progress request. |
- net::ProxyService::PacRequest* request_; |
- |
- net::CompletionCallbackImpl<ResultFuture> callback_; |
- base::WaitableEvent completion_; |
- base::WaitableEvent cancelled_; |
- base::WaitableEvent started_; |
- bool did_complete_; |
- |
- // Results from the request. |
- int result_code_; |
- net::ProxyInfo proxy_info_; |
-}; |
- |
-// Wraps a ProxyService running on its own IO thread. |
-class ProxyServiceWithFutures { |
- public: |
- ProxyServiceWithFutures(net::ProxyConfigService* config_service, |
- net::ProxyResolver* resolver) |
- : io_thread_("IO_Thread"), |
- io_thread_state_(new IOThreadState) { |
- base::Thread::Options options; |
- options.message_loop_type = MessageLoop::TYPE_IO; |
- io_thread_.StartWithOptions(options); |
- |
- // Initialize state that lives on |io_thread_|. |
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
- io_thread_state_.get(), &IOThreadState::DoInit, |
- config_service, resolver)); |
- io_thread_state_->event.Wait(); |
+ // Test code completes the request by calling request->CompleteNow(). |
+ return net::ERR_IO_PENDING; |
} |
- ~ProxyServiceWithFutures() { |
- // Destroy state that lives on |io_thread_|. |
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
- io_thread_state_.get(), &IOThreadState::DoDestroy)); |
- io_thread_state_->event.Wait(); |
+ virtual void CancelRequest(RequestHandle request_handle) { |
+ scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle); |
+ cancelled_requests_.push_back(request); |
+ RemovePendingRequest(request); |
} |
- // Start the request on |io_thread_|, and return a handle that can be |
- // used to access the results. The caller is responsible for freeing |
- // the ResultFuture. |
- void ResolveProxy(scoped_refptr<ResultFuture>* result, const GURL& url) { |
- *result = new ResultFuture(io_thread_.message_loop(), |
- io_thread_state_->service); |
- (*result)->StartResolve(url); |
+ virtual void SetPacScriptByUrlInternal(const GURL& pac_url) { |
+ pac_url_ = pac_url; |
} |
- // Same as above, but for "ReconsiderProxyAfterError()". |
- void ReconsiderProxyAfterError(scoped_refptr<ResultFuture>* result, |
- const GURL& url, |
- const net::ProxyInfo& proxy_info) { |
- *result = new ResultFuture(io_thread_.message_loop(), |
- io_thread_state_->service); |
- (*result)->StartReconsider(url, proxy_info); |
+ virtual void SetPacScriptByDataInternal(const std::string& bytes) { |
+ pac_bytes_ = bytes; |
} |
- void ResetConfigService(scoped_refptr<ResultFuture>* result, |
- net::ProxyConfigService* new_proxy_config_service) { |
- *result = new ResultFuture(io_thread_.message_loop(), |
- io_thread_state_->service); |
- (*result)->StartResetConfigService(new_proxy_config_service); |
+ const RequestsList& pending_requests() const { |
+ return pending_requests_; |
} |
- void SetProxyScriptFetcher(net::ProxyScriptFetcher* proxy_script_fetcher) { |
- io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
- io_thread_state_.get(), &IOThreadState::DoSetProxyScriptFetcher, |
- proxy_script_fetcher)); |
- io_thread_state_->event.Wait(); |
+ const RequestsList& cancelled_requests() const { |
+ return cancelled_requests_; |
} |
- private: |
- // Class that encapsulates the state living on IO thread. It needs to be |
- // ref-counted for posting tasks. |
- class IOThreadState : public base::RefCountedThreadSafe<IOThreadState> { |
- public: |
- IOThreadState() : event(false, false), service(NULL) {} |
- |
- void DoInit(net::ProxyConfigService* config_service, |
- net::ProxyResolver* resolver) { |
- service = new net::ProxyService(config_service, resolver); |
- event.Signal(); |
- } |
- |
- void DoDestroy() { |
- delete service; |
- service = NULL; |
- event.Signal(); |
- } |
- |
- void DoSetProxyScriptFetcher( |
- net::ProxyScriptFetcher* proxy_script_fetcher) { |
- service->SetProxyScriptFetcher(proxy_script_fetcher); |
- event.Signal(); |
- } |
- |
- base::WaitableEvent event; |
- net::ProxyService* service; |
- }; |
- |
- base::Thread io_thread_; |
- scoped_refptr<IOThreadState> io_thread_state_; // Lives on |io_thread_|. |
-}; |
- |
-// Wrapper around ProxyServiceWithFutures to do one request at a time. |
-class SyncProxyService { |
- public: |
- SyncProxyService(net::ProxyConfigService* config_service, |
- net::ProxyResolver* resolver) |
- : service_(config_service, resolver) { |
+ const GURL& pac_url() const { |
+ return pac_url_; |
} |
- int ResolveProxy(const GURL& url, net::ProxyInfo* proxy_info) { |
- scoped_refptr<ResultFuture> result; |
- service_.ResolveProxy(&result, url); |
- *proxy_info = result->GetProxyInfo(); |
- return result->GetResultCode(); |
+ const std::string& pac_bytes() const { |
+ return pac_bytes_; |
} |
- int ReconsiderProxyAfterError(const GURL& url, net::ProxyInfo* proxy_info) { |
- scoped_refptr<ResultFuture> result; |
- service_.ReconsiderProxyAfterError(&result, url, *proxy_info); |
- *proxy_info = result->GetProxyInfo(); |
- return result->GetResultCode(); |
+ void RemovePendingRequest(Request* request) { |
+ RequestsList::iterator it = std::find( |
+ pending_requests_.begin(), pending_requests_.end(), request); |
+ DCHECK(it != pending_requests_.end()); |
+ pending_requests_.erase(it); |
} |
- int ResetConfigService(net::ProxyConfigService* new_proxy_config_service) { |
- scoped_refptr<ResultFuture> result; |
- service_.ResetConfigService(&result, new_proxy_config_service); |
- return result->GetResultCode(); |
- } |
+ protected: |
+ explicit MockAsyncProxyResolverBase(bool expects_pac_bytes) |
+ : net::ProxyResolver(expects_pac_bytes) {} |
private: |
- ProxyServiceWithFutures service_; |
+ RequestsList pending_requests_; |
+ RequestsList cancelled_requests_; |
+ GURL pac_url_; |
+ std::string pac_bytes_; |
}; |
-// A ProxyResolver which can be set to block upon reaching GetProxyForURL. |
-class SyncBlockableProxyResolver : public net::ProxyResolver { |
+class MockAsyncProxyResolver : public MockAsyncProxyResolverBase { |
public: |
- SyncBlockableProxyResolver() |
- : net::ProxyResolver(false /*expects_pac_bytes*/), |
- should_block_(false), |
- unblocked_(true, true), |
- blocked_(true, false) { |
- } |
- |
- void Block() { |
- should_block_ = true; |
- unblocked_.Reset(); |
- } |
- |
- void Unblock() { |
- should_block_ = false; |
- blocked_.Reset(); |
- unblocked_.Signal(); |
- } |
- |
- void WaitUntilBlocked() { |
- blocked_.Wait(); |
- } |
- |
- // net::ProxyResolver implementation: |
- virtual int GetProxyForURL(const GURL& query_url, |
- net::ProxyInfo* results, |
- net::CompletionCallback* callback, |
- RequestHandle* request) { |
- if (should_block_) { |
- blocked_.Signal(); |
- unblocked_.Wait(); |
- } |
- |
- results->UseNamedProxy(query_url.host()); |
- return net::OK; |
- } |
- |
- virtual void CancelRequest(RequestHandle request) { |
- NOTREACHED(); |
- } |
- |
- virtual void SetPacScriptByUrlInternal(const GURL& pac_url) {} |
- |
- private: |
- bool should_block_; |
- base::WaitableEvent unblocked_; |
- base::WaitableEvent blocked_; |
+ MockAsyncProxyResolver() |
+ : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {} |
}; |
-class BlockableProxyResolver : public net::SingleThreadedProxyResolver { |
+class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase { |
public: |
- BlockableProxyResolver() |
- : net::SingleThreadedProxyResolver(new SyncBlockableProxyResolver) { |
- x = reinterpret_cast<SyncBlockableProxyResolver*>(resolver()); |
- } |
- |
- // TODO(eroman): cleanup. |
- SyncBlockableProxyResolver* x; |
+ MockAsyncProxyResolverExpectsBytes() |
+ : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {} |
}; |
-// A mock ProxyResolverWithoutFetch which concatenates the query's host with |
-// the last download PAC contents. This way the result describes what the last |
-// downloaded PAC script's contents were, in addition to the query url itself. |
-class SyncMockProxyResolverWithoutFetch : public net::ProxyResolver { |
- public: |
- SyncMockProxyResolverWithoutFetch() |
- : net::ProxyResolver(true /*expects_pac_bytes*/), |
- last_pac_contents_("NONE") {} |
- |
- // net::ProxyResolver implementation: |
- virtual int GetProxyForURL(const GURL& query_url, |
- net::ProxyInfo* results, |
- net::CompletionCallback* callback, |
- RequestHandle* request) { |
- results->UseNamedProxy(last_pac_contents_ + "." + query_url.host()); |
- return net::OK; |
- } |
- |
- virtual void SetPacScriptByDataInternal(const std::string& bytes) { |
- last_pac_contents_ = bytes; |
- } |
- |
- virtual void CancelRequest(RequestHandle request) { |
- NOTREACHED(); |
- } |
- |
- private: |
- std::string last_pac_contents_; |
-}; |
- |
-class MockProxyResolverWithoutFetch : public net::SingleThreadedProxyResolver { |
- public: |
- MockProxyResolverWithoutFetch() |
- : net::SingleThreadedProxyResolver( |
- new SyncMockProxyResolverWithoutFetch) { |
- x = reinterpret_cast<SyncMockProxyResolverWithoutFetch*>(resolver()); |
- } |
- |
- // TODO(eroman): cleanup. |
- SyncMockProxyResolverWithoutFetch* x; |
-}; |
- |
- |
} // namespace |
// A mock ProxyScriptFetcher. No result will be returned to the fetch client |
// until we call NotifyFetchCompletion() to set the results. |
class MockProxyScriptFetcher : public net::ProxyScriptFetcher { |
public: |
- MockProxyScriptFetcher() : pending_request_loop_(NULL), |
- pending_request_callback_(NULL), pending_request_bytes_(NULL) {} |
+ MockProxyScriptFetcher() |
+ : pending_request_callback_(NULL), pending_request_bytes_(NULL) { |
+ } |
// net::ProxyScriptFetcher implementation. |
- virtual void Fetch(const GURL& url, std::string* bytes, |
+ virtual void Fetch(const GURL& url, |
+ std::string* bytes, |
net::CompletionCallback* callback) { |
- DCHECK(!HasPendingRequest()); |
+ DCHECK(!has_pending_request()); |
// Save the caller's information, and have them wait. |
- pending_request_loop_ = MessageLoop::current(); |
pending_request_url_ = url; |
pending_request_callback_ = callback; |
pending_request_bytes_ = bytes; |
} |
void NotifyFetchCompletion(int result, const std::string& bytes) { |
- DCHECK(HasPendingRequest()); |
- pending_request_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
- this, &MockProxyScriptFetcher::DoNotifyFetchCompletion, result, bytes)); |
+ DCHECK(has_pending_request()); |
+ *pending_request_bytes_ = bytes; |
+ pending_request_callback_->Run(result); |
} |
virtual void Cancel() {} |
- private: |
- // Runs on |pending_request_loop_|. |
- void DoNotifyFetchCompletion(int result, const std::string& bytes) { |
- DCHECK(HasPendingRequest()); |
- *pending_request_bytes_ = bytes; |
- pending_request_callback_->Run(result); |
+ const GURL& pending_request_url() const { |
+ return pending_request_url_; |
} |
- bool HasPendingRequest() const { |
- return pending_request_loop_ != NULL; |
+ bool has_pending_request() const { |
+ return pending_request_callback_ != NULL; |
} |
- MessageLoop* pending_request_loop_; |
+ private: |
GURL pending_request_url_; |
net::CompletionCallback* pending_request_callback_; |
std::string* pending_request_bytes_; |
@@ -508,14 +201,17 @@ |
MockProxyScriptFetcher* remover) {} |
TEST(ProxyServiceTest, Direct) { |
- SyncProxyService service(new MockProxyConfigService, |
- new MockProxyResolver); |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
+ net::ProxyService service(new MockProxyConfigService, resolver); |
GURL url("http://www.google.com/"); |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_TRUE(resolver->pending_requests().empty()); |
+ |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -523,17 +219,26 @@ |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- SyncProxyService service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
GURL url("http://www.google.com/"); |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(url, &info, &callback, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("foopy"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ EXPECT_EQ(net::OK, callback.WaitForResult()); |
EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy:80", info.proxy_server().ToURI()); |
} |
@@ -541,59 +246,86 @@ |
TEST(ProxyServiceTest, PAC_FailoverToDirect) { |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy:8080"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
+ net::ProxyService service(config_service, resolver); |
- SyncProxyService service(config_service, resolver); |
- |
GURL url("http://www.google.com/"); |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy:8080", info.proxy_server().ToURI()); |
// Now, imagine that connecting to foopy:8080 fails. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback2; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
-TEST(ProxyServiceTest, PAC_FailsToDownload) { |
- // Test what happens when we fail to download the PAC URL. |
+TEST(ProxyServiceTest, ProxyResolverFails) { |
+ // Test what happens when the ProxyResolver fails (this could represent |
+ // a failure to download the PAC script in the case of ProxyResolvers which |
+ // do the fetch internally.) |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy:8080"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
- resolver->x->fail_get_proxy_for_url = true; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- SyncProxyService service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
- // The first resolve fails in the MockProxyResolver. |
+ // Start first resolve request. |
GURL url("http://www.google.com/"); |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::ERR_FAILED); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Fail the first resolve request in MockAsyncProxyResolver. |
+ resolver->pending_requests()[0]->CompleteNow(net::ERR_FAILED); |
+ |
+ EXPECT_EQ(net::ERR_FAILED, callback1.WaitForResult()); |
+ |
// The second resolve request will automatically select direct connect, |
// because it has cached the configuration as being bad. |
- rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback2; |
+ rv = service.ResolveProxy(url, &info, &callback2, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
+ EXPECT_TRUE(resolver->pending_requests().empty()); |
- resolver->x->fail_get_proxy_for_url = false; |
- resolver->x->info.UseNamedProxy("foopy_valid:8080"); |
- |
// But, if that fails, then we should give the proxy config another shot |
// since we have never tried it with this URL before. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback3; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ EXPECT_EQ(net::OK, callback3.WaitForResult()); |
EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI()); |
} |
@@ -605,56 +337,73 @@ |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy1:8080;foopy2:9090"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
- resolver->x->fail_get_proxy_for_url = false; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- SyncProxyService service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
GURL url("http://www.google.com/"); |
// Get the proxy information. |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info.is_direct()); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
// The first item is valid. |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
+ EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
// Fake an error on the proxy. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback2; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); |
+ EXPECT_EQ(net::OK, rv); |
// The second proxy should be specified. |
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); |
- // Create a new resolver that returns 3 proxies. The second one is already |
- // known to be bad. |
- config_service->config.pac_url = GURL("http://foopy/proxy.pac"); |
- resolver->x->info.UseNamedProxy("foopy3:7070;foopy1:8080;foopy2:9090"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
- resolver->x->fail_get_proxy_for_url = false; |
+ TestCompletionCallback callback3; |
+ rv = service.ResolveProxy(url, &info, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
- rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver -- the second result is already known |
+ // to be bad. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy3:7070;foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ EXPECT_EQ(net::OK, callback3.WaitForResult()); |
EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI()); |
// We fake another error. It should now try the third one. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback4; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); |
// Fake another error, the last proxy is gone, the list should now be empty. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); // We try direct. |
+ TestCompletionCallback callback5; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback5, NULL); |
+ EXPECT_EQ(net::OK, rv); // We try direct. |
EXPECT_TRUE(info.is_direct()); |
// If it fails again, we don't have anything else to try. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::ERR_FAILED); // We try direct. |
+ TestCompletionCallback callback6; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback6, NULL); |
+ EXPECT_EQ(net::ERR_FAILED, rv); |
// TODO(nsylvain): Test that the proxy can be retried after the delay. |
} |
@@ -665,46 +414,76 @@ |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy1:8080;foopy2:9090"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
- resolver->x->fail_get_proxy_for_url = false; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- SyncProxyService service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
GURL url("http://www.google.com/"); |
// Get the proxy information. |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info.is_direct()); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ // Set the result in proxy resolver. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
// The first item is valid. |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
+ EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
// Fake an error on the proxy, and also a new configuration on the proxy. |
config_service->config = net::ProxyConfig(); |
config_service->config.pac_url = GURL("http://foopy-new/proxy.pac"); |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback2; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ EXPECT_EQ(GURL("http://foopy-new/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
// The first proxy is still there since the configuration changed. |
+ EXPECT_EQ(net::OK, callback2.WaitForResult()); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
// We fake another error. It should now ignore the first one. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback3; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback3, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI()); |
// We simulate a new configuration. |
config_service->config = net::ProxyConfig(); |
config_service->config.pac_url = GURL("http://foopy-new2/proxy.pac"); |
- // We fake anothe error. It should go back to the first proxy. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ // We fake another error. It should go back to the first proxy. |
+ TestCompletionCallback callback4; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback4, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ EXPECT_EQ(net::OK, callback4.WaitForResult()); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
} |
@@ -714,27 +493,35 @@ |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolver* resolver = new MockProxyResolver; |
- resolver->x->info.UseNamedProxy("foopy1:8080;foopy2:9090"); |
- resolver->x->info_predicate_query_host = "www.google.com"; |
- resolver->x->fail_get_proxy_for_url = false; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- SyncProxyService service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
GURL url("http://www.google.com/"); |
// Get the proxy information. |
net::ProxyInfo info; |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info.is_direct()); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy(url, &info, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), resolver->pac_url()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
// The first item is valid. |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
+ EXPECT_FALSE(info.is_direct()); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
// Fake a proxy error. |
- rv = service.ReconsiderProxyAfterError(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback2; |
+ rv = service.ReconsiderProxyAfterError(url, &info, &callback2, NULL); |
+ EXPECT_EQ(net::OK, rv); |
// The first proxy is ignored, and the second one is selected. |
EXPECT_FALSE(info.is_direct()); |
@@ -742,31 +529,46 @@ |
// Fake a PAC failure. |
net::ProxyInfo info2; |
- resolver->x->fail_get_proxy_for_url = true; |
- rv = service.ResolveProxy(url, &info2); |
- EXPECT_EQ(rv, net::ERR_FAILED); |
+ TestCompletionCallback callback3; |
+ rv = service.ResolveProxy(url, &info2, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ resolver->pending_requests()[0]->CompleteNow(net::ERR_FAILED); |
+ |
// No proxy servers are returned. It's a direct connection. |
+ EXPECT_EQ(net::ERR_FAILED, callback3.WaitForResult()); |
EXPECT_TRUE(info2.is_direct()); |
- // The PAC is now fixed and will return a proxy server. |
+ // The PAC will now be fixed and will return a proxy server. |
// It should also clear the list of bad proxies. |
- resolver->x->fail_get_proxy_for_url = false; |
// Try to resolve, it will still return "direct" because we have no reason |
// to check the config since everything works. |
net::ProxyInfo info3; |
- rv = service.ResolveProxy(url, &info3); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback4; |
+ rv = service.ResolveProxy(url, &info3, &callback4, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info3.is_direct()); |
// But if the direct connection fails, we check if the ProxyInfo tried to |
// resolve the proxy before, and if not (like in this case), we give the |
// PAC another try. |
- rv = service.ReconsiderProxyAfterError(url, &info3); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback5; |
+ rv = service.ReconsiderProxyAfterError(url, &info3, &callback5, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(url, resolver->pending_requests()[0]->url()); |
+ |
+ resolver->pending_requests()[0]->results()->UseNamedProxy( |
+ "foopy1:8080;foopy2:9090"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
// The first proxy is still there since the list of bad proxies got cleared. |
+ EXPECT_EQ(net::OK, callback5.WaitForResult()); |
EXPECT_FALSE(info3.is_direct()); |
EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI()); |
} |
@@ -781,21 +583,23 @@ |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver()); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver()); |
GURL url("http://www.google.com/"); |
// Get the proxy information. |
- int rv = service.ResolveProxy(url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_FALSE(info.is_direct()); |
} |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver()); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver()); |
GURL test_url("local"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -803,11 +607,12 @@ |
config.proxy_bypass.push_back("*.org"); |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://www.webkit.org"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -816,11 +621,12 @@ |
config.proxy_bypass.push_back("7*"); |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://74.125.19.147"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -828,11 +634,12 @@ |
config.proxy_bypass.push_back("*.org"); |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://www.msn.com"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_FALSE(info.is_direct()); |
} |
@@ -840,11 +647,12 @@ |
config.proxy_bypass.push_back("*.MSN.COM"); |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://www.msnbc.msn.com"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -852,11 +660,12 @@ |
config.proxy_bypass.push_back("*.msn.com"); |
config.proxy_bypass_local_names = true; |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("HTTP://WWW.MSNBC.MSN.COM"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
} |
@@ -872,24 +681,27 @@ |
config.proxy_bypass.clear(); |
config.proxy_bypass.push_back("*.example.com:99"); |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
{ |
GURL test_url("http://www.example.com:99"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
{ |
GURL test_url("http://www.example.com:100"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_FALSE(info.is_direct()); |
} |
{ |
GURL test_url("http://www.example.com"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_FALSE(info.is_direct()); |
} |
} |
@@ -897,22 +709,24 @@ |
config.proxy_bypass.clear(); |
config.proxy_bypass.push_back("*.example.com:80"); |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://www.example.com"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
config.proxy_bypass.clear(); |
config.proxy_bypass.push_back("*.example.com"); |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
GURL test_url("http://www.example.com:99"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
@@ -920,18 +734,20 @@ |
config.proxy_bypass.clear(); |
config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99"); |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
{ |
GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
{ |
GURL test_url("http://[3ffe:2a00:100:7031::1]/"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_FALSE(info.is_direct()); |
} |
} |
@@ -942,18 +758,20 @@ |
config.proxy_bypass.clear(); |
config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]"); |
{ |
- SyncProxyService service(new MockProxyConfigService(config), |
- new MockProxyResolver); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
{ |
GURL test_url("http://[3ffe:2a00:100:7031::1]:99/"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
{ |
GURL test_url("http://[3ffe:2a00:100:7031::1]/"); |
- int rv = service.ResolveProxy(test_url, &info); |
- EXPECT_EQ(rv, net::OK); |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_TRUE(info.is_direct()); |
} |
} |
@@ -963,43 +781,51 @@ |
net::ProxyConfig config; |
config.proxy_rules.ParseFromString("http=foopy1:8080;https=foopy2:8080"); |
config.auto_detect = false; |
- |
- SyncProxyService service1(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url1("http://www.msn.com"); |
- net::ProxyInfo info1; |
- int rv = service1.ResolveProxy(test_url1, &info1); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info1.is_direct()); |
- EXPECT_EQ("foopy1:8080", info1.proxy_server().ToURI()); |
- |
- SyncProxyService service2(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url2("ftp://ftp.google.com"); |
- net::ProxyInfo info2; |
- rv = service2.ResolveProxy(test_url2, &info2); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_TRUE(info2.is_direct()); |
- EXPECT_EQ("direct://", info2.proxy_server().ToURI()); |
- |
- SyncProxyService service3(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url3("https://webbranch.techcu.com"); |
- net::ProxyInfo info3; |
- rv = service3.ResolveProxy(test_url3, &info3); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info3.is_direct()); |
- EXPECT_EQ("foopy2:8080", info3.proxy_server().ToURI()); |
- |
- config.proxy_rules.ParseFromString("foopy1:8080"); |
- SyncProxyService service4(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url4("www.microsoft.com"); |
- net::ProxyInfo info4; |
- rv = service4.ResolveProxy(test_url4, &info4); |
- EXPECT_EQ(rv, net::OK); |
- EXPECT_FALSE(info4.is_direct()); |
- EXPECT_EQ("foopy1:8080", info4.proxy_server().ToURI()); |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("http://www.msn.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
+ } |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("ftp://ftp.google.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_TRUE(info.is_direct()); |
+ EXPECT_EQ("direct://", info.proxy_server().ToURI()); |
+ } |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("https://webbranch.techcu.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); |
+ } |
+ { |
+ config.proxy_rules.ParseFromString("foopy1:8080"); |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("www.microsoft.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
+ } |
} |
// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries |
@@ -1011,181 +837,189 @@ |
EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME, |
config.proxy_rules.type); |
- SyncProxyService service1(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url1("http://www.msn.com"); |
- net::ProxyInfo info1; |
- int rv = service1.ResolveProxy(test_url1, &info1); |
- EXPECT_EQ(net::OK, rv); |
- EXPECT_FALSE(info1.is_direct()); |
- EXPECT_EQ("foopy1:8080", info1.proxy_server().ToURI()); |
- |
- SyncProxyService service2(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url2("ftp://ftp.google.com"); |
- net::ProxyInfo info2; |
- rv = service2.ResolveProxy(test_url2, &info2); |
- EXPECT_EQ(net::OK, rv); |
- EXPECT_FALSE(info2.is_direct()); |
- EXPECT_EQ("socks4://foopy2:1080", info2.proxy_server().ToURI()); |
- |
- SyncProxyService service3(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url3("https://webbranch.techcu.com"); |
- net::ProxyInfo info3; |
- rv = service3.ResolveProxy(test_url3, &info3); |
- EXPECT_EQ(net::OK, rv); |
- EXPECT_FALSE(info3.is_direct()); |
- EXPECT_EQ("socks4://foopy2:1080", info3.proxy_server().ToURI()); |
- |
- SyncProxyService service4(new MockProxyConfigService(config), |
- new MockProxyResolver); |
- GURL test_url4("www.microsoft.com"); |
- net::ProxyInfo info4; |
- rv = service4.ResolveProxy(test_url4, &info4); |
- EXPECT_EQ(net::OK, rv); |
- EXPECT_FALSE(info4.is_direct()); |
- EXPECT_EQ("socks4://foopy2:1080", info4.proxy_server().ToURI()); |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("http://www.msn.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
+ } |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("ftp://ftp.google.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); |
+ } |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("https://webbranch.techcu.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); |
+ } |
+ { |
+ net::ProxyService service(new MockProxyConfigService(config), |
+ new MockAsyncProxyResolver); |
+ GURL test_url("www.microsoft.com"); |
+ net::ProxyInfo info; |
+ TestCompletionCallback callback; |
+ int rv = service.ResolveProxy(test_url, &info, &callback, NULL); |
+ EXPECT_EQ(net::OK, rv); |
+ EXPECT_FALSE(info.is_direct()); |
+ EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI()); |
+ } |
} |
-// Test cancellation of a queued request. |
-TEST(ProxyServiceTest, CancelQueuedRequest) { |
+// Test cancellation of an in-progress request. |
+TEST(ProxyServiceTest, CancelInProgressRequest) { |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- BlockableProxyResolver* resolver = new BlockableProxyResolver; |
+ MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; |
- ProxyServiceWithFutures service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
- // Cause requests to pile up, by having them block in the PAC thread. |
- resolver->x->Block(); |
- |
// Start 3 requests. |
- scoped_refptr<ResultFuture> result1; |
- service.ResolveProxy(&result1, GURL("http://request1")); |
- scoped_refptr<ResultFuture> result2; |
- service.ResolveProxy(&result2, GURL("http://request2")); |
+ net::ProxyInfo info1; |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy( |
+ GURL("http://request1"), &info1, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); |
- scoped_refptr<ResultFuture> result3; |
- service.ResolveProxy(&result3, GURL("http://request3")); |
+ net::ProxyInfo info2; |
+ TestCompletionCallback callback2; |
+ net::ProxyService::PacRequest* request2; |
+ rv = service.ResolveProxy( |
+ GURL("http://request2"), &info2, &callback2, &request2); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ ASSERT_EQ(2u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); |
- // Wait until the first request has become blocked in the PAC thread. |
- resolver->x->WaitUntilBlocked(); |
+ net::ProxyInfo info3; |
+ TestCompletionCallback callback3; |
+ rv = service.ResolveProxy( |
+ GURL("http://request3"), &info3, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ ASSERT_EQ(3u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); |
// Cancel the second request |
- result2->Cancel(); |
+ service.CancelPacRequest(request2); |
- // Unblock the PAC thread. |
- resolver->x->Unblock(); |
+ ASSERT_EQ(2u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); |
+ EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url()); |
- // Wait for the final request to complete. |
- result3->WaitUntilCompleted(); |
+ // Complete the two un-cancelled requests. |
+ // We complete the last one first, just to mix it up a bit. |
+ resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80"); |
+ resolver->pending_requests()[1]->CompleteNow(net::OK); |
- // Verify that requests ran as expected. |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
- EXPECT_TRUE(result1->IsCompleted()); |
- EXPECT_EQ(net::OK, result1->GetResultCode()); |
- EXPECT_EQ("request1:80", result1->GetProxyInfo().proxy_server().ToURI()); |
+ // Complete and verify that requests ran as expected. |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
+ EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); |
- EXPECT_FALSE(result2->IsCompleted()); // Cancelled. |
+ EXPECT_FALSE(callback2.have_result()); // Cancelled. |
+ ASSERT_EQ(1u, resolver->cancelled_requests().size()); |
+ EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url()); |
- EXPECT_TRUE(result3->IsCompleted()); |
- EXPECT_EQ(net::OK, result3->GetResultCode()); |
- EXPECT_EQ("request3:80", result3->GetProxyInfo().proxy_server().ToURI()); |
+ EXPECT_EQ(net::OK, callback3.WaitForResult()); |
+ EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); |
} |
-// Test cancellation of an in-progress request. |
-TEST(ProxyServiceTest, CancelInprogressRequest) { |
- MockProxyConfigService* config_service = |
- new MockProxyConfigService("http://foopy/proxy.pac"); |
- |
- BlockableProxyResolver* resolver = new BlockableProxyResolver; |
- |
- ProxyServiceWithFutures service(config_service, resolver); |
- |
- // Cause requests to pile up, by having them block in the PAC thread. |
- resolver->x->Block(); |
- |
- // Start 3 requests. |
- scoped_refptr<ResultFuture> result1; |
- service.ResolveProxy(&result1, GURL("http://request1")); |
- |
- scoped_refptr<ResultFuture> result2; |
- service.ResolveProxy(&result2, GURL("http://request2")); |
- |
- scoped_refptr<ResultFuture> result3; |
- service.ResolveProxy(&result3, GURL("http://request3")); |
- |
- // Wait until the first request has become blocked in the PAC thread. |
- resolver->x->WaitUntilBlocked(); |
- |
- // Cancel the first request |
- result1->Cancel(); |
- |
- // Unblock the PAC thread. |
- resolver->x->Unblock(); |
- |
- // Wait for the final request to complete. |
- result3->WaitUntilCompleted(); |
- |
- // Verify that requests ran as expected. |
- |
- EXPECT_FALSE(result1->IsCompleted()); // Cancelled. |
- |
- EXPECT_TRUE(result2->IsCompleted()); |
- EXPECT_EQ(net::OK, result2->GetResultCode()); |
- EXPECT_EQ("request2:80", result2->GetProxyInfo().proxy_server().ToURI()); |
- |
- EXPECT_TRUE(result3->IsCompleted()); |
- EXPECT_EQ(net::OK, result3->GetResultCode()); |
- EXPECT_EQ("request3:80", result3->GetProxyInfo().proxy_server().ToURI()); |
-} |
- |
// Test the initial PAC download for ProxyResolverWithoutFetch. |
TEST(ProxyServiceTest, InitialPACScriptDownload) { |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolverWithoutFetch* resolver = new MockProxyResolverWithoutFetch; |
+ MockAsyncProxyResolverExpectsBytes* resolver = |
+ new MockAsyncProxyResolverExpectsBytes; |
- ProxyServiceWithFutures service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; |
service.SetProxyScriptFetcher(fetcher); |
// Start 3 requests. |
- scoped_refptr<ResultFuture> result1; |
- service.ResolveProxy(&result1, GURL("http://request1")); |
- scoped_refptr<ResultFuture> result2; |
- service.ResolveProxy(&result2, GURL("http://request2")); |
+ net::ProxyInfo info1; |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy( |
+ GURL("http://request1"), &info1, &callback1, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
- scoped_refptr<ResultFuture> result3; |
- service.ResolveProxy(&result3, GURL("http://request3")); |
+ // The first request should have triggered download of PAC script. |
+ EXPECT_TRUE(fetcher->has_pending_request()); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); |
+ net::ProxyInfo info2; |
+ TestCompletionCallback callback2; |
+ rv = service.ResolveProxy( |
+ GURL("http://request2"), &info2, &callback2, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ net::ProxyInfo info3; |
+ TestCompletionCallback callback3; |
+ rv = service.ResolveProxy( |
+ GURL("http://request3"), &info3, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ // Nothing has been sent to the resolver yet. |
+ EXPECT_TRUE(resolver->pending_requests().empty()); |
+ |
// At this point the ProxyService should be waiting for the |
// ProxyScriptFetcher to invoke its completion callback, notifying it of |
// PAC script download completion. |
fetcher->NotifyFetchCompletion(net::OK, "pac-v1"); |
- // Complete all the requests. |
- result3->WaitUntilCompleted(); |
+ // Now that the PAC script is downloaded, everything should have been sent |
+ // over to the proxy resolver. |
+ EXPECT_EQ("pac-v1", resolver->pac_bytes()); |
+ ASSERT_EQ(3u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url()); |
+ EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url()); |
+ EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url()); |
- EXPECT_TRUE(result1->IsCompleted()); |
- EXPECT_EQ(net::OK, result1->GetResultCode()); |
- EXPECT_EQ("pac-v1.request1:80", |
- result1->GetProxyInfo().proxy_server().ToURI()); |
+ // Complete all the requests (in some order). |
+ // Note that as we complete requests, they shift up in |pending_requests()|. |
- EXPECT_TRUE(result2->IsCompleted()); |
- EXPECT_EQ(net::OK, result2->GetResultCode()); |
- EXPECT_EQ("pac-v1.request2:80", |
- result2->GetProxyInfo().proxy_server().ToURI()); |
+ resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80"); |
+ resolver->pending_requests()[2]->CompleteNow(net::OK); |
- EXPECT_TRUE(result3->IsCompleted()); |
- EXPECT_EQ(net::OK, result3->GetResultCode()); |
- EXPECT_EQ("pac-v1.request3:80", |
- result3->GetProxyInfo().proxy_server().ToURI()); |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
+ |
+ // Complete and verify that requests ran as expected. |
+ EXPECT_EQ(net::OK, callback1.WaitForResult()); |
+ EXPECT_EQ("request1:80", info1.proxy_server().ToURI()); |
+ |
+ EXPECT_EQ(net::OK, callback2.WaitForResult()); |
+ EXPECT_EQ("request2:80", info2.proxy_server().ToURI()); |
+ |
+ EXPECT_EQ(net::OK, callback3.WaitForResult()); |
+ EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); |
} |
// Test cancellation of a request, while the PAC script is being fetched. |
@@ -1193,61 +1027,90 @@ |
MockProxyConfigService* config_service = |
new MockProxyConfigService("http://foopy/proxy.pac"); |
- MockProxyResolverWithoutFetch* resolver = new MockProxyResolverWithoutFetch; |
+ MockAsyncProxyResolverExpectsBytes* resolver = |
+ new MockAsyncProxyResolverExpectsBytes; |
- ProxyServiceWithFutures service(config_service, resolver); |
+ net::ProxyService service(config_service, resolver); |
MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher; |
service.SetProxyScriptFetcher(fetcher); |
// Start 3 requests. |
- scoped_refptr<ResultFuture> result1; |
- service.ResolveProxy(&result1, GURL("http://request1")); |
+ net::ProxyInfo info1; |
+ TestCompletionCallback callback1; |
+ net::ProxyService::PacRequest* request1; |
+ int rv = service.ResolveProxy( |
+ GURL("http://request1"), &info1, &callback1, &request1); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
- scoped_refptr<ResultFuture> result2; |
- service.ResolveProxy(&result2, GURL("http://request2")); |
+ // The first request should have triggered download of PAC script. |
+ EXPECT_TRUE(fetcher->has_pending_request()); |
+ EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url()); |
- scoped_refptr<ResultFuture> result3; |
- service.ResolveProxy(&result3, GURL("http://request3")); |
+ net::ProxyInfo info2; |
+ TestCompletionCallback callback2; |
+ net::ProxyService::PacRequest* request2; |
+ rv = service.ResolveProxy( |
+ GURL("http://request2"), &info2, &callback2, &request2); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ net::ProxyInfo info3; |
+ TestCompletionCallback callback3; |
+ rv = service.ResolveProxy( |
+ GURL("http://request3"), &info3, &callback3, NULL); |
+ EXPECT_EQ(net::ERR_IO_PENDING, rv); |
+ |
+ // Nothing has been sent to the resolver yet. |
+ EXPECT_TRUE(resolver->pending_requests().empty()); |
+ |
// Cancel the first 2 requests. |
- result1->Cancel(); |
- result2->Cancel(); |
+ service.CancelPacRequest(request1); |
+ service.CancelPacRequest(request2); |
// At this point the ProxyService should be waiting for the |
// ProxyScriptFetcher to invoke its completion callback, notifying it of |
// PAC script download completion. |
fetcher->NotifyFetchCompletion(net::OK, "pac-v1"); |
+ // Now that the PAC script is downloaded, everything should have been sent |
+ // over to the proxy resolver. |
+ EXPECT_EQ("pac-v1", resolver->pac_bytes()); |
+ ASSERT_EQ(1u, resolver->pending_requests().size()); |
+ EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url()); |
+ |
// Complete all the requests. |
- result3->WaitUntilCompleted(); |
+ resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80"); |
+ resolver->pending_requests()[0]->CompleteNow(net::OK); |
- EXPECT_FALSE(result1->IsCompleted()); // Cancelled. |
- EXPECT_FALSE(result2->IsCompleted()); // Cancelled. |
+ EXPECT_EQ(net::OK, callback3.WaitForResult()); |
+ EXPECT_EQ("request3:80", info3.proxy_server().ToURI()); |
- EXPECT_TRUE(result3->IsCompleted()); |
- EXPECT_EQ(net::OK, result3->GetResultCode()); |
- EXPECT_EQ("pac-v1.request3:80", |
- result3->GetProxyInfo().proxy_server().ToURI()); |
+ EXPECT_TRUE(resolver->cancelled_requests().empty()); |
+ |
+ EXPECT_FALSE(callback1.have_result()); // Cancelled. |
+ EXPECT_FALSE(callback2.have_result()); // Cancelled. |
} |
TEST(ProxyServiceTest, ResetProxyConfigService) { |
net::ProxyConfig config1; |
config1.proxy_rules.ParseFromString("foopy1:8080"); |
config1.auto_detect = false; |
- scoped_ptr<SyncProxyService> service( |
- new SyncProxyService(new MockProxyConfigService(config1), |
- new MockProxyResolverWithoutFetch)); |
+ net::ProxyService service(new MockProxyConfigService(config1), |
+ new MockAsyncProxyResolverExpectsBytes); |
net::ProxyInfo info; |
- service->ResolveProxy(GURL("http://request1"), &info); |
+ TestCompletionCallback callback1; |
+ int rv = service.ResolveProxy( |
+ GURL("http://request1"), &info, &callback1, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI()); |
net::ProxyConfig config2; |
config2.proxy_rules.ParseFromString("foopy2:8080"); |
config2.auto_detect = false; |
- int result = service->ResetConfigService(new MockProxyConfigService(config2)); |
- DCHECK(result == 0); |
- service->ResolveProxy(GURL("http://request2"), &info); |
+ service.ResetConfigService(new MockProxyConfigService(config2)); |
+ TestCompletionCallback callback2; |
+ rv = service.ResolveProxy(GURL("http://request2"), &info, &callback2, NULL); |
+ EXPECT_EQ(net::OK, rv); |
EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI()); |
} |