Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/base/host_resolver_impl.h"
      6 
      7 #include <string>
      8 
      9 #include "base/compiler_specific.h"
     10 #include "base/message_loop.h"
     11 #include "base/ref_counted.h"
     12 #include "net/base/address_list.h"
     13 #include "net/base/completion_callback.h"
     14 #include "net/base/load_log_unittest.h"
     15 #include "net/base/mock_host_resolver.h"
     16 #include "net/base/mock_network_change_notifier.h"
     17 #include "net/base/net_errors.h"
     18 #include "net/base/sys_addrinfo.h"
     19 #include "net/base/test_completion_callback.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 // TODO(eroman):
     23 //  - Test mixing async with sync (in particular how does sync update the
     24 //    cache while an async is already pending).
     25 
     26 namespace net {
     27 
     28 namespace {
     29 
     30 HostCache* CreateDefaultCache() {
     31   return new HostCache(
     32       100,  // max cache entries.
     33       base::TimeDelta::FromMinutes(1),
     34       base::TimeDelta::FromSeconds(0));
     35 }
     36 
     37 static const size_t kMaxJobs = 10u;
     38 
     39 HostResolverImpl* CreateHostResolverImpl(HostResolverProc* resolver_proc) {
     40   return new HostResolverImpl(
     41       resolver_proc,
     42       CreateDefaultCache(),
     43       NULL,  // network_change_notifier
     44       kMaxJobs);
     45 }
     46 
     47 // Helper to create a HostResolver::RequestInfo.
     48 HostResolver::RequestInfo CreateResolverRequest(
     49     const std::string& hostname,
     50     RequestPriority priority) {
     51   HostResolver::RequestInfo info(hostname, 80);
     52   info.set_priority(priority);
     53   return info;
     54 }
     55 
     56 // A variant of WaitingHostResolverProc that pushes each host mapped into a
     57 // list.
     58 // (and uses a manual-reset event rather than auto-reset).
     59 class CapturingHostResolverProc : public HostResolverProc {
     60  public:
     61   explicit CapturingHostResolverProc(HostResolverProc* previous)
     62       : HostResolverProc(previous), event_(true, false) {
     63   }
     64 
     65   void Signal() {
     66     event_.Signal();
     67   }
     68 
     69   virtual int Resolve(const std::string& host,
     70                       AddressFamily address_family,
     71                       AddressList* addrlist) {
     72     event_.Wait();
     73     {
     74       AutoLock l(lock_);
     75       capture_list_.push_back(host);
     76     }
     77     return ResolveUsingPrevious(host, address_family, addrlist);
     78   }
     79 
     80   std::vector<std::string> GetCaptureList() const {
     81     std::vector<std::string> copy;
     82     {
     83       AutoLock l(lock_);
     84       copy = capture_list_;
     85     }
     86     return copy;
     87   }
     88 
     89  private:
     90   ~CapturingHostResolverProc() {}
     91 
     92   std::vector<std::string> capture_list_;
     93   mutable Lock lock_;
     94   base::WaitableEvent event_;
     95 };
     96 
     97 // Helper that represents a single Resolve() result, used to inspect all the
     98 // resolve results by forwarding them to Delegate.
     99 class ResolveRequest {
    100  public:
    101   // Delegate interface, for notification when the ResolveRequest completes.
    102   class Delegate {
    103    public:
    104     virtual ~Delegate() {}
    105     virtual void OnCompleted(ResolveRequest* resolve) = 0;
    106   };
    107 
    108   ResolveRequest(HostResolver* resolver,
    109                  const std::string& hostname,
    110                  int port,
    111                  Delegate* delegate)
    112       : info_(hostname, port), resolver_(resolver), delegate_(delegate),
    113         ALLOW_THIS_IN_INITIALIZER_LIST(
    114             callback_(this, &ResolveRequest::OnLookupFinished)) {
    115     // Start the request.
    116     int err = resolver->Resolve(info_, &addrlist_, &callback_, &req_, NULL);
    117     EXPECT_EQ(ERR_IO_PENDING, err);
    118   }
    119 
    120   ResolveRequest(HostResolver* resolver,
    121                  const HostResolver::RequestInfo& info,
    122                  Delegate* delegate)
    123       : info_(info), resolver_(resolver), delegate_(delegate),
    124         ALLOW_THIS_IN_INITIALIZER_LIST(
    125             callback_(this, &ResolveRequest::OnLookupFinished)) {
    126     // Start the request.
    127     int err = resolver->Resolve(info, &addrlist_, &callback_, &req_, NULL);
    128     EXPECT_EQ(ERR_IO_PENDING, err);
    129   }
    130 
    131   void Cancel() {
    132     resolver_->CancelRequest(req_);
    133   }
    134 
    135   const std::string& hostname() const {
    136     return info_.hostname();
    137   }
    138 
    139   int port() const {
    140     return info_.port();
    141   }
    142 
    143   int result() const {
    144     return result_;
    145   }
    146 
    147   const AddressList& addrlist() const {
    148     return addrlist_;
    149   }
    150 
    151   HostResolver* resolver() const {
    152     return resolver_;
    153   }
    154 
    155  private:
    156   void OnLookupFinished(int result) {
    157     result_ = result;
    158     delegate_->OnCompleted(this);
    159   }
    160 
    161   // The request details.
    162   HostResolver::RequestInfo info_;
    163   HostResolver::RequestHandle req_;
    164 
    165   // The result of the resolve.
    166   int result_;
    167   AddressList addrlist_;
    168 
    169   // We don't use a scoped_refptr, to simplify deleting shared resolver in
    170   // DeleteWithinCallback test.
    171   HostResolver* resolver_;
    172 
    173   Delegate* delegate_;
    174   CompletionCallbackImpl<ResolveRequest> callback_;
    175 
    176   DISALLOW_COPY_AND_ASSIGN(ResolveRequest);
    177 };
    178 
    179 class HostResolverImplTest : public testing::Test {
    180  public:
    181   HostResolverImplTest()
    182       : callback_called_(false),
    183         ALLOW_THIS_IN_INITIALIZER_LIST(
    184             callback_(this, &HostResolverImplTest::OnLookupFinished)) {
    185   }
    186 
    187  protected:
    188   bool callback_called_;
    189   int callback_result_;
    190   CompletionCallbackImpl<HostResolverImplTest> callback_;
    191 
    192  private:
    193   void OnLookupFinished(int result) {
    194     callback_called_ = true;
    195     callback_result_ = result;
    196     MessageLoop::current()->Quit();
    197   }
    198 };
    199 
    200 TEST_F(HostResolverImplTest, SynchronousLookup) {
    201   AddressList adrlist;
    202   const int kPortnum = 80;
    203 
    204   scoped_refptr<RuleBasedHostResolverProc> resolver_proc =
    205       new RuleBasedHostResolverProc(NULL);
    206   resolver_proc->AddRule("just.testing", "192.168.1.42");
    207 
    208   scoped_refptr<HostResolver> host_resolver(
    209       CreateHostResolverImpl(resolver_proc));
    210 
    211   HostResolver::RequestInfo info("just.testing", kPortnum);
    212   scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
    213   int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, log);
    214   EXPECT_EQ(OK, err);
    215 
    216   EXPECT_EQ(2u, log->entries().size());
    217   EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    218   EXPECT_TRUE(LogContainsEndEvent(*log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    219 
    220   const struct addrinfo* ainfo = adrlist.head();
    221   EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
    222   EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
    223 
    224   const struct sockaddr* sa = ainfo->ai_addr;
    225   const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
    226   EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
    227   EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr);
    228 }
    229 
    230 TEST_F(HostResolverImplTest, AsynchronousLookup) {
    231   AddressList adrlist;
    232   const int kPortnum = 80;
    233 
    234   scoped_refptr<RuleBasedHostResolverProc> resolver_proc =
    235       new RuleBasedHostResolverProc(NULL);
    236   resolver_proc->AddRule("just.testing", "192.168.1.42");
    237 
    238   scoped_refptr<HostResolver> host_resolver(
    239       CreateHostResolverImpl(resolver_proc));
    240 
    241   HostResolver::RequestInfo info("just.testing", kPortnum);
    242   scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
    243   int err = host_resolver->Resolve(info, &adrlist, &callback_, NULL, log);
    244   EXPECT_EQ(ERR_IO_PENDING, err);
    245 
    246   EXPECT_EQ(1u, log->entries().size());
    247   EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    248 
    249   MessageLoop::current()->Run();
    250 
    251   ASSERT_TRUE(callback_called_);
    252   ASSERT_EQ(OK, callback_result_);
    253 
    254   EXPECT_EQ(2u, log->entries().size());
    255   EXPECT_TRUE(LogContainsEndEvent(*log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    256 
    257   const struct addrinfo* ainfo = adrlist.head();
    258   EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
    259   EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
    260 
    261   const struct sockaddr* sa = ainfo->ai_addr;
    262   const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
    263   EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
    264   EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr);
    265 }
    266 
    267 TEST_F(HostResolverImplTest, CanceledAsynchronousLookup) {
    268   scoped_refptr<WaitingHostResolverProc> resolver_proc =
    269       new WaitingHostResolverProc(NULL);
    270 
    271   scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
    272   {
    273     scoped_refptr<HostResolver> host_resolver(
    274         CreateHostResolverImpl(resolver_proc));
    275     AddressList adrlist;
    276     const int kPortnum = 80;
    277 
    278     HostResolver::RequestInfo info("just.testing", kPortnum);
    279     int err = host_resolver->Resolve(info, &adrlist, &callback_, NULL, log);
    280     EXPECT_EQ(ERR_IO_PENDING, err);
    281 
    282     // Make sure we will exit the queue even when callback is not called.
    283     MessageLoop::current()->PostDelayedTask(FROM_HERE,
    284                                             new MessageLoop::QuitTask(),
    285                                             1000);
    286     MessageLoop::current()->Run();
    287   }
    288 
    289   resolver_proc->Signal();
    290 
    291   EXPECT_EQ(3u, log->entries().size());
    292   EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    293   EXPECT_TRUE(LogContainsEvent(
    294       *log, 1, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE));
    295   EXPECT_TRUE(LogContainsEndEvent(*log, 2, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    296 
    297   EXPECT_FALSE(callback_called_);
    298 }
    299 
    300 TEST_F(HostResolverImplTest, NumericIPv4Address) {
    301   // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in.
    302 
    303   scoped_refptr<RuleBasedHostResolverProc> resolver_proc =
    304       new RuleBasedHostResolverProc(NULL);
    305   resolver_proc->AllowDirectLookup("*");
    306 
    307   scoped_refptr<HostResolver> host_resolver(
    308       CreateHostResolverImpl(resolver_proc));
    309   AddressList adrlist;
    310   const int kPortnum = 5555;
    311   HostResolver::RequestInfo info("127.1.2.3", kPortnum);
    312   int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, NULL);
    313   EXPECT_EQ(OK, err);
    314 
    315   const struct addrinfo* ainfo = adrlist.head();
    316   EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
    317   EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
    318 
    319   const struct sockaddr* sa = ainfo->ai_addr;
    320   const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
    321   EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
    322   EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr);
    323 }
    324 
    325 TEST_F(HostResolverImplTest, NumericIPv6Address) {
    326   scoped_refptr<RuleBasedHostResolverProc> resolver_proc =
    327       new RuleBasedHostResolverProc(NULL);
    328   resolver_proc->AllowDirectLookup("*");
    329 
    330   // Resolve a plain IPv6 address.  Don't worry about [brackets], because
    331   // the caller should have removed them.
    332   scoped_refptr<HostResolver> host_resolver(
    333       CreateHostResolverImpl(resolver_proc));
    334   AddressList adrlist;
    335   const int kPortnum = 5555;
    336   HostResolver::RequestInfo info("2001:db8::1", kPortnum);
    337   int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, NULL);
    338   // On computers without IPv6 support, getaddrinfo cannot convert IPv6
    339   // address literals to addresses (getaddrinfo returns EAI_NONAME).  So this
    340   // test has to allow host_resolver->Resolve to fail.
    341   if (err == ERR_NAME_NOT_RESOLVED)
    342     return;
    343   EXPECT_EQ(OK, err);
    344 
    345   const struct addrinfo* ainfo = adrlist.head();
    346   EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
    347   EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen);
    348 
    349   const struct sockaddr* sa = ainfo->ai_addr;
    350   const struct sockaddr_in6* sa_in6 = (const struct sockaddr_in6*) sa;
    351   EXPECT_TRUE(htons(kPortnum) == sa_in6->sin6_port);
    352 
    353   const uint8 expect_addr[] = {
    354     0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
    355     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
    356   };
    357   for (int i = 0; i < 16; i++) {
    358     EXPECT_EQ(expect_addr[i], sa_in6->sin6_addr.s6_addr[i]);
    359   }
    360 }
    361 
    362 TEST_F(HostResolverImplTest, EmptyHost) {
    363   scoped_refptr<RuleBasedHostResolverProc> resolver_proc =
    364       new RuleBasedHostResolverProc(NULL);
    365   resolver_proc->AllowDirectLookup("*");
    366 
    367   scoped_refptr<HostResolver> host_resolver(
    368       CreateHostResolverImpl(resolver_proc));
    369   AddressList adrlist;
    370   const int kPortnum = 5555;
    371   HostResolver::RequestInfo info("", kPortnum);
    372   int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, NULL);
    373   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err);
    374 }
    375 
    376 // Helper class used by HostResolverImplTest.DeDupeRequests. It receives request
    377 // completion notifications for all the resolves, so it can tally up and
    378 // determine when we are done.
    379 class DeDupeRequestsVerifier : public ResolveRequest::Delegate {
    380  public:
    381   explicit DeDupeRequestsVerifier(CapturingHostResolverProc* resolver_proc)
    382       : count_a_(0), count_b_(0), resolver_proc_(resolver_proc) {}
    383 
    384   // The test does 5 resolves (which can complete in any order).
    385   virtual void OnCompleted(ResolveRequest* resolve) {
    386     // Tally up how many requests we have seen.
    387     if (resolve->hostname() == "a") {
    388       count_a_++;
    389     } else if (resolve->hostname() == "b") {
    390       count_b_++;
    391     } else {
    392       FAIL() << "Unexpected hostname: " << resolve->hostname();
    393     }
    394 
    395     // Check that the port was set correctly.
    396     EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort());
    397 
    398     // Check whether all the requests have finished yet.
    399     int total_completions = count_a_ + count_b_;
    400     if (total_completions == 5) {
    401       EXPECT_EQ(2, count_a_);
    402       EXPECT_EQ(3, count_b_);
    403 
    404       // The resolver_proc should have been called only twice -- once with "a",
    405       // once with "b".
    406       std::vector<std::string> capture_list = resolver_proc_->GetCaptureList();
    407       EXPECT_EQ(2U, capture_list.size());
    408 
    409       // End this test, we are done.
    410       MessageLoop::current()->Quit();
    411     }
    412   }
    413 
    414  private:
    415   int count_a_;
    416   int count_b_;
    417   CapturingHostResolverProc* resolver_proc_;
    418 
    419   DISALLOW_COPY_AND_ASSIGN(DeDupeRequestsVerifier);
    420 };
    421 
    422 TEST_F(HostResolverImplTest, DeDupeRequests) {
    423   // Use a capturing resolver_proc, since the verifier needs to know what calls
    424   // reached Resolve().  Also, the capturing resolver_proc is initially blocked.
    425   scoped_refptr<CapturingHostResolverProc> resolver_proc =
    426       new CapturingHostResolverProc(NULL);
    427 
    428   scoped_refptr<HostResolver> host_resolver(
    429       CreateHostResolverImpl(resolver_proc));
    430 
    431   // The class will receive callbacks for when each resolve completes. It
    432   // checks that the right things happened.
    433   DeDupeRequestsVerifier verifier(resolver_proc.get());
    434 
    435   // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is
    436   // blocked, these should all pile up until we signal it.
    437 
    438   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    439   ResolveRequest req2(host_resolver, "b", 80, &verifier);
    440   ResolveRequest req3(host_resolver, "b", 81, &verifier);
    441   ResolveRequest req4(host_resolver, "a", 82, &verifier);
    442   ResolveRequest req5(host_resolver, "b", 83, &verifier);
    443 
    444   // Ready, Set, GO!!!
    445   resolver_proc->Signal();
    446 
    447   // |verifier| will send quit message once all the requests have finished.
    448   MessageLoop::current()->Run();
    449 }
    450 
    451 // Helper class used by HostResolverImplTest.CancelMultipleRequests.
    452 class CancelMultipleRequestsVerifier : public ResolveRequest::Delegate {
    453  public:
    454   CancelMultipleRequestsVerifier() {}
    455 
    456   // The cancels kill all but one request.
    457   virtual void OnCompleted(ResolveRequest* resolve) {
    458     EXPECT_EQ("a", resolve->hostname());
    459     EXPECT_EQ(82, resolve->port());
    460 
    461     // Check that the port was set correctly.
    462     EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort());
    463 
    464     // End this test, we are done.
    465     MessageLoop::current()->Quit();
    466   }
    467 
    468  private:
    469   DISALLOW_COPY_AND_ASSIGN(CancelMultipleRequestsVerifier);
    470 };
    471 
    472 TEST_F(HostResolverImplTest, CancelMultipleRequests) {
    473   // Use a capturing resolver_proc, since the verifier needs to know what calls
    474   // reached Resolver().  Also, the capturing resolver_proc is initially
    475   // blocked.
    476   scoped_refptr<CapturingHostResolverProc> resolver_proc =
    477       new CapturingHostResolverProc(NULL);
    478 
    479   scoped_refptr<HostResolver> host_resolver(
    480       CreateHostResolverImpl(resolver_proc));
    481 
    482   // The class will receive callbacks for when each resolve completes. It
    483   // checks that the right things happened.
    484   CancelMultipleRequestsVerifier verifier;
    485 
    486   // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is
    487   // blocked, these should all pile up until we signal it.
    488 
    489   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    490   ResolveRequest req2(host_resolver, "b", 80, &verifier);
    491   ResolveRequest req3(host_resolver, "b", 81, &verifier);
    492   ResolveRequest req4(host_resolver, "a", 82, &verifier);
    493   ResolveRequest req5(host_resolver, "b", 83, &verifier);
    494 
    495   // Cancel everything except request 4.
    496   req1.Cancel();
    497   req2.Cancel();
    498   req3.Cancel();
    499   req5.Cancel();
    500 
    501   // Ready, Set, GO!!!
    502   resolver_proc->Signal();
    503 
    504   // |verifier| will send quit message once all the requests have finished.
    505   MessageLoop::current()->Run();
    506 }
    507 
    508 // Helper class used by HostResolverImplTest.CancelWithinCallback.
    509 class CancelWithinCallbackVerifier : public ResolveRequest::Delegate {
    510  public:
    511   CancelWithinCallbackVerifier()
    512       : req_to_cancel1_(NULL), req_to_cancel2_(NULL), num_completions_(0) {
    513   }
    514 
    515   virtual void OnCompleted(ResolveRequest* resolve) {
    516     num_completions_++;
    517 
    518     // Port 80 is the first request that the callback will be invoked for.
    519     // While we are executing within that callback, cancel the other requests
    520     // in the job and start another request.
    521     if (80 == resolve->port()) {
    522       EXPECT_EQ("a", resolve->hostname());
    523 
    524       req_to_cancel1_->Cancel();
    525       req_to_cancel2_->Cancel();
    526 
    527       // Start a request (so we can make sure the canceled requests don't
    528       // complete before "finalrequest" finishes.
    529       final_request_.reset(new ResolveRequest(
    530           resolve->resolver(), "finalrequest", 70, this));
    531 
    532     } else if (83 == resolve->port()) {
    533       EXPECT_EQ("a", resolve->hostname());
    534     } else if (resolve->hostname() == "finalrequest") {
    535       EXPECT_EQ(70, resolve->addrlist().GetPort());
    536 
    537       // End this test, we are done.
    538       MessageLoop::current()->Quit();
    539     } else {
    540       FAIL() << "Unexpected completion: " << resolve->hostname() << ", "
    541              << resolve->port();
    542     }
    543   }
    544 
    545   void SetRequestsToCancel(ResolveRequest* req_to_cancel1,
    546                            ResolveRequest* req_to_cancel2) {
    547     req_to_cancel1_ = req_to_cancel1;
    548     req_to_cancel2_ = req_to_cancel2;
    549   }
    550 
    551  private:
    552   scoped_ptr<ResolveRequest> final_request_;
    553   ResolveRequest* req_to_cancel1_;
    554   ResolveRequest* req_to_cancel2_;
    555   int num_completions_;
    556   DISALLOW_COPY_AND_ASSIGN(CancelWithinCallbackVerifier);
    557 };
    558 
    559 TEST_F(HostResolverImplTest, CancelWithinCallback) {
    560   // Use a capturing resolver_proc, since the verifier needs to know what calls
    561   // reached Resolver().  Also, the capturing resolver_proc is initially
    562   // blocked.
    563   scoped_refptr<CapturingHostResolverProc> resolver_proc =
    564       new CapturingHostResolverProc(NULL);
    565 
    566   scoped_refptr<HostResolver> host_resolver(
    567       CreateHostResolverImpl(resolver_proc));
    568 
    569   // The class will receive callbacks for when each resolve completes. It
    570   // checks that the right things happened.
    571   CancelWithinCallbackVerifier verifier;
    572 
    573   // Start 4 requests, duplicating hosts "a". Since the resolver_proc is
    574   // blocked, these should all pile up until we signal it.
    575 
    576   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    577   ResolveRequest req2(host_resolver, "a", 81, &verifier);
    578   ResolveRequest req3(host_resolver, "a", 82, &verifier);
    579   ResolveRequest req4(host_resolver, "a", 83, &verifier);
    580 
    581   // Once "a:80" completes, it will cancel "a:81" and "a:82".
    582   verifier.SetRequestsToCancel(&req2, &req3);
    583 
    584   // Ready, Set, GO!!!
    585   resolver_proc->Signal();
    586 
    587   // |verifier| will send quit message once all the requests have finished.
    588   MessageLoop::current()->Run();
    589 }
    590 
    591 // Helper class used by HostResolverImplTest.DeleteWithinCallback.
    592 class DeleteWithinCallbackVerifier : public ResolveRequest::Delegate {
    593  public:
    594   // |host_resolver| is the resolver that the the resolve requests were started
    595   // with.
    596   DeleteWithinCallbackVerifier(HostResolver* host_resolver)
    597       : host_resolver_(host_resolver) {}
    598 
    599   virtual void OnCompleted(ResolveRequest* resolve) {
    600     EXPECT_EQ("a", resolve->hostname());
    601     EXPECT_EQ(80, resolve->port());
    602 
    603     // Release the last reference to the host resolver that started the
    604     // requests.
    605     host_resolver_ = NULL;
    606 
    607     // Quit after returning from OnCompleted (to give it a chance at
    608     // incorrectly running the cancelled tasks).
    609     MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
    610   }
    611 
    612  private:
    613   scoped_refptr<HostResolver> host_resolver_;
    614   DISALLOW_COPY_AND_ASSIGN(DeleteWithinCallbackVerifier);
    615 };
    616 
    617 TEST_F(HostResolverImplTest, DeleteWithinCallback) {
    618   // Use a capturing resolver_proc, since the verifier needs to know what calls
    619   // reached Resolver().  Also, the capturing resolver_proc is initially
    620   // blocked.
    621   scoped_refptr<CapturingHostResolverProc> resolver_proc =
    622       new CapturingHostResolverProc(NULL);
    623 
    624   // The class will receive callbacks for when each resolve completes. It
    625   // checks that the right things happened. Note that the verifier holds the
    626   // only reference to |host_resolver|, so it can delete it within callback.
    627   HostResolver* host_resolver =
    628       CreateHostResolverImpl(resolver_proc);
    629   DeleteWithinCallbackVerifier verifier(host_resolver);
    630 
    631   // Start 4 requests, duplicating hosts "a". Since the resolver_proc is
    632   // blocked, these should all pile up until we signal it.
    633 
    634   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    635   ResolveRequest req2(host_resolver, "a", 81, &verifier);
    636   ResolveRequest req3(host_resolver, "a", 82, &verifier);
    637   ResolveRequest req4(host_resolver, "a", 83, &verifier);
    638 
    639   // Ready, Set, GO!!!
    640   resolver_proc->Signal();
    641 
    642   // |verifier| will send quit message once all the requests have finished.
    643   MessageLoop::current()->Run();
    644 }
    645 
    646 // Helper class used by HostResolverImplTest.StartWithinCallback.
    647 class StartWithinCallbackVerifier : public ResolveRequest::Delegate {
    648  public:
    649   StartWithinCallbackVerifier() : num_requests_(0) {}
    650 
    651   virtual void OnCompleted(ResolveRequest* resolve) {
    652     EXPECT_EQ("a", resolve->hostname());
    653 
    654     if (80 == resolve->port()) {
    655       // On completing the first request, start another request for "a".
    656       // Since caching is disabled, this will result in another async request.
    657       final_request_.reset(new ResolveRequest(
    658         resolve->resolver(), "a", 70, this));
    659     }
    660     if (++num_requests_ == 5) {
    661       // Test is done.
    662       MessageLoop::current()->Quit();
    663     }
    664   }
    665 
    666  private:
    667   int num_requests_;
    668   scoped_ptr<ResolveRequest> final_request_;
    669   DISALLOW_COPY_AND_ASSIGN(StartWithinCallbackVerifier);
    670 };
    671 
    672 TEST_F(HostResolverImplTest, StartWithinCallback) {
    673   // Use a capturing resolver_proc, since the verifier needs to know what calls
    674   // reached Resolver().  Also, the capturing resolver_proc is initially
    675   // blocked.
    676   scoped_refptr<CapturingHostResolverProc> resolver_proc =
    677       new CapturingHostResolverProc(NULL);
    678 
    679   // Turn off caching for this host resolver.
    680   scoped_refptr<HostResolver> host_resolver(
    681       new HostResolverImpl(resolver_proc, NULL, NULL, kMaxJobs));
    682 
    683   // The class will receive callbacks for when each resolve completes. It
    684   // checks that the right things happened.
    685   StartWithinCallbackVerifier verifier;
    686 
    687   // Start 4 requests, duplicating hosts "a". Since the resolver_proc is
    688   // blocked, these should all pile up until we signal it.
    689 
    690   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    691   ResolveRequest req2(host_resolver, "a", 81, &verifier);
    692   ResolveRequest req3(host_resolver, "a", 82, &verifier);
    693   ResolveRequest req4(host_resolver, "a", 83, &verifier);
    694 
    695   // Ready, Set, GO!!!
    696   resolver_proc->Signal();
    697 
    698   // |verifier| will send quit message once all the requests have finished.
    699   MessageLoop::current()->Run();
    700 }
    701 
    702 // Helper class used by HostResolverImplTest.BypassCache.
    703 class BypassCacheVerifier : public ResolveRequest::Delegate {
    704  public:
    705   BypassCacheVerifier() {}
    706 
    707   virtual void OnCompleted(ResolveRequest* resolve) {
    708     EXPECT_EQ("a", resolve->hostname());
    709     HostResolver* resolver = resolve->resolver();
    710 
    711     if (80 == resolve->port()) {
    712       // On completing the first request, start another request for "a".
    713       // Since caching is enabled, this should complete synchronously.
    714 
    715       // Note that |junk_callback| shouldn't be used since we are going to
    716       // complete synchronously. We can't specify NULL though since that would
    717       // mean synchronous mode so we give it a value of 1.
    718       CompletionCallback* junk_callback =
    719           reinterpret_cast<CompletionCallback*> (1);
    720       AddressList addrlist;
    721 
    722       HostResolver::RequestInfo info("a", 70);
    723       int error = resolver->Resolve(info, &addrlist, junk_callback, NULL, NULL);
    724       EXPECT_EQ(OK, error);
    725 
    726       // Ok good. Now make sure that if we ask to bypass the cache, it can no
    727       // longer service the request synchronously.
    728       info = HostResolver::RequestInfo("a", 71);
    729       info.set_allow_cached_response(false);
    730       final_request_.reset(new ResolveRequest(resolver, info, this));
    731     } else if (71 == resolve->port()) {
    732       // Test is done.
    733       MessageLoop::current()->Quit();
    734     } else {
    735       FAIL() << "Unexpected port number";
    736     }
    737   }
    738 
    739  private:
    740   scoped_ptr<ResolveRequest> final_request_;
    741   DISALLOW_COPY_AND_ASSIGN(BypassCacheVerifier);
    742 };
    743 
    744 TEST_F(HostResolverImplTest, BypassCache) {
    745   scoped_refptr<HostResolver> host_resolver(
    746       CreateHostResolverImpl(NULL));
    747 
    748   // The class will receive callbacks for when each resolve completes. It
    749   // checks that the right things happened.
    750   BypassCacheVerifier verifier;
    751 
    752   // Start a request.
    753   ResolveRequest req1(host_resolver, "a", 80, &verifier);
    754 
    755   // |verifier| will send quit message once all the requests have finished.
    756   MessageLoop::current()->Run();
    757 }
    758 
    759 bool operator==(const HostResolver::RequestInfo& a,
    760                 const HostResolver::RequestInfo& b) {
    761    return a.hostname() == b.hostname() &&
    762           a.port() == b.port() &&
    763           a.allow_cached_response() == b.allow_cached_response() &&
    764           a.priority() == b.priority() &&
    765           a.is_speculative() == b.is_speculative() &&
    766           a.referrer() == b.referrer();
    767 }
    768 
    769 // Observer that just makes note of how it was called. The test code can then
    770 // inspect to make sure it was called with the right parameters.
    771 class CapturingObserver : public HostResolver::Observer {
    772  public:
    773   // DnsResolutionObserver methods:
    774   virtual void OnStartResolution(int id,
    775                                  const HostResolver::RequestInfo& info) {
    776     start_log.push_back(StartOrCancelEntry(id, info));
    777   }
    778 
    779   virtual void OnFinishResolutionWithStatus(
    780       int id,
    781       bool was_resolved,
    782       const HostResolver::RequestInfo& info) {
    783     finish_log.push_back(FinishEntry(id, was_resolved, info));
    784   }
    785 
    786   virtual void OnCancelResolution(int id,
    787                                   const HostResolver::RequestInfo& info) {
    788     cancel_log.push_back(StartOrCancelEntry(id, info));
    789   }
    790 
    791   // Tuple (id, info).
    792   struct StartOrCancelEntry {
    793     StartOrCancelEntry(int id, const HostResolver::RequestInfo& info)
    794         : id(id), info(info) {}
    795 
    796     bool operator==(const StartOrCancelEntry& other) const {
    797       return id == other.id && info == other.info;
    798     }
    799 
    800     int id;
    801     HostResolver::RequestInfo info;
    802   };
    803 
    804   // Tuple (id, was_resolved, info).
    805   struct FinishEntry {
    806     FinishEntry(int id, bool was_resolved,
    807                 const HostResolver::RequestInfo& info)
    808         : id(id), was_resolved(was_resolved), info(info) {}
    809 
    810     bool operator==(const FinishEntry& other) const {
    811       return id == other.id &&
    812              was_resolved == other.was_resolved &&
    813              info == other.info;
    814     }
    815 
    816     int id;
    817     bool was_resolved;
    818     HostResolver::RequestInfo info;
    819   };
    820 
    821   std::vector<StartOrCancelEntry> start_log;
    822   std::vector<FinishEntry> finish_log;
    823   std::vector<StartOrCancelEntry> cancel_log;
    824 };
    825 
    826 // Test that registering, unregistering, and notifying of observers works.
    827 // Does not test the cancellation notification since all resolves are
    828 // synchronous.
    829 TEST_F(HostResolverImplTest, Observers) {
    830   scoped_refptr<HostResolver> host_resolver(
    831       CreateHostResolverImpl(NULL));
    832 
    833   CapturingObserver observer;
    834 
    835   host_resolver->AddObserver(&observer);
    836 
    837   AddressList addrlist;
    838 
    839   // Resolve "host1".
    840   HostResolver::RequestInfo info1("host1", 70);
    841   scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
    842   int rv = host_resolver->Resolve(info1, &addrlist, NULL, NULL, log);
    843   EXPECT_EQ(OK, rv);
    844 
    845   EXPECT_EQ(6u, log->entries().size());
    846   EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    847   EXPECT_TRUE(LogContainsBeginEvent(
    848       *log, 1, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART));
    849   EXPECT_TRUE(LogContainsEndEvent(
    850       *log, 2, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONSTART));
    851   EXPECT_TRUE(LogContainsBeginEvent(
    852       *log, 3, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH));
    853   EXPECT_TRUE(LogContainsEndEvent(
    854       *log, 4, LoadLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONFINISH));
    855   EXPECT_TRUE(LogContainsEndEvent(
    856       *log, 5, LoadLog::TYPE_HOST_RESOLVER_IMPL));
    857 
    858   EXPECT_EQ(1U, observer.start_log.size());
    859   EXPECT_EQ(1U, observer.finish_log.size());
    860   EXPECT_EQ(0U, observer.cancel_log.size());
    861   EXPECT_TRUE(observer.start_log[0] ==
    862               CapturingObserver::StartOrCancelEntry(0, info1));
    863   EXPECT_TRUE(observer.finish_log[0] ==
    864               CapturingObserver::FinishEntry(0, true, info1));
    865 
    866   // Resolve "host1" again -- this time it  will be served from cache, but it
    867   // should still notify of completion.
    868   TestCompletionCallback callback;
    869   rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, NULL);
    870   ASSERT_EQ(OK, rv);  // Should complete synchronously.
    871 
    872   EXPECT_EQ(2U, observer.start_log.size());
    873   EXPECT_EQ(2U, observer.finish_log.size());
    874   EXPECT_EQ(0U, observer.cancel_log.size());
    875   EXPECT_TRUE(observer.start_log[1] ==
    876               CapturingObserver::StartOrCancelEntry(1, info1));
    877   EXPECT_TRUE(observer.finish_log[1] ==
    878               CapturingObserver::FinishEntry(1, true, info1));
    879 
    880   // Resolve "host2", setting referrer to "http://foobar.com"
    881   HostResolver::RequestInfo info2("host2", 70);
    882   info2.set_referrer(GURL("http://foobar.com"));
    883   rv = host_resolver->Resolve(info2, &addrlist, NULL, NULL, NULL);
    884   EXPECT_EQ(OK, rv);
    885 
    886   EXPECT_EQ(3U, observer.start_log.size());
    887   EXPECT_EQ(3U, observer.finish_log.size());
    888   EXPECT_EQ(0U, observer.cancel_log.size());
    889   EXPECT_TRUE(observer.start_log[2] ==
    890               CapturingObserver::StartOrCancelEntry(2, info2));
    891   EXPECT_TRUE(observer.finish_log[2] ==
    892               CapturingObserver::FinishEntry(2, true, info2));
    893 
    894   // Unregister the observer.
    895   host_resolver->RemoveObserver(&observer);
    896 
    897   // Resolve "host3"
    898   HostResolver::RequestInfo info3("host3", 70);
    899   host_resolver->Resolve(info3, &addrlist, NULL, NULL, NULL);
    900 
    901   // No effect this time, since observer was removed.
    902   EXPECT_EQ(3U, observer.start_log.size());
    903   EXPECT_EQ(3U, observer.finish_log.size());
    904   EXPECT_EQ(0U, observer.cancel_log.size());
    905 }
    906 
    907 // Tests that observers are sent OnCancelResolution() whenever a request is
    908 // cancelled. There are two ways to cancel a request:
    909 //  (1) Delete the HostResolver while job is outstanding.
    910 //  (2) Call HostResolver::CancelRequest() while a request is outstanding.
    911 TEST_F(HostResolverImplTest, CancellationObserver) {
    912   CapturingObserver observer;
    913   {
    914     // Create a host resolver and attach an observer.
    915     scoped_refptr<HostResolver> host_resolver(
    916         CreateHostResolverImpl(NULL));
    917     host_resolver->AddObserver(&observer);
    918 
    919     TestCompletionCallback callback;
    920 
    921     EXPECT_EQ(0U, observer.start_log.size());
    922     EXPECT_EQ(0U, observer.finish_log.size());
    923     EXPECT_EQ(0U, observer.cancel_log.size());
    924 
    925     // Start an async resolve for (host1:70).
    926     HostResolver::RequestInfo info1("host1", 70);
    927     HostResolver::RequestHandle req = NULL;
    928     AddressList addrlist;
    929     int rv = host_resolver->Resolve(info1, &addrlist, &callback, &req, NULL);
    930     EXPECT_EQ(ERR_IO_PENDING, rv);
    931     EXPECT_TRUE(NULL != req);
    932 
    933     EXPECT_EQ(1U, observer.start_log.size());
    934     EXPECT_EQ(0U, observer.finish_log.size());
    935     EXPECT_EQ(0U, observer.cancel_log.size());
    936 
    937     EXPECT_TRUE(observer.start_log[0] ==
    938                 CapturingObserver::StartOrCancelEntry(0, info1));
    939 
    940     // Cancel the request.
    941     host_resolver->CancelRequest(req);
    942 
    943     EXPECT_EQ(1U, observer.start_log.size());
    944     EXPECT_EQ(0U, observer.finish_log.size());
    945     EXPECT_EQ(1U, observer.cancel_log.size());
    946 
    947     EXPECT_TRUE(observer.cancel_log[0] ==
    948                 CapturingObserver::StartOrCancelEntry(0, info1));
    949 
    950     // Start an async request for (host2:60)
    951     HostResolver::RequestInfo info2("host2", 60);
    952     rv = host_resolver->Resolve(info2, &addrlist, &callback, NULL, NULL);
    953     EXPECT_EQ(ERR_IO_PENDING, rv);
    954     EXPECT_TRUE(NULL != req);
    955 
    956     EXPECT_EQ(2U, observer.start_log.size());
    957     EXPECT_EQ(0U, observer.finish_log.size());
    958     EXPECT_EQ(1U, observer.cancel_log.size());
    959 
    960     EXPECT_TRUE(observer.start_log[1] ==
    961                 CapturingObserver::StartOrCancelEntry(1, info2));
    962 
    963     // Upon exiting this scope, HostResolver is destroyed, so all requests are
    964     // implicitly cancelled.
    965   }
    966 
    967   // Check that destroying the HostResolver sent a notification for
    968   // cancellation of host2:60 request.
    969 
    970   EXPECT_EQ(2U, observer.start_log.size());
    971   EXPECT_EQ(0U, observer.finish_log.size());
    972   EXPECT_EQ(2U, observer.cancel_log.size());
    973 
    974   HostResolver::RequestInfo info("host2", 60);
    975   EXPECT_TRUE(observer.cancel_log[1] ==
    976               CapturingObserver::StartOrCancelEntry(1, info));
    977 }
    978 
    979 // Test that IP address changes flush the cache.
    980 TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) {
    981   MockNetworkChangeNotifier mock_network_change_notifier;
    982   scoped_refptr<HostResolver> host_resolver(
    983       new HostResolverImpl(NULL, CreateDefaultCache(),
    984                            &mock_network_change_notifier,
    985                            kMaxJobs));
    986 
    987   AddressList addrlist;
    988 
    989   // Resolve "host1".
    990   HostResolver::RequestInfo info1("host1", 70);
    991   TestCompletionCallback callback;
    992   int rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, NULL);
    993   EXPECT_EQ(ERR_IO_PENDING, rv);
    994   EXPECT_EQ(OK, callback.WaitForResult());
    995 
    996   // Resolve "host1" again -- this time it will be served from cache, but it
    997   // should still notify of completion.
    998   rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, NULL);
    999   ASSERT_EQ(OK, rv);  // Should complete synchronously.
   1000 
   1001   // Flush cache by triggering an IP address change.
   1002   mock_network_change_notifier.NotifyIPAddressChange();
   1003 
   1004   // Resolve "host1" again -- this time it won't be served from cache, so it
   1005   // will complete asynchronously.
   1006   rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, NULL);
   1007   ASSERT_EQ(ERR_IO_PENDING, rv);  // Should complete asynchronously.
   1008   EXPECT_EQ(OK, callback.WaitForResult());
   1009 }
   1010 
   1011 // Tests that when the maximum threads is set to 1, requests are dequeued
   1012 // in order of priority.
   1013 TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) {
   1014   scoped_refptr<CapturingHostResolverProc> resolver_proc =
   1015       new CapturingHostResolverProc(NULL);
   1016 
   1017   // This HostResolverImpl will only allow 1 outstanding resolve at a time.
   1018   size_t kMaxJobs = 1u;
   1019   scoped_refptr<HostResolver> host_resolver(
   1020       new HostResolverImpl(resolver_proc, CreateDefaultCache(),
   1021                            NULL, kMaxJobs));
   1022 
   1023   CapturingObserver observer;
   1024   host_resolver->AddObserver(&observer);
   1025 
   1026   // Note that at this point the CapturingHostResolverProc is blocked, so any
   1027   // requests we make will not complete.
   1028 
   1029   HostResolver::RequestInfo req[] = {
   1030       CreateResolverRequest("req0", LOW),
   1031       CreateResolverRequest("req1", MEDIUM),
   1032       CreateResolverRequest("req2", MEDIUM),
   1033       CreateResolverRequest("req3", LOW),
   1034       CreateResolverRequest("req4", HIGHEST),
   1035       CreateResolverRequest("req5", LOW),
   1036       CreateResolverRequest("req6", LOW),
   1037       CreateResolverRequest("req5", HIGHEST),
   1038   };
   1039 
   1040   TestCompletionCallback callback[arraysize(req)];
   1041   AddressList addrlist[arraysize(req)];
   1042 
   1043   // Start all of the requests.
   1044   for (size_t i = 0; i < arraysize(req); ++i) {
   1045     int rv = host_resolver->Resolve(req[i], &addrlist[i],
   1046                                     &callback[i], NULL, NULL);
   1047     EXPECT_EQ(ERR_IO_PENDING, rv);
   1048   }
   1049 
   1050   // Unblock the resolver thread so the requests can run.
   1051   resolver_proc->Signal();
   1052 
   1053   // Wait for all the requests to complete succesfully.
   1054   for (size_t i = 0; i < arraysize(req); ++i) {
   1055     EXPECT_EQ(OK, callback[i].WaitForResult()) << "i=" << i;
   1056   }
   1057 
   1058   host_resolver->RemoveObserver(&observer);
   1059 
   1060   // Since we have restricted to a single concurrent thread in the jobpool,
   1061   // the requests should complete in order of priority (with the exception
   1062   // of the first request, which gets started right away, since there is
   1063   // nothing outstanding).
   1064   std::vector<std::string> capture_list = resolver_proc->GetCaptureList();
   1065   ASSERT_EQ(7u, capture_list.size());
   1066 
   1067   EXPECT_EQ("req0", capture_list[0]);
   1068   EXPECT_EQ("req4", capture_list[1]);
   1069   EXPECT_EQ("req5", capture_list[2]);
   1070   EXPECT_EQ("req1", capture_list[3]);
   1071   EXPECT_EQ("req2", capture_list[4]);
   1072   EXPECT_EQ("req3", capture_list[5]);
   1073   EXPECT_EQ("req6", capture_list[6]);
   1074 
   1075   // Also check using the observer's trace.
   1076   EXPECT_EQ(8U, observer.start_log.size());
   1077   EXPECT_EQ(8U, observer.finish_log.size());
   1078   EXPECT_EQ(0U, observer.cancel_log.size());
   1079 
   1080   EXPECT_EQ("req0", observer.finish_log[0].info.hostname());
   1081   EXPECT_EQ("req4", observer.finish_log[1].info.hostname());
   1082 
   1083   // There were two requests for "req5". The highest priority
   1084   // one should have been dispatched earlier.
   1085   EXPECT_EQ("req5", observer.finish_log[2].info.hostname());
   1086   EXPECT_EQ("req5", observer.finish_log[3].info.hostname());
   1087   EXPECT_EQ(HIGHEST, observer.finish_log[2].info.priority());
   1088   EXPECT_EQ(LOW, observer.finish_log[3].info.priority());
   1089 
   1090   EXPECT_EQ("req1", observer.finish_log[4].info.hostname());
   1091   EXPECT_EQ("req2", observer.finish_log[5].info.hostname());
   1092   EXPECT_EQ("req3", observer.finish_log[6].info.hostname());
   1093   EXPECT_EQ("req6", observer.finish_log[7].info.hostname());
   1094 }
   1095 
   1096 // Try cancelling a request which has not been attached to a job yet.
   1097 TEST_F(HostResolverImplTest, CancelPendingRequest) {
   1098   scoped_refptr<CapturingHostResolverProc> resolver_proc =
   1099       new CapturingHostResolverProc(NULL);
   1100 
   1101   // This HostResolverImpl will only allow 1 outstanding resolve at a time.
   1102   const size_t kMaxJobs = 1u;
   1103   scoped_refptr<HostResolver> host_resolver(
   1104       new HostResolverImpl(resolver_proc, CreateDefaultCache(),
   1105                            NULL, kMaxJobs));
   1106 
   1107   // Note that at this point the CapturingHostResolverProc is blocked, so any
   1108   // requests we make will not complete.
   1109 
   1110   HostResolver::RequestInfo req[] = {
   1111       CreateResolverRequest("req0", LOWEST),
   1112       CreateResolverRequest("req1", HIGHEST),  // Will cancel.
   1113       CreateResolverRequest("req2", MEDIUM),
   1114       CreateResolverRequest("req3", LOW),
   1115       CreateResolverRequest("req4", HIGHEST),   // Will cancel.
   1116       CreateResolverRequest("req5", LOWEST),    // Will cancel.
   1117       CreateResolverRequest("req6", MEDIUM),
   1118   };
   1119 
   1120   TestCompletionCallback callback[arraysize(req)];
   1121   AddressList addrlist[arraysize(req)];
   1122   HostResolver::RequestHandle handle[arraysize(req)];
   1123 
   1124   // Start all of the requests.
   1125   for (size_t i = 0; i < arraysize(req); ++i) {
   1126     int rv = host_resolver->Resolve(req[i], &addrlist[i],
   1127                                     &callback[i], &handle[i], NULL);
   1128     EXPECT_EQ(ERR_IO_PENDING, rv);
   1129   }
   1130 
   1131   // Cancel some requests
   1132   host_resolver->CancelRequest(handle[1]);
   1133   host_resolver->CancelRequest(handle[4]);
   1134   host_resolver->CancelRequest(handle[5]);
   1135   handle[1] = handle[4] = handle[5] = NULL;
   1136 
   1137   // Unblock the resolver thread so the requests can run.
   1138   resolver_proc->Signal();
   1139 
   1140   // Wait for all the requests to complete succesfully.
   1141   for (size_t i = 0; i < arraysize(req); ++i) {
   1142     if (!handle[i])
   1143       continue;  // Don't wait for the requests we cancelled.
   1144     EXPECT_EQ(OK, callback[i].WaitForResult());
   1145   }
   1146 
   1147   // Verify that they called out the the resolver proc (which runs on the
   1148   // resolver thread) in the expected order.
   1149   std::vector<std::string> capture_list = resolver_proc->GetCaptureList();
   1150   ASSERT_EQ(4u, capture_list.size());
   1151 
   1152   EXPECT_EQ("req0", capture_list[0]);
   1153   EXPECT_EQ("req2", capture_list[1]);
   1154   EXPECT_EQ("req6", capture_list[2]);
   1155   EXPECT_EQ("req3", capture_list[3]);
   1156 }
   1157 
   1158 // Test that when too many requests are enqueued, old ones start to be aborted.
   1159 TEST_F(HostResolverImplTest, QueueOverflow) {
   1160   scoped_refptr<CapturingHostResolverProc> resolver_proc =
   1161       new CapturingHostResolverProc(NULL);
   1162 
   1163   // This HostResolverImpl will only allow 1 outstanding resolve at a time.
   1164   const size_t kMaxOutstandingJobs = 1u;
   1165   scoped_refptr<HostResolverImpl> host_resolver(
   1166       new HostResolverImpl(resolver_proc, CreateDefaultCache(),
   1167                            NULL, kMaxOutstandingJobs));
   1168 
   1169   // Only allow up to 3 requests to be enqueued at a time.
   1170   const size_t kMaxPendingRequests = 3u;
   1171   host_resolver->SetPoolConstraints(HostResolverImpl::POOL_NORMAL,
   1172                                     kMaxOutstandingJobs,
   1173                                     kMaxPendingRequests);
   1174 
   1175   // Note that at this point the CapturingHostResolverProc is blocked, so any
   1176   // requests we make will not complete.
   1177 
   1178   HostResolver::RequestInfo req[] = {
   1179       CreateResolverRequest("req0", LOWEST),
   1180       CreateResolverRequest("req1", HIGHEST),
   1181       CreateResolverRequest("req2", MEDIUM),
   1182       CreateResolverRequest("req3", MEDIUM),
   1183 
   1184       // At this point, there are 3 enqueued requests.
   1185       // Insertion of subsequent requests will cause evictions
   1186       // based on priority.
   1187 
   1188       CreateResolverRequest("req4", LOW),      // Evicts itself!
   1189       CreateResolverRequest("req5", MEDIUM),   // Evicts req3
   1190       CreateResolverRequest("req6", HIGHEST),  // Evicts req5.
   1191       CreateResolverRequest("req7", MEDIUM),   // Evicts req2.
   1192   };
   1193 
   1194   TestCompletionCallback callback[arraysize(req)];
   1195   AddressList addrlist[arraysize(req)];
   1196   HostResolver::RequestHandle handle[arraysize(req)];
   1197 
   1198   // Start all of the requests.
   1199   for (size_t i = 0; i < arraysize(req); ++i) {
   1200     int rv = host_resolver->Resolve(req[i], &addrlist[i],
   1201                                     &callback[i], &handle[i], NULL);
   1202     if (i == 4u)
   1203       EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, rv);
   1204     else
   1205       EXPECT_EQ(ERR_IO_PENDING, rv) << i;
   1206   }
   1207 
   1208   // Unblock the resolver thread so the requests can run.
   1209   resolver_proc->Signal();
   1210 
   1211   // Requests 3, 5, 2 will have been evicted due to queue overflow.
   1212   size_t reqs_expected_to_fail[] = { 2, 3, 5 };
   1213   for (size_t i = 0; i < arraysize(reqs_expected_to_fail); ++i) {
   1214     EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE,
   1215               callback[reqs_expected_to_fail[i]].WaitForResult());
   1216   }
   1217 
   1218   // The rest should succeed.
   1219   size_t reqs_expected_to_succeed[] = { 0, 1, 6, 7 };
   1220   for (size_t i = 0; i < arraysize(reqs_expected_to_succeed); ++i) {
   1221     EXPECT_EQ(OK, callback[reqs_expected_to_succeed[i]].WaitForResult());
   1222   }
   1223 
   1224   // Verify that they called out the the resolver proc (which runs on the
   1225   // resolver thread) in the expected order.
   1226   std::vector<std::string> capture_list = resolver_proc->GetCaptureList();
   1227   ASSERT_EQ(4u, capture_list.size());
   1228 
   1229   EXPECT_EQ("req0", capture_list[0]);
   1230   EXPECT_EQ("req1", capture_list[1]);
   1231   EXPECT_EQ("req6", capture_list[2]);
   1232   EXPECT_EQ("req7", capture_list[3]);
   1233 }
   1234 
   1235 }  // namespace
   1236 
   1237 }  // namespace net
   1238