diff options
-rw-r--r-- | chrome/browser/net/predictor_unittest.cc | 7 | ||||
-rw-r--r-- | chrome/browser/sync/test/integration/sync_test.h | 1 | ||||
-rw-r--r-- | jingle/notifier/communicator/xmpp_connection_generator_unittest.cc | 1 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 101 | ||||
-rw-r--r-- | net/base/mapped_host_resolver_unittest.cc | 3 | ||||
-rw-r--r-- | net/base/mock_host_resolver.cc | 241 | ||||
-rw-r--r-- | net/base/mock_host_resolver.h | 85 | ||||
-rw-r--r-- | net/base/net_test_suite.cc | 1 | ||||
-rw-r--r-- | net/base/single_request_host_resolver_unittest.cc | 2 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 3 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_unittest.cc | 1 | ||||
-rw-r--r-- | net/net.gyp | 1 | ||||
-rw-r--r-- | net/proxy/proxy_resolver_js_bindings_unittest.cc | 31 | ||||
-rw-r--r-- | net/socket/socket_test_util.cc | 17 | ||||
-rw-r--r-- | net/socket/socks_client_socket_unittest.cc | 9 |
15 files changed, 313 insertions, 191 deletions
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc index 19bb21b..6e4e90c 100644 --- a/chrome/browser/net/predictor_unittest.cc +++ b/chrome/browser/net/predictor_unittest.cc @@ -116,12 +116,10 @@ TEST_F(PredictorTest, StartupShutdownTest) { TEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) { - scoped_refptr<net::WaitingHostResolverProc> resolver_proc( - new net::WaitingHostResolverProc(NULL)); - host_resolver_->Reset(resolver_proc); + scoped_ptr<net::HostResolver> host_resolver(new net::HangingHostResolver()); Predictor testing_master(true); - testing_master.SetHostResolver(host_resolver_.get()); + testing_master.SetHostResolver(host_resolver.get()); GURL localhost("http://localhost:80"); UrlList names; @@ -138,7 +136,6 @@ TEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) { testing_master.Shutdown(); // Clean up after ourselves. - resolver_proc->Signal(); MessageLoop::current()->RunAllPending(); } diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h index 609ba3e..73c03de 100644 --- a/chrome/browser/sync/test/integration/sync_test.h +++ b/chrome/browser/sync/test/integration/sync_test.h @@ -16,6 +16,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/process_util.h" +#include "base/task.h" #include "chrome/browser/sync/protocol/sync_protocol_error.h" #include "chrome/browser/sync/syncable/model_type.h" #include "net/base/mock_host_resolver.h" diff --git a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc b/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc index 04da3df..b57a3c3 100644 --- a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc +++ b/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc @@ -5,6 +5,7 @@ #include "jingle/notifier/communicator/xmpp_connection_generator.h" #include "base/basictypes.h" +#include "base/message_loop.h" #include "jingle/notifier/communicator/connection_options.h" #include "jingle/notifier/communicator/connection_settings.h" #include "net/base/host_port_pair.h" diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc index df38919..2922758 100644 --- a/net/base/host_resolver_impl_unittest.cc +++ b/net/base/host_resolver_impl_unittest.cc @@ -401,6 +401,47 @@ TEST_F(HostResolverImplTest, AsynchronousLookup) { EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); } + +// Using WaitingHostResolverProc you can simulate very long lookups. +class WaitingHostResolverProc : public HostResolverProc { + public: + explicit WaitingHostResolverProc(HostResolverProc* previous) + : HostResolverProc(previous), + is_waiting_(false, false), + is_signaled_(false, false) {} + + // Waits until a call to |Resolve| is blocked. It is recommended to always + // |Wait| before |Signal|, and required if issuing a series of two or more + // calls to |Signal|, because |WaitableEvent| does not count the number of + // signals. + void Wait() { + is_waiting_.Wait(); + } + + // Signals a waiting call to |Resolve|. + void Signal() { + is_signaled_.Signal(); + } + + // HostResolverProc methods: + virtual int Resolve(const std::string& host, + AddressFamily address_family, + HostResolverFlags host_resolver_flags, + AddressList* addrlist, + int* os_error) { + is_waiting_.Signal(); + is_signaled_.Wait(); + return ResolveUsingPrevious(host, address_family, host_resolver_flags, + addrlist, os_error); + } + + private: + virtual ~WaitingHostResolverProc() {} + + base::WaitableEvent is_waiting_; + base::WaitableEvent is_signaled_; +}; + TEST_F(HostResolverImplTest, CanceledAsynchronousLookup) { scoped_refptr<WaitingHostResolverProc> resolver_proc( new WaitingHostResolverProc(NULL)); @@ -422,11 +463,7 @@ TEST_F(HostResolverImplTest, CanceledAsynchronousLookup) { log.bound()); EXPECT_EQ(ERR_IO_PENDING, err); - // Make sure we will exit the queue even when callback is not called. - MessageLoop::current()->PostDelayedTask(FROM_HERE, - new MessageLoop::QuitTask(), - 1000); - MessageLoop::current()->Run(); + resolver_proc->Wait(); } resolver_proc->Signal(); @@ -753,8 +790,7 @@ TEST_F(HostResolverImplTest, CancelWithinCallback) { scoped_refptr<CapturingHostResolverProc> resolver_proc( new CapturingHostResolverProc(NULL)); - scoped_ptr<HostResolver> host_resolver( - CreateHostResolverImpl(resolver_proc)); + scoped_ptr<HostResolver> host_resolver(CreateHostResolverImpl(resolver_proc)); // The class will receive callbacks for when each resolve completes. It // checks that the right things happened. @@ -813,8 +849,7 @@ TEST_F(HostResolverImplTest, DeleteWithinCallback) { // The class will receive callbacks for when each resolve completes. It // checks that the right things happened. Note that the verifier holds the // only reference to |host_resolver|, so it can delete it within callback. - HostResolver* host_resolver = - CreateHostResolverImpl(resolver_proc); + HostResolver* host_resolver = CreateHostResolverImpl(resolver_proc); DeleteWithinCallbackVerifier verifier(host_resolver); // Start 4 requests, duplicating hosts "a". Since the resolver_proc is @@ -1139,10 +1174,7 @@ TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { scoped_refptr<WaitingHostResolverProc> resolver_proc( new WaitingHostResolverProc(NULL)); - HostCache* cache = HostCache::CreateDefaultCache(); - scoped_ptr<HostResolver> host_resolver( - new HostResolverImpl(resolver_proc, cache, kMaxJobs, kMaxRetryAttempts, - NULL)); + scoped_ptr<HostResolver> host_resolver(CreateHostResolverImpl(resolver_proc)); // Resolve "host1". HostResolver::RequestInfo info(HostPortPair("host1", 70)); @@ -1152,21 +1184,23 @@ TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + resolver_proc->Wait(); // Triggering an IP address change. NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); MessageLoop::current()->RunAllPending(); // Notification happens async. resolver_proc->Signal(); EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); - EXPECT_EQ(0u, cache->size()); + EXPECT_EQ(0u, host_resolver->GetHostCache()->size()); } // Obey pool constraints after IP address has changed. TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { scoped_refptr<WaitingHostResolverProc> resolver_proc( - new WaitingHostResolverProc(NULL)); - scoped_ptr<MockHostResolver> host_resolver(new MockHostResolver()); - host_resolver->Reset(resolver_proc); + new WaitingHostResolverProc(CreateCatchAllHostResolverProc())); + scoped_ptr<HostResolverImpl> host_resolver( + new HostResolverImpl(resolver_proc, HostCache::CreateDefaultCache(), + kMaxJobs, kMaxRetryAttempts, NULL)); const size_t kMaxOutstandingJobs = 1u; const size_t kMaxPendingRequests = 1000000u; // not relevant. @@ -1182,6 +1216,9 @@ TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + // Must wait before signal to ensure that the two signals don't get merged + // together. (Worker threads might not start until the last WaitForResult.) + resolver_proc->Wait(); // Triggering an IP address change. NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); MessageLoop::current()->RunAllPending(); // Notification happens async. @@ -1189,30 +1226,25 @@ TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); - // Don't bother with WaitingHostResolverProc anymore. - host_resolver->Reset(NULL); - rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + resolver_proc->Wait(); + resolver_proc->Signal(); EXPECT_EQ(OK, callback.WaitForResult()); } class ResolveWithinCallback : public CallbackRunner< Tuple1<int> > { public: - ResolveWithinCallback( - MockHostResolver* host_resolver, - const HostResolver::RequestInfo& info) - : host_resolver_(host_resolver), - info_(info) { - DCHECK(host_resolver); - } + explicit ResolveWithinCallback(const HostResolver::RequestInfo& info) + : info_(info) {} virtual void RunWithParams(const Tuple1<int>& params) { // Ditch the WaitingHostResolverProc so that the subsequent request // succeeds. - host_resolver_->Reset(NULL); callback_.RunWithParams(params); + host_resolver_.reset( + CreateHostResolverImpl(CreateCatchAllHostResolverProc())); EXPECT_EQ(ERR_IO_PENDING, host_resolver_->Resolve(info_, &addrlist_, &nested_callback_, NULL, BoundNetLog())); @@ -1227,33 +1259,32 @@ class ResolveWithinCallback : public CallbackRunner< Tuple1<int> > { } private: - MockHostResolver* const host_resolver_; const HostResolver::RequestInfo info_; AddressList addrlist_; TestOldCompletionCallback callback_; TestOldCompletionCallback nested_callback_; + scoped_ptr<HostResolver> host_resolver_; }; TEST_F(HostResolverImplTest, OnlyAbortExistingRequestsOnIPAddressChange) { scoped_refptr<WaitingHostResolverProc> resolver_proc( - new WaitingHostResolverProc(NULL)); - scoped_ptr<MockHostResolver> host_resolver(new MockHostResolver()); - host_resolver->Reset(resolver_proc); + new WaitingHostResolverProc(CreateCatchAllHostResolverProc())); + scoped_ptr<HostResolver> host_resolver(CreateHostResolverImpl(resolver_proc)); // Resolve "host1". HostResolver::RequestInfo info(HostPortPair("host1", 70)); - ResolveWithinCallback callback(host_resolver.get(), info); + ResolveWithinCallback callback(info); AddressList addrlist; int rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); + resolver_proc->Wait(); // Triggering an IP address change. NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); MessageLoop::current()->RunAllPending(); // Notification happens async. - EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); - resolver_proc->Signal(); + resolver_proc->Signal(); // release the thread from WorkerPool for cleanup EXPECT_EQ(OK, callback.WaitForNestedResult()); } diff --git a/net/base/mapped_host_resolver_unittest.cc b/net/base/mapped_host_resolver_unittest.cc index 8144b5c..e24fca3 100644 --- a/net/base/mapped_host_resolver_unittest.cc +++ b/net/base/mapped_host_resolver_unittest.cc @@ -1,9 +1,10 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/base/mapped_host_resolver.h" +#include "net/base/address_list.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" #include "net/base/net_log.h" diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc index 2e38dd9..87cb408 100644 --- a/net/base/mock_host_resolver.cc +++ b/net/base/mock_host_resolver.cc @@ -4,10 +4,15 @@ #include "net/base/mock_host_resolver.h" +#include "base/bind.h" +#include "base/location.h" #include "base/memory/ref_counted.h" +#include "base/message_loop.h" +#include "base/stl_util.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/threading/platform_thread.h" +#include "net/base/host_cache.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/base/sys_addrinfo.h" @@ -25,13 +30,11 @@ char* do_strdup(const char* src) { #endif } -// Fills |*addrlist| with a socket address for |host_list| which should be a -// comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets. -// If |canonical_name| is non-empty it is used as the DNS canonical name for -// the host. Returns OK on success, ERR_UNEXPECTED otherwise. -int CreateIPAddressList(const std::string& host_list, - const std::string& canonical_name, - AddressList* addrlist) { +} // namespace + +int ParseAddressList(const std::string& host_list, + const std::string& canonical_name, + AddressList* addrlist) { *addrlist = AddressList(); std::vector<std::string> addresses; base::SplitString(host_list, ',', &addresses); @@ -54,85 +57,156 @@ int CreateIPAddressList(const std::string& host_list, return OK; } -} // namespace - -MockHostResolverBase::~MockHostResolverBase() {} - -void MockHostResolverBase::Reset(HostResolverProc* interceptor) { - synchronous_mode_ = false; - - // At the root of the chain, map everything to localhost. - scoped_refptr<RuleBasedHostResolverProc> catchall( - new RuleBasedHostResolverProc(NULL)); -#if defined(OS_ANDROID) - // In Android emulator, the development machine's '127.0.0.1' is mapped to - // '10.0.2.2'. - catchall->AddRule("*", "10.0.2.2"); -#else - catchall->AddRule("*", "127.0.0.1"); -#endif - - // Next add a rules-based layer the use controls. - rules_ = new RuleBasedHostResolverProc(catchall); - - HostResolverProc* proc = rules_; - - // Lastly add the provided interceptor to the front of the chain. - if (interceptor) { - interceptor->SetPreviousProc(proc); - proc = interceptor; - } - - HostCache* cache = NULL; - - if (use_caching_) { - cache = new HostCache( - 100, // max entries. - base::TimeDelta::FromMinutes(1), - base::TimeDelta::FromSeconds(0)); - } +struct MockHostResolverBase::Request { + Request(const RequestInfo& req_info, + AddressList* addr, + OldCompletionCallback* cb) + : info(req_info), addresses(addr), callback(cb) {} + RequestInfo info; + AddressList* addresses; + OldCompletionCallback* callback; +}; - impl_.reset(new HostResolverImpl(proc, cache, 50u, 4u, NULL)); +MockHostResolverBase::~MockHostResolverBase() { + STLDeleteValues(&requests_); } int MockHostResolverBase::Resolve(const RequestInfo& info, AddressList* addresses, OldCompletionCallback* callback, - RequestHandle* out_req, + RequestHandle* handle, const BoundNetLog& net_log) { - if (synchronous_mode_) { - TestOldCompletionCallback sync_callback; - int rv = impl_->Resolve(info, addresses, &sync_callback, out_req, net_log); - if (rv == ERR_IO_PENDING) { - MessageLoop::ScopedNestableTaskAllower nestable(MessageLoop::current()); - return sync_callback.WaitForResult(); - } + DCHECK(CalledOnValidThread()); + size_t id = next_request_id_++; + FOR_EACH_OBSERVER(Observer, observers_, OnStartResolution(id, info)); + int rv = ResolveFromIPLiteralOrCache(info, addresses); + if (rv != ERR_DNS_CACHE_MISS) { + FOR_EACH_OBSERVER(Observer, observers_, + OnFinishResolutionWithStatus(id, rv == OK, info)); return rv; } - return impl_->Resolve(info, addresses, callback, out_req, net_log); + if (synchronous_mode_) { + return ResolveProc(id, info, addresses); + } + // Store the request for asynchronous resolution + Request* req = new Request(info, addresses, callback); + requests_[id] = req; + if (handle) + *handle = reinterpret_cast<RequestHandle>(id); + MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&MockHostResolverBase::ResolveNow, + AsWeakPtr(), + id)); + return ERR_IO_PENDING; } int MockHostResolverBase::ResolveFromCache(const RequestInfo& info, AddressList* addresses, const BoundNetLog& net_log) { - return impl_->ResolveFromCache(info, addresses, net_log); + DCHECK(CalledOnValidThread()); + size_t id = next_request_id_++; + FOR_EACH_OBSERVER(Observer, observers_, OnStartResolution(id, info)); + int rv = ResolveFromIPLiteralOrCache(info, addresses); + FOR_EACH_OBSERVER(Observer, observers_, + OnFinishResolutionWithStatus(id, rv == OK, info)); + return rv; } -void MockHostResolverBase::CancelRequest(RequestHandle req) { - impl_->CancelRequest(req); +void MockHostResolverBase::CancelRequest(RequestHandle handle) { + DCHECK(CalledOnValidThread()); + size_t id = reinterpret_cast<size_t>(handle); + RequestMap::iterator it = requests_.find(id); + if (it != requests_.end()) { + scoped_ptr<Request> req(it->second); + requests_.erase(it); + FOR_EACH_OBSERVER(Observer, observers_, OnCancelResolution(id, req->info)); + } } void MockHostResolverBase::AddObserver(Observer* observer) { - impl_->AddObserver(observer); + DCHECK(CalledOnValidThread()); + observers_.AddObserver(observer); } void MockHostResolverBase::RemoveObserver(Observer* observer) { - impl_->RemoveObserver(observer); + DCHECK(CalledOnValidThread()); + observers_.RemoveObserver(observer); } +HostCache* MockHostResolverBase::GetHostCache() { + return cache_.get(); +} + +// start id from 1 to distinguish from NULL RequestHandle MockHostResolverBase::MockHostResolverBase(bool use_caching) - : use_caching_(use_caching) { - Reset(NULL); + : synchronous_mode_(false), next_request_id_(1) { + rules_ = CreateCatchAllHostResolverProc(); + proc_ = rules_; + + if (use_caching) { + cache_.reset(new HostCache( + 100, // max entries. + base::TimeDelta::FromMinutes(1), + base::TimeDelta::FromSeconds(0))); + } + STLDeleteValues(&requests_); +} + +int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info, + AddressList* addresses) { + IPAddressNumber ip; + if (ParseIPLiteralToNumber(info.hostname(), &ip)) { + *addresses = AddressList::CreateFromIPAddressWithCname( + ip, info.port(), info.host_resolver_flags() & HOST_RESOLVER_CANONNAME); + return OK; + } + int rv = ERR_DNS_CACHE_MISS; + if (cache_.get() && info.allow_cached_response()) { + HostCache::Key key(info.hostname(), + info.address_family(), + info.host_resolver_flags()); + const HostCache::Entry* entry = cache_->Lookup(key, base::TimeTicks::Now()); + if (entry) { + rv = entry->error; + if (rv == OK) + *addresses = CreateAddressListUsingPort(entry->addrlist, info.port()); + } + } + return rv; +} + +int MockHostResolverBase::ResolveProc(size_t id, + const RequestInfo& info, + AddressList* addresses) { + AddressList addr; + int rv = proc_->Resolve(info.hostname(), + info.address_family(), + info.host_resolver_flags(), + &addr, + NULL); + if (cache_.get()) { + HostCache::Key key(info.hostname(), + info.address_family(), + info.host_resolver_flags()); + cache_->Set(key, rv, addr, base::TimeTicks::Now()); + } + if (rv == OK) + *addresses = CreateAddressListUsingPort(addr, info.port()); + FOR_EACH_OBSERVER(Observer, observers_, + OnFinishResolutionWithStatus(id, rv == OK, info)); + return rv; +} + +void MockHostResolverBase::ResolveNow(size_t id) { + RequestMap::iterator it = requests_.find(id); + if (it == requests_.end()) + return; // was canceled + + scoped_ptr<Request> req(it->second); + requests_.erase(it); + int rv = ResolveProc(id, req->info, req->addresses); + if (req->callback) + req->callback->Run(rv); } //----------------------------------------------------------------------------- @@ -273,9 +347,9 @@ int RuleBasedHostResolverProc::Resolve(const std::string& host, host_resolver_flags, addrlist, os_error); case Rule::kResolverTypeIPLiteral: - return CreateIPAddressList(effective_host, - r->canonical_name, - addrlist); + return ParseAddressList(effective_host, + r->canonical_name, + addrlist); default: NOTREACHED(); return ERR_UNEXPECTED; @@ -289,26 +363,35 @@ int RuleBasedHostResolverProc::Resolve(const std::string& host, RuleBasedHostResolverProc::~RuleBasedHostResolverProc() { } -//----------------------------------------------------------------------------- - -WaitingHostResolverProc::WaitingHostResolverProc(HostResolverProc* previous) - : HostResolverProc(previous), event_(false, false) {} +RuleBasedHostResolverProc* CreateCatchAllHostResolverProc() { + RuleBasedHostResolverProc* catchall = new RuleBasedHostResolverProc(NULL); +#if defined(OS_ANDROID) + // In Android emulator, the development machine's '127.0.0.1' is mapped to + // '10.0.2.2'. + catchall->AddIPLiteralRule("*", "10.0.2.2", "localhost"); +#else + catchall->AddIPLiteralRule("*", "127.0.0.1", "localhost"); +#endif -void WaitingHostResolverProc::Signal() { - event_.Signal(); + // Next add a rules-based layer the use controls. + return new RuleBasedHostResolverProc(catchall); } -int WaitingHostResolverProc::Resolve(const std::string& host, - AddressFamily address_family, - HostResolverFlags host_resolver_flags, - AddressList* addrlist, - int* os_error) { - event_.Wait(); - return ResolveUsingPrevious(host, address_family, host_resolver_flags, - addrlist, os_error); +//----------------------------------------------------------------------------- + +int HangingHostResolver::Resolve(const RequestInfo& info, + AddressList* addresses, + OldCompletionCallback* callback, + RequestHandle* out_req, + const BoundNetLog& net_log) { + return ERR_IO_PENDING; } -WaitingHostResolverProc::~WaitingHostResolverProc() {} +int HangingHostResolver::ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) { + return ERR_DNS_CACHE_MISS; +} //----------------------------------------------------------------------------- diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h index 27360b0..3c6f178 100644 --- a/net/base/mock_host_resolver.h +++ b/net/base/mock_host_resolver.h @@ -7,15 +7,28 @@ #pragma once #include <list> +#include <map> +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "base/synchronization/waitable_event.h" -#include "net/base/host_resolver_impl.h" +#include "base/threading/non_thread_safe.h" +#include "net/base/host_resolver.h" #include "net/base/host_resolver_proc.h" namespace net { +class HostCache; class RuleBasedHostResolverProc; +// Fills |*addrlist| with a socket address for |host_list| which should be a +// comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets. +// If |canonical_name| is non-empty it is used as the DNS canonical name for +// the host. Returns OK on success, ERR_UNEXPECTED otherwise. +int ParseAddressList(const std::string& host_list, + const std::string& canonical_name, + AddressList* addrlist); + // In most cases, it is important that unit tests avoid relying on making actual // DNS queries since the resulting tests can be flaky, especially if the network // is unreliable for some reason. To simplify writing tests that avoid making @@ -37,7 +50,9 @@ class RuleBasedHostResolverProc; // re-map one hostname to another as well. // Base class shared by MockHostResolver and MockCachingHostResolver. -class MockHostResolverBase : public HostResolver { +class MockHostResolverBase : public HostResolver, + public base::SupportsWeakPtr<MockHostResolverBase>, + public base::NonThreadSafe { public: virtual ~MockHostResolverBase(); @@ -51,13 +66,6 @@ class MockHostResolverBase : public HostResolver { // Resets the mock. void Reset(HostResolverProc* interceptor); - void SetPoolConstraints(HostResolverImpl::JobPoolIndex pool_index, - size_t max_outstanding_jobs, - size_t max_pending_requests) { - impl_->SetPoolConstraints( - pool_index, max_outstanding_jobs, max_pending_requests); - } - // HostResolver methods: virtual int Resolve(const RequestInfo& info, AddressList* addresses, @@ -70,16 +78,32 @@ class MockHostResolverBase : public HostResolver { virtual void CancelRequest(RequestHandle req) OVERRIDE; virtual void AddObserver(Observer* observer) OVERRIDE; virtual void RemoveObserver(Observer* observer) OVERRIDE; + virtual HostCache* GetHostCache() OVERRIDE; protected: - MockHostResolverBase(bool use_caching); + explicit MockHostResolverBase(bool use_caching); + + private: + struct Request; + typedef std::map<size_t, Request*> RequestMap; + + // Resolve as IP or from |cache_| return cached error or + // DNS_CACHE_MISS if failed. + int ResolveFromIPLiteralOrCache(const RequestInfo& info, + AddressList* addresses); + // Resolve via |proc_|. + int ResolveProc(size_t id, const RequestInfo& info, AddressList* addresses); + // Resolve request stored in |requests_|. Pass rv to callback. + void ResolveNow(size_t id); - scoped_ptr<HostResolverImpl> impl_; - scoped_refptr<RuleBasedHostResolverProc> rules_; bool synchronous_mode_; - bool use_caching_; + ObserverList<Observer> observers_; + scoped_refptr<RuleBasedHostResolverProc> rules_; + scoped_refptr<HostResolverProc> proc_; + scoped_ptr<HostCache> cache_; + RequestMap requests_; + size_t next_request_id_; - private: DISALLOW_COPY_AND_ASSIGN(MockHostResolverBase); }; @@ -154,24 +178,23 @@ class RuleBasedHostResolverProc : public HostResolverProc { RuleList rules_; }; -// Using WaitingHostResolverProc you can simulate very long lookups. -class WaitingHostResolverProc : public HostResolverProc { - public: - explicit WaitingHostResolverProc(HostResolverProc* previous); - - void Signal(); - - // HostResolverProc methods: - virtual int Resolve(const std::string& host, - AddressFamily address_family, - HostResolverFlags host_resolver_flags, - AddressList* addrlist, - int* os_error); - - private: - virtual ~WaitingHostResolverProc(); +// Create rules that map all requests to localhost. +RuleBasedHostResolverProc* CreateCatchAllHostResolverProc(); - base::WaitableEvent event_; +// HangingHostResolver never completes its |Resolve| request. +class HangingHostResolver : public HostResolver { + public: + virtual int Resolve(const RequestInfo& info, + AddressList* addresses, + OldCompletionCallback* callback, + RequestHandle* out_req, + const BoundNetLog& net_log) OVERRIDE; + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE; + virtual void CancelRequest(RequestHandle req) OVERRIDE {} + virtual void AddObserver(Observer* observer) OVERRIDE {} + virtual void RemoveObserver(Observer* observer) OVERRIDE {} }; // This class sets the default HostResolverProc for a particular scope. The diff --git a/net/base/net_test_suite.cc b/net/base/net_test_suite.cc index 451a8aaa..b3ee578 100644 --- a/net/base/net_test_suite.cc +++ b/net/base/net_test_suite.cc @@ -5,6 +5,7 @@ #include "net/base/net_test_suite.h" #include "base/message_loop.h" +#include "net/base/network_change_notifier.h" #include "net/http/http_stream_factory.h" #if defined(USE_NSS) #include "net/ocsp/nss_ocsp.h" diff --git a/net/base/single_request_host_resolver_unittest.cc b/net/base/single_request_host_resolver_unittest.cc index 2fb781f..ddf8c70e0 100644 --- a/net/base/single_request_host_resolver_unittest.cc +++ b/net/base/single_request_host_resolver_unittest.cc @@ -4,8 +4,10 @@ #include "net/base/single_request_host_resolver.h" +#include "net/base/address_list.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" +#include "net/base/net_log.h" #include "net/base/test_completion_callback.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index ceb6b9e..7c02e83 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -20,6 +20,7 @@ #include "net/base/auth.h" #include "net/base/capturing_net_log.h" #include "net/base/completion_callback.h" +#include "net/base/host_cache.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_log.h" #include "net/base/net_log_unittest.h" @@ -9130,7 +9131,7 @@ class OneTimeCachingHostResolver : public net::HostResolver { const BoundNetLog& net_log) OVERRIDE { int rv = host_resolver_.ResolveFromCache(info, addresses, net_log); if (rv == OK && info.host_port_pair().Equals(host_port_)) - host_resolver_.Reset(NULL); + host_resolver_.GetHostCache()->clear(); return rv; } diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index dd08965..818049f 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -7,6 +7,7 @@ #include <string> #include "base/basictypes.h" +#include "net/base/capturing_net_log.h" #include "net/base/cert_verifier.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_log.h" diff --git a/net/net.gyp b/net/net.gyp index 09b9f97..970a9e1 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -1310,6 +1310,7 @@ 'net', '../base/base.gyp:base', '../base/base.gyp:test_support_base', + '../build/temp_gyp/googleurl.gyp:googleurl', '../testing/gtest.gyp:gtest', ], 'sources': [ diff --git a/net/proxy/proxy_resolver_js_bindings_unittest.cc b/net/proxy/proxy_resolver_js_bindings_unittest.cc index 1c580b9..e4fa389 100644 --- a/net/proxy/proxy_resolver_js_bindings_unittest.cc +++ b/net/proxy/proxy_resolver_js_bindings_unittest.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/string_util.h" #include "net/base/address_list.h" +#include "net/base/host_cache.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" #include "net/base/net_log.h" @@ -33,40 +34,14 @@ class MockHostResolverWithMultipleResults : public SyncHostResolver { // HostResolver methods: virtual int Resolve(const HostResolver::RequestInfo& info, AddressList* addresses) OVERRIDE { - // Build up the result list (in reverse). - AddressList temp_list = ResolveIPLiteral("200.100.1.2"); - temp_list = PrependAddressToList("172.22.34.1", temp_list); - temp_list = PrependAddressToList("192.168.1.1", temp_list); - *addresses = temp_list; - return OK; + return ParseAddressList("192.168.1.1,172.22.34.1,200.100.1.2", "", + addresses); } virtual void Shutdown() OVERRIDE {} private: virtual ~MockHostResolverWithMultipleResults() {} - - // Resolves an IP literal to an address list. - AddressList ResolveIPLiteral(const char* ip_literal) { - AddressList result; - int rv = SystemHostResolverProc(ip_literal, - ADDRESS_FAMILY_UNSPECIFIED, - 0, - &result, NULL); - EXPECT_EQ(OK, rv); - EXPECT_EQ(NULL, result.head()->ai_next); - return result; - } - - // Builds an AddressList that is |ip_literal| + |orig_list|. - // |orig_list| must not be empty. - AddressList PrependAddressToList(const char* ip_literal, - const AddressList& orig_list) { - // Build an addrinfo for |ip_literal|. - AddressList result = ResolveIPLiteral(ip_literal); - result.Append(orig_list.head()); - return result; - } }; class MockFailingHostResolver : public SyncHostResolver { diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 8191bbe..2444756 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc @@ -13,8 +13,8 @@ #include "base/message_loop.h" #include "base/time.h" #include "net/base/address_family.h" +#include "net/base/address_list.h" #include "net/base/auth.h" -#include "net/base/host_resolver_proc.h" #include "net/base/ssl_cert_request_info.h" #include "net/base/ssl_info.h" #include "net/http/http_network_session.h" @@ -656,16 +656,19 @@ bool MockClientSocket::IsConnectedAndIdle() const { } int MockClientSocket::GetPeerAddress(AddressList* address) const { - return net::SystemHostResolverProc("192.0.2.33", ADDRESS_FAMILY_UNSPECIFIED, - 0, address, NULL); + IPAddressNumber ip; + bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); + CHECK(rv); + *address = AddressList::CreateFromIPAddress(ip, 0); + return OK; } int MockClientSocket::GetLocalAddress(IPEndPoint* address) const { IPAddressNumber ip; - if (!ParseIPLiteralToNumber("192.0.2.33", &ip)) - return ERR_FAILED; + bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); + CHECK(rv); *address = IPEndPoint(ip, 123); - return OK; + return OK; } const BoundNetLog& MockClientSocket::NetLog() const { @@ -677,7 +680,7 @@ void MockClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) { } void MockClientSocket::GetSSLCertRequestInfo( - net::SSLCertRequestInfo* cert_request_info) { + net::SSLCertRequestInfo* cert_request_info) { } int MockClientSocket::ExportKeyingMaterial(const base::StringPiece& label, diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc index ce80719..0ed1834 100644 --- a/net/socket/socks_client_socket_unittest.cc +++ b/net/socket/socks_client_socket_unittest.cc @@ -81,9 +81,9 @@ SOCKSClientSocket* SOCKSClientSocketTest::BuildMockSocket( // Implementation of HostResolver that never completes its resolve request. // We use this in the test "DisconnectWhileHostResolveInProgress" to make // sure that the outstanding resolve request gets cancelled. -class HangingHostResolver : public HostResolver { +class HangingHostResolverWithCancel : public HostResolver { public: - HangingHostResolver() : outstanding_request_(NULL) {} + HangingHostResolverWithCancel() : outstanding_request_(NULL) {} virtual int Resolve(const RequestInfo& info, AddressList* addresses, @@ -121,7 +121,7 @@ class HangingHostResolver : public HostResolver { private: RequestHandle outstanding_request_; - DISALLOW_COPY_AND_ASSIGN(HangingHostResolver); + DISALLOW_COPY_AND_ASSIGN(HangingHostResolverWithCancel); }; // Tests a complete handshake and the disconnection. @@ -371,7 +371,8 @@ TEST_F(SOCKSClientSocketTest, FailedDNS) { // Calls Disconnect() while a host resolve is in progress. The outstanding host // resolve should be cancelled. TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { - scoped_ptr<HangingHostResolver> hanging_resolver(new HangingHostResolver()); + scoped_ptr<HangingHostResolverWithCancel> hanging_resolver( + new HangingHostResolverWithCancel()); // Doesn't matter what the socket data is, we will never use it -- garbage. MockWrite data_writes[] = { MockWrite(false, "", 0) }; |