diff options
Diffstat (limited to 'net/base/host_resolver_impl_unittest.cc')
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 101 |
1 files changed, 66 insertions, 35 deletions
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()); } |