1 // Copyright (c) 2011 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/memory/ref_counted.h" 11 #include "base/message_loop.h" 12 #include "base/string_util.h" 13 #include "base/stringprintf.h" 14 #include "net/base/address_list.h" 15 #include "net/base/completion_callback.h" 16 #include "net/base/mock_host_resolver.h" 17 #include "net/base/net_errors.h" 18 #include "net/base/net_log_unittest.h" 19 #include "net/base/net_util.h" 20 #include "net/base/sys_addrinfo.h" 21 #include "net/base/test_completion_callback.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 // TODO(eroman): 25 // - Test mixing async with sync (in particular how does sync update the 26 // cache while an async is already pending). 27 28 namespace net { 29 30 namespace { 31 32 HostCache* CreateDefaultCache() { 33 return new HostCache( 34 100, // max cache entries. 35 base::TimeDelta::FromMinutes(1), 36 base::TimeDelta::FromSeconds(0)); 37 } 38 39 static const size_t kMaxJobs = 10u; 40 41 HostResolverImpl* CreateHostResolverImpl(HostResolverProc* resolver_proc) { 42 return new HostResolverImpl(resolver_proc, CreateDefaultCache(), kMaxJobs, 43 NULL); 44 } 45 46 // Helper to create a HostResolver::RequestInfo. 47 HostResolver::RequestInfo CreateResolverRequest( 48 const std::string& hostname, 49 RequestPriority priority) { 50 HostResolver::RequestInfo info(HostPortPair(hostname, 80)); 51 info.set_priority(priority); 52 return info; 53 } 54 55 // Helper to create a HostResolver::RequestInfo. 56 HostResolver::RequestInfo CreateResolverRequestForAddressFamily( 57 const std::string& hostname, 58 RequestPriority priority, 59 AddressFamily address_family) { 60 HostResolver::RequestInfo info(HostPortPair(hostname, 80)); 61 info.set_priority(priority); 62 info.set_address_family(address_family); 63 return info; 64 } 65 66 // A variant of WaitingHostResolverProc that pushes each host mapped into a 67 // list. 68 // (and uses a manual-reset event rather than auto-reset). 69 class CapturingHostResolverProc : public HostResolverProc { 70 public: 71 struct CaptureEntry { 72 CaptureEntry(const std::string& hostname, AddressFamily address_family) 73 : hostname(hostname), address_family(address_family) {} 74 std::string hostname; 75 AddressFamily address_family; 76 }; 77 78 typedef std::vector<CaptureEntry> CaptureList; 79 80 explicit CapturingHostResolverProc(HostResolverProc* previous) 81 : HostResolverProc(previous), event_(true, false) { 82 } 83 84 void Signal() { 85 event_.Signal(); 86 } 87 88 virtual int Resolve(const std::string& hostname, 89 AddressFamily address_family, 90 HostResolverFlags host_resolver_flags, 91 AddressList* addrlist, 92 int* os_error) { 93 event_.Wait(); 94 { 95 base::AutoLock l(lock_); 96 capture_list_.push_back(CaptureEntry(hostname, address_family)); 97 } 98 return ResolveUsingPrevious(hostname, address_family, 99 host_resolver_flags, addrlist, os_error); 100 } 101 102 CaptureList GetCaptureList() const { 103 CaptureList copy; 104 { 105 base::AutoLock l(lock_); 106 copy = capture_list_; 107 } 108 return copy; 109 } 110 111 private: 112 ~CapturingHostResolverProc() {} 113 114 CaptureList capture_list_; 115 mutable base::Lock lock_; 116 base::WaitableEvent event_; 117 }; 118 119 // This resolver function creates an IPv4 address, whose numeral value 120 // describes a hash of the requested hostname, and the value of the requested 121 // address_family. 122 // 123 // The resolved address for (hostname, address_family) will take the form: 124 // 192.x.y.z 125 // 126 // Where: 127 // x = length of hostname 128 // y = ASCII value of hostname[0] 129 // z = value of address_family 130 // 131 class EchoingHostResolverProc : public HostResolverProc { 132 public: 133 EchoingHostResolverProc() : HostResolverProc(NULL) {} 134 135 virtual int Resolve(const std::string& hostname, 136 AddressFamily address_family, 137 HostResolverFlags host_resolver_flags, 138 AddressList* addrlist, 139 int* os_error) { 140 // Encode the request's hostname and address_family in the output address. 141 std::string ip_literal = base::StringPrintf("192.%d.%d.%d", 142 static_cast<int>(hostname.size()), 143 static_cast<int>(hostname[0]), 144 static_cast<int>(address_family)); 145 146 return SystemHostResolverProc(ip_literal, 147 ADDRESS_FAMILY_UNSPECIFIED, 148 host_resolver_flags, 149 addrlist, os_error); 150 } 151 }; 152 153 // Helper that represents a single Resolve() result, used to inspect all the 154 // resolve results by forwarding them to Delegate. 155 class ResolveRequest { 156 public: 157 // Delegate interface, for notification when the ResolveRequest completes. 158 class Delegate { 159 public: 160 virtual ~Delegate() {} 161 virtual void OnCompleted(ResolveRequest* resolve) = 0; 162 }; 163 164 ResolveRequest(HostResolver* resolver, 165 const std::string& hostname, 166 int port, 167 Delegate* delegate) 168 : info_(HostPortPair(hostname, port)), 169 resolver_(resolver), 170 delegate_(delegate), 171 ALLOW_THIS_IN_INITIALIZER_LIST( 172 callback_(this, &ResolveRequest::OnLookupFinished)) { 173 // Start the request. 174 int err = resolver->Resolve(info_, &addrlist_, &callback_, &req_, 175 BoundNetLog()); 176 EXPECT_EQ(ERR_IO_PENDING, err); 177 } 178 179 ResolveRequest(HostResolver* resolver, 180 const HostResolver::RequestInfo& info, 181 Delegate* delegate) 182 : info_(info), resolver_(resolver), delegate_(delegate), 183 ALLOW_THIS_IN_INITIALIZER_LIST( 184 callback_(this, &ResolveRequest::OnLookupFinished)) { 185 // Start the request. 186 int err = resolver->Resolve(info, &addrlist_, &callback_, &req_, 187 BoundNetLog()); 188 EXPECT_EQ(ERR_IO_PENDING, err); 189 } 190 191 void Cancel() { 192 resolver_->CancelRequest(req_); 193 } 194 195 const std::string& hostname() const { 196 return info_.hostname(); 197 } 198 199 int port() const { 200 return info_.port(); 201 } 202 203 int result() const { 204 return result_; 205 } 206 207 const AddressList& addrlist() const { 208 return addrlist_; 209 } 210 211 HostResolver* resolver() const { 212 return resolver_; 213 } 214 215 private: 216 void OnLookupFinished(int result) { 217 result_ = result; 218 delegate_->OnCompleted(this); 219 } 220 221 // The request details. 222 HostResolver::RequestInfo info_; 223 HostResolver::RequestHandle req_; 224 225 // The result of the resolve. 226 int result_; 227 AddressList addrlist_; 228 229 HostResolver* resolver_; 230 231 Delegate* delegate_; 232 CompletionCallbackImpl<ResolveRequest> callback_; 233 234 DISALLOW_COPY_AND_ASSIGN(ResolveRequest); 235 }; 236 237 class HostResolverImplTest : public testing::Test { 238 public: 239 HostResolverImplTest() 240 : callback_called_(false), 241 ALLOW_THIS_IN_INITIALIZER_LIST( 242 callback_(this, &HostResolverImplTest::OnLookupFinished)) { 243 } 244 245 protected: 246 bool callback_called_; 247 int callback_result_; 248 CompletionCallbackImpl<HostResolverImplTest> callback_; 249 250 private: 251 void OnLookupFinished(int result) { 252 callback_called_ = true; 253 callback_result_ = result; 254 MessageLoop::current()->Quit(); 255 } 256 }; 257 258 TEST_F(HostResolverImplTest, SynchronousLookup) { 259 AddressList addrlist; 260 const int kPortnum = 80; 261 262 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 263 new RuleBasedHostResolverProc(NULL)); 264 resolver_proc->AddRule("just.testing", "192.168.1.42"); 265 266 scoped_ptr<HostResolver> host_resolver( 267 CreateHostResolverImpl(resolver_proc)); 268 269 HostResolver::RequestInfo info(HostPortPair("just.testing", kPortnum)); 270 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 271 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); 272 EXPECT_EQ(OK, err); 273 274 CapturingNetLog::EntryList entries; 275 log.GetEntries(&entries); 276 277 EXPECT_EQ(2u, entries.size()); 278 EXPECT_TRUE(LogContainsBeginEvent( 279 entries, 0, NetLog::TYPE_HOST_RESOLVER_IMPL)); 280 EXPECT_TRUE(LogContainsEndEvent( 281 entries, 1, NetLog::TYPE_HOST_RESOLVER_IMPL)); 282 283 const struct addrinfo* ainfo = addrlist.head(); 284 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 285 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 286 287 const struct sockaddr* sa = ainfo->ai_addr; 288 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 289 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 290 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); 291 } 292 293 TEST_F(HostResolverImplTest, AsynchronousLookup) { 294 AddressList addrlist; 295 const int kPortnum = 80; 296 297 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 298 new RuleBasedHostResolverProc(NULL)); 299 resolver_proc->AddRule("just.testing", "192.168.1.42"); 300 301 scoped_ptr<HostResolver> host_resolver( 302 CreateHostResolverImpl(resolver_proc)); 303 304 HostResolver::RequestInfo info(HostPortPair("just.testing", kPortnum)); 305 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 306 int err = host_resolver->Resolve(info, &addrlist, &callback_, NULL, 307 log.bound()); 308 EXPECT_EQ(ERR_IO_PENDING, err); 309 310 CapturingNetLog::EntryList entries; 311 log.GetEntries(&entries); 312 313 EXPECT_EQ(1u, entries.size()); 314 EXPECT_TRUE(LogContainsBeginEvent( 315 entries, 0, NetLog::TYPE_HOST_RESOLVER_IMPL)); 316 317 MessageLoop::current()->Run(); 318 319 ASSERT_TRUE(callback_called_); 320 ASSERT_EQ(OK, callback_result_); 321 322 log.GetEntries(&entries); 323 324 EXPECT_EQ(2u, entries.size()); 325 EXPECT_TRUE(LogContainsEndEvent( 326 entries, 1, NetLog::TYPE_HOST_RESOLVER_IMPL)); 327 328 const struct addrinfo* ainfo = addrlist.head(); 329 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 330 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 331 332 const struct sockaddr* sa = ainfo->ai_addr; 333 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 334 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 335 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); 336 } 337 338 TEST_F(HostResolverImplTest, CanceledAsynchronousLookup) { 339 scoped_refptr<WaitingHostResolverProc> resolver_proc( 340 new WaitingHostResolverProc(NULL)); 341 342 CapturingNetLog net_log(CapturingNetLog::kUnbounded); 343 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 344 { 345 scoped_ptr<HostResolver> host_resolver( 346 new HostResolverImpl(resolver_proc, 347 CreateDefaultCache(), 348 kMaxJobs, 349 &net_log)); 350 AddressList addrlist; 351 const int kPortnum = 80; 352 353 HostResolver::RequestInfo info(HostPortPair("just.testing", kPortnum)); 354 int err = host_resolver->Resolve(info, &addrlist, &callback_, NULL, 355 log.bound()); 356 EXPECT_EQ(ERR_IO_PENDING, err); 357 358 // Make sure we will exit the queue even when callback is not called. 359 MessageLoop::current()->PostDelayedTask(FROM_HERE, 360 new MessageLoop::QuitTask(), 361 1000); 362 MessageLoop::current()->Run(); 363 } 364 365 resolver_proc->Signal(); 366 367 CapturingNetLog::EntryList entries; 368 log.GetEntries(&entries); 369 370 EXPECT_EQ(2u, entries.size()); 371 EXPECT_TRUE(LogContainsBeginEvent( 372 entries, 0, NetLog::TYPE_HOST_RESOLVER_IMPL)); 373 EXPECT_TRUE(LogContainsEndEvent( 374 entries, 1, NetLog::TYPE_HOST_RESOLVER_IMPL)); 375 376 CapturingNetLog::EntryList net_log_entries; 377 net_log.GetEntries(&net_log_entries); 378 379 int pos = ExpectLogContainsSomewhereAfter(net_log_entries, 0, 380 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, 381 NetLog::PHASE_BEGIN); 382 pos = ExpectLogContainsSomewhereAfter(net_log_entries, pos + 1, 383 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 384 NetLog::PHASE_BEGIN); 385 // Both Job and Request need to be cancelled. 386 pos = ExpectLogContainsSomewhereAfter(net_log_entries, pos + 1, 387 NetLog::TYPE_CANCELLED, 388 NetLog::PHASE_NONE); 389 // Don't care about order in which they end, or when the other one is 390 // cancelled. 391 ExpectLogContainsSomewhereAfter(net_log_entries, pos + 1, 392 NetLog::TYPE_CANCELLED, 393 NetLog::PHASE_NONE); 394 ExpectLogContainsSomewhereAfter(net_log_entries, pos + 1, 395 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, 396 NetLog::PHASE_END); 397 ExpectLogContainsSomewhereAfter(net_log_entries, pos + 1, 398 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 399 NetLog::PHASE_END); 400 401 EXPECT_FALSE(callback_called_); 402 } 403 404 TEST_F(HostResolverImplTest, NumericIPv4Address) { 405 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in. 406 407 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 408 new RuleBasedHostResolverProc(NULL)); 409 resolver_proc->AllowDirectLookup("*"); 410 411 scoped_ptr<HostResolver> host_resolver( 412 CreateHostResolverImpl(resolver_proc)); 413 AddressList addrlist; 414 const int kPortnum = 5555; 415 HostResolver::RequestInfo info(HostPortPair("127.1.2.3", kPortnum)); 416 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); 417 EXPECT_EQ(OK, err); 418 419 const struct addrinfo* ainfo = addrlist.head(); 420 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 421 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 422 423 const struct sockaddr* sa = ainfo->ai_addr; 424 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 425 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 426 EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr); 427 } 428 429 TEST_F(HostResolverImplTest, NumericIPv6Address) { 430 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 431 new RuleBasedHostResolverProc(NULL)); 432 resolver_proc->AllowDirectLookup("*"); 433 434 // Resolve a plain IPv6 address. Don't worry about [brackets], because 435 // the caller should have removed them. 436 scoped_ptr<HostResolver> host_resolver( 437 CreateHostResolverImpl(resolver_proc)); 438 AddressList addrlist; 439 const int kPortnum = 5555; 440 HostResolver::RequestInfo info(HostPortPair("2001:db8::1", kPortnum)); 441 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); 442 EXPECT_EQ(OK, err); 443 444 const struct addrinfo* ainfo = addrlist.head(); 445 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 446 EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen); 447 448 const struct sockaddr* sa = ainfo->ai_addr; 449 const struct sockaddr_in6* sa_in6 = (const struct sockaddr_in6*) sa; 450 EXPECT_TRUE(htons(kPortnum) == sa_in6->sin6_port); 451 452 const uint8 expect_addr[] = { 453 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 455 }; 456 for (int i = 0; i < 16; i++) { 457 EXPECT_EQ(expect_addr[i], sa_in6->sin6_addr.s6_addr[i]); 458 } 459 } 460 461 TEST_F(HostResolverImplTest, EmptyHost) { 462 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 463 new RuleBasedHostResolverProc(NULL)); 464 resolver_proc->AllowDirectLookup("*"); 465 466 scoped_ptr<HostResolver> host_resolver( 467 CreateHostResolverImpl(resolver_proc)); 468 AddressList addrlist; 469 const int kPortnum = 5555; 470 HostResolver::RequestInfo info(HostPortPair("", kPortnum)); 471 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); 472 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); 473 } 474 475 TEST_F(HostResolverImplTest, LongHost) { 476 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 477 new RuleBasedHostResolverProc(NULL)); 478 resolver_proc->AllowDirectLookup("*"); 479 480 scoped_ptr<HostResolver> host_resolver( 481 CreateHostResolverImpl(resolver_proc)); 482 AddressList addrlist; 483 const int kPortnum = 5555; 484 std::string hostname(4097, 'a'); 485 HostResolver::RequestInfo info(HostPortPair(hostname, kPortnum)); 486 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); 487 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); 488 } 489 490 // Helper class used by HostResolverImplTest.DeDupeRequests. It receives request 491 // completion notifications for all the resolves, so it can tally up and 492 // determine when we are done. 493 class DeDupeRequestsVerifier : public ResolveRequest::Delegate { 494 public: 495 explicit DeDupeRequestsVerifier(CapturingHostResolverProc* resolver_proc) 496 : count_a_(0), count_b_(0), resolver_proc_(resolver_proc) {} 497 498 // The test does 5 resolves (which can complete in any order). 499 virtual void OnCompleted(ResolveRequest* resolve) { 500 // Tally up how many requests we have seen. 501 if (resolve->hostname() == "a") { 502 count_a_++; 503 } else if (resolve->hostname() == "b") { 504 count_b_++; 505 } else { 506 FAIL() << "Unexpected hostname: " << resolve->hostname(); 507 } 508 509 // Check that the port was set correctly. 510 EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort()); 511 512 // Check whether all the requests have finished yet. 513 int total_completions = count_a_ + count_b_; 514 if (total_completions == 5) { 515 EXPECT_EQ(2, count_a_); 516 EXPECT_EQ(3, count_b_); 517 518 // The resolver_proc should have been called only twice -- once with "a", 519 // once with "b". 520 CapturingHostResolverProc::CaptureList capture_list = 521 resolver_proc_->GetCaptureList(); 522 EXPECT_EQ(2U, capture_list.size()); 523 524 // End this test, we are done. 525 MessageLoop::current()->Quit(); 526 } 527 } 528 529 private: 530 int count_a_; 531 int count_b_; 532 CapturingHostResolverProc* resolver_proc_; 533 534 DISALLOW_COPY_AND_ASSIGN(DeDupeRequestsVerifier); 535 }; 536 537 TEST_F(HostResolverImplTest, DeDupeRequests) { 538 // Use a capturing resolver_proc, since the verifier needs to know what calls 539 // reached Resolve(). Also, the capturing resolver_proc is initially blocked. 540 scoped_refptr<CapturingHostResolverProc> resolver_proc( 541 new CapturingHostResolverProc(NULL)); 542 543 scoped_ptr<HostResolver> host_resolver( 544 CreateHostResolverImpl(resolver_proc)); 545 546 // The class will receive callbacks for when each resolve completes. It 547 // checks that the right things happened. 548 DeDupeRequestsVerifier verifier(resolver_proc.get()); 549 550 // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is 551 // blocked, these should all pile up until we signal it. 552 553 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); 554 ResolveRequest req2(host_resolver.get(), "b", 80, &verifier); 555 ResolveRequest req3(host_resolver.get(), "b", 81, &verifier); 556 ResolveRequest req4(host_resolver.get(), "a", 82, &verifier); 557 ResolveRequest req5(host_resolver.get(), "b", 83, &verifier); 558 559 // Ready, Set, GO!!! 560 resolver_proc->Signal(); 561 562 // |verifier| will send quit message once all the requests have finished. 563 MessageLoop::current()->Run(); 564 } 565 566 // Helper class used by HostResolverImplTest.CancelMultipleRequests. 567 class CancelMultipleRequestsVerifier : public ResolveRequest::Delegate { 568 public: 569 CancelMultipleRequestsVerifier() {} 570 571 // The cancels kill all but one request. 572 virtual void OnCompleted(ResolveRequest* resolve) { 573 EXPECT_EQ("a", resolve->hostname()); 574 EXPECT_EQ(82, resolve->port()); 575 576 // Check that the port was set correctly. 577 EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort()); 578 579 // End this test, we are done. 580 MessageLoop::current()->Quit(); 581 } 582 583 private: 584 DISALLOW_COPY_AND_ASSIGN(CancelMultipleRequestsVerifier); 585 }; 586 587 TEST_F(HostResolverImplTest, CancelMultipleRequests) { 588 // Use a capturing resolver_proc, since the verifier needs to know what calls 589 // reached Resolver(). Also, the capturing resolver_proc is initially 590 // blocked. 591 scoped_refptr<CapturingHostResolverProc> resolver_proc( 592 new CapturingHostResolverProc(NULL)); 593 594 scoped_ptr<HostResolver> host_resolver( 595 CreateHostResolverImpl(resolver_proc)); 596 597 // The class will receive callbacks for when each resolve completes. It 598 // checks that the right things happened. 599 CancelMultipleRequestsVerifier verifier; 600 601 // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is 602 // blocked, these should all pile up until we signal it. 603 604 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); 605 ResolveRequest req2(host_resolver.get(), "b", 80, &verifier); 606 ResolveRequest req3(host_resolver.get(), "b", 81, &verifier); 607 ResolveRequest req4(host_resolver.get(), "a", 82, &verifier); 608 ResolveRequest req5(host_resolver.get(), "b", 83, &verifier); 609 610 // Cancel everything except request 4. 611 req1.Cancel(); 612 req2.Cancel(); 613 req3.Cancel(); 614 req5.Cancel(); 615 616 // Ready, Set, GO!!! 617 resolver_proc->Signal(); 618 619 // |verifier| will send quit message once all the requests have finished. 620 MessageLoop::current()->Run(); 621 } 622 623 // Helper class used by HostResolverImplTest.CancelWithinCallback. 624 class CancelWithinCallbackVerifier : public ResolveRequest::Delegate { 625 public: 626 CancelWithinCallbackVerifier() 627 : req_to_cancel1_(NULL), req_to_cancel2_(NULL), num_completions_(0) { 628 } 629 630 virtual void OnCompleted(ResolveRequest* resolve) { 631 num_completions_++; 632 633 // Port 80 is the first request that the callback will be invoked for. 634 // While we are executing within that callback, cancel the other requests 635 // in the job and start another request. 636 if (80 == resolve->port()) { 637 EXPECT_EQ("a", resolve->hostname()); 638 639 req_to_cancel1_->Cancel(); 640 req_to_cancel2_->Cancel(); 641 642 // Start a request (so we can make sure the canceled requests don't 643 // complete before "finalrequest" finishes. 644 final_request_.reset(new ResolveRequest( 645 resolve->resolver(), "finalrequest", 70, this)); 646 647 } else if (83 == resolve->port()) { 648 EXPECT_EQ("a", resolve->hostname()); 649 } else if (resolve->hostname() == "finalrequest") { 650 EXPECT_EQ(70, resolve->addrlist().GetPort()); 651 652 // End this test, we are done. 653 MessageLoop::current()->Quit(); 654 } else { 655 FAIL() << "Unexpected completion: " << resolve->hostname() << ", " 656 << resolve->port(); 657 } 658 } 659 660 void SetRequestsToCancel(ResolveRequest* req_to_cancel1, 661 ResolveRequest* req_to_cancel2) { 662 req_to_cancel1_ = req_to_cancel1; 663 req_to_cancel2_ = req_to_cancel2; 664 } 665 666 private: 667 scoped_ptr<ResolveRequest> final_request_; 668 ResolveRequest* req_to_cancel1_; 669 ResolveRequest* req_to_cancel2_; 670 int num_completions_; 671 DISALLOW_COPY_AND_ASSIGN(CancelWithinCallbackVerifier); 672 }; 673 674 TEST_F(HostResolverImplTest, CancelWithinCallback) { 675 // Use a capturing resolver_proc, since the verifier needs to know what calls 676 // reached Resolver(). Also, the capturing resolver_proc is initially 677 // blocked. 678 scoped_refptr<CapturingHostResolverProc> resolver_proc( 679 new CapturingHostResolverProc(NULL)); 680 681 scoped_ptr<HostResolver> host_resolver( 682 CreateHostResolverImpl(resolver_proc)); 683 684 // The class will receive callbacks for when each resolve completes. It 685 // checks that the right things happened. 686 CancelWithinCallbackVerifier verifier; 687 688 // Start 4 requests, duplicating hosts "a". Since the resolver_proc is 689 // blocked, these should all pile up until we signal it. 690 691 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); 692 ResolveRequest req2(host_resolver.get(), "a", 81, &verifier); 693 ResolveRequest req3(host_resolver.get(), "a", 82, &verifier); 694 ResolveRequest req4(host_resolver.get(), "a", 83, &verifier); 695 696 // Once "a:80" completes, it will cancel "a:81" and "a:82". 697 verifier.SetRequestsToCancel(&req2, &req3); 698 699 // Ready, Set, GO!!! 700 resolver_proc->Signal(); 701 702 // |verifier| will send quit message once all the requests have finished. 703 MessageLoop::current()->Run(); 704 } 705 706 // Helper class used by HostResolverImplTest.DeleteWithinCallback. 707 class DeleteWithinCallbackVerifier : public ResolveRequest::Delegate { 708 public: 709 // |host_resolver| is the resolver that the the resolve requests were started 710 // with. 711 explicit DeleteWithinCallbackVerifier(HostResolver* host_resolver) 712 : host_resolver_(host_resolver) {} 713 714 virtual void OnCompleted(ResolveRequest* resolve) { 715 EXPECT_EQ("a", resolve->hostname()); 716 EXPECT_EQ(80, resolve->port()); 717 718 // Deletes the host resolver. 719 host_resolver_.reset(); 720 721 // Quit after returning from OnCompleted (to give it a chance at 722 // incorrectly running the cancelled tasks). 723 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 724 } 725 726 private: 727 scoped_ptr<HostResolver> host_resolver_; 728 DISALLOW_COPY_AND_ASSIGN(DeleteWithinCallbackVerifier); 729 }; 730 731 TEST_F(HostResolverImplTest, DeleteWithinCallback) { 732 // Use a capturing resolver_proc, since the verifier needs to know what calls 733 // reached Resolver(). Also, the capturing resolver_proc is initially 734 // blocked. 735 scoped_refptr<CapturingHostResolverProc> resolver_proc( 736 new CapturingHostResolverProc(NULL)); 737 738 // The class will receive callbacks for when each resolve completes. It 739 // checks that the right things happened. Note that the verifier holds the 740 // only reference to |host_resolver|, so it can delete it within callback. 741 HostResolver* host_resolver = 742 CreateHostResolverImpl(resolver_proc); 743 DeleteWithinCallbackVerifier verifier(host_resolver); 744 745 // Start 4 requests, duplicating hosts "a". Since the resolver_proc is 746 // blocked, these should all pile up until we signal it. 747 748 ResolveRequest req1(host_resolver, "a", 80, &verifier); 749 ResolveRequest req2(host_resolver, "a", 81, &verifier); 750 ResolveRequest req3(host_resolver, "a", 82, &verifier); 751 ResolveRequest req4(host_resolver, "a", 83, &verifier); 752 753 // Ready, Set, GO!!! 754 resolver_proc->Signal(); 755 756 // |verifier| will send quit message once all the requests have finished. 757 MessageLoop::current()->Run(); 758 } 759 760 // Helper class used by HostResolverImplTest.StartWithinCallback. 761 class StartWithinCallbackVerifier : public ResolveRequest::Delegate { 762 public: 763 StartWithinCallbackVerifier() : num_requests_(0) {} 764 765 virtual void OnCompleted(ResolveRequest* resolve) { 766 EXPECT_EQ("a", resolve->hostname()); 767 768 if (80 == resolve->port()) { 769 // On completing the first request, start another request for "a". 770 // Since caching is disabled, this will result in another async request. 771 final_request_.reset(new ResolveRequest( 772 resolve->resolver(), "a", 70, this)); 773 } 774 if (++num_requests_ == 5) { 775 // Test is done. 776 MessageLoop::current()->Quit(); 777 } 778 } 779 780 private: 781 int num_requests_; 782 scoped_ptr<ResolveRequest> final_request_; 783 DISALLOW_COPY_AND_ASSIGN(StartWithinCallbackVerifier); 784 }; 785 786 TEST_F(HostResolverImplTest, StartWithinCallback) { 787 // Use a capturing resolver_proc, since the verifier needs to know what calls 788 // reached Resolver(). Also, the capturing resolver_proc is initially 789 // blocked. 790 scoped_refptr<CapturingHostResolverProc> resolver_proc( 791 new CapturingHostResolverProc(NULL)); 792 793 // Turn off caching for this host resolver. 794 scoped_ptr<HostResolver> host_resolver( 795 new HostResolverImpl(resolver_proc, NULL, kMaxJobs, NULL)); 796 797 // The class will receive callbacks for when each resolve completes. It 798 // checks that the right things happened. 799 StartWithinCallbackVerifier verifier; 800 801 // Start 4 requests, duplicating hosts "a". Since the resolver_proc is 802 // blocked, these should all pile up until we signal it. 803 804 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); 805 ResolveRequest req2(host_resolver.get(), "a", 81, &verifier); 806 ResolveRequest req3(host_resolver.get(), "a", 82, &verifier); 807 ResolveRequest req4(host_resolver.get(), "a", 83, &verifier); 808 809 // Ready, Set, GO!!! 810 resolver_proc->Signal(); 811 812 // |verifier| will send quit message once all the requests have finished. 813 MessageLoop::current()->Run(); 814 } 815 816 // Helper class used by HostResolverImplTest.BypassCache. 817 class BypassCacheVerifier : public ResolveRequest::Delegate { 818 public: 819 BypassCacheVerifier() {} 820 821 virtual void OnCompleted(ResolveRequest* resolve) { 822 EXPECT_EQ("a", resolve->hostname()); 823 HostResolver* resolver = resolve->resolver(); 824 825 if (80 == resolve->port()) { 826 // On completing the first request, start another request for "a". 827 // Since caching is enabled, this should complete synchronously. 828 829 // Note that |junk_callback| shouldn't be used since we are going to 830 // complete synchronously. We can't specify NULL though since that would 831 // mean synchronous mode so we give it a value of 1. 832 CompletionCallback* junk_callback = 833 reinterpret_cast<CompletionCallback*> (1); 834 AddressList addrlist; 835 836 HostResolver::RequestInfo info(HostPortPair("a", 70)); 837 int error = resolver->Resolve(info, &addrlist, junk_callback, NULL, 838 BoundNetLog()); 839 EXPECT_EQ(OK, error); 840 841 // Ok good. Now make sure that if we ask to bypass the cache, it can no 842 // longer service the request synchronously. 843 info = HostResolver::RequestInfo(HostPortPair("a", 71)); 844 info.set_allow_cached_response(false); 845 final_request_.reset(new ResolveRequest(resolver, info, this)); 846 } else if (71 == resolve->port()) { 847 // Test is done. 848 MessageLoop::current()->Quit(); 849 } else { 850 FAIL() << "Unexpected port number"; 851 } 852 } 853 854 private: 855 scoped_ptr<ResolveRequest> final_request_; 856 DISALLOW_COPY_AND_ASSIGN(BypassCacheVerifier); 857 }; 858 859 TEST_F(HostResolverImplTest, BypassCache) { 860 scoped_ptr<HostResolver> host_resolver( 861 CreateHostResolverImpl(NULL)); 862 863 // The class will receive callbacks for when each resolve completes. It 864 // checks that the right things happened. 865 BypassCacheVerifier verifier; 866 867 // Start a request. 868 ResolveRequest req1(host_resolver.get(), "a", 80, &verifier); 869 870 // |verifier| will send quit message once all the requests have finished. 871 MessageLoop::current()->Run(); 872 } 873 874 bool operator==(const HostResolver::RequestInfo& a, 875 const HostResolver::RequestInfo& b) { 876 return a.hostname() == b.hostname() && 877 a.port() == b.port() && 878 a.allow_cached_response() == b.allow_cached_response() && 879 a.priority() == b.priority() && 880 a.is_speculative() == b.is_speculative() && 881 a.referrer() == b.referrer(); 882 } 883 884 // Observer that just makes note of how it was called. The test code can then 885 // inspect to make sure it was called with the right parameters. 886 class CapturingObserver : public HostResolver::Observer { 887 public: 888 // DnsResolutionObserver methods: 889 virtual void OnStartResolution(int id, 890 const HostResolver::RequestInfo& info) { 891 start_log.push_back(StartOrCancelEntry(id, info)); 892 } 893 894 virtual void OnFinishResolutionWithStatus( 895 int id, 896 bool was_resolved, 897 const HostResolver::RequestInfo& info) { 898 finish_log.push_back(FinishEntry(id, was_resolved, info)); 899 } 900 901 virtual void OnCancelResolution(int id, 902 const HostResolver::RequestInfo& info) { 903 cancel_log.push_back(StartOrCancelEntry(id, info)); 904 } 905 906 // Tuple (id, info). 907 struct StartOrCancelEntry { 908 StartOrCancelEntry(int id, const HostResolver::RequestInfo& info) 909 : id(id), info(info) {} 910 911 bool operator==(const StartOrCancelEntry& other) const { 912 return id == other.id && info == other.info; 913 } 914 915 int id; 916 HostResolver::RequestInfo info; 917 }; 918 919 // Tuple (id, was_resolved, info). 920 struct FinishEntry { 921 FinishEntry(int id, bool was_resolved, 922 const HostResolver::RequestInfo& info) 923 : id(id), was_resolved(was_resolved), info(info) {} 924 925 bool operator==(const FinishEntry& other) const { 926 return id == other.id && 927 was_resolved == other.was_resolved && 928 info == other.info; 929 } 930 931 int id; 932 bool was_resolved; 933 HostResolver::RequestInfo info; 934 }; 935 936 std::vector<StartOrCancelEntry> start_log; 937 std::vector<FinishEntry> finish_log; 938 std::vector<StartOrCancelEntry> cancel_log; 939 }; 940 941 // Test that registering, unregistering, and notifying of observers works. 942 // Does not test the cancellation notification since all resolves are 943 // synchronous. 944 TEST_F(HostResolverImplTest, Observers) { 945 scoped_ptr<HostResolver> host_resolver( 946 CreateHostResolverImpl(NULL)); 947 948 CapturingObserver observer; 949 950 host_resolver->AddObserver(&observer); 951 952 AddressList addrlist; 953 954 // Resolve "host1". 955 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); 956 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 957 int rv = host_resolver->Resolve(info1, &addrlist, NULL, NULL, log.bound()); 958 EXPECT_EQ(OK, rv); 959 960 CapturingNetLog::EntryList entries; 961 log.GetEntries(&entries); 962 963 EXPECT_EQ(2u, entries.size()); 964 EXPECT_TRUE(LogContainsBeginEvent( 965 entries, 0, NetLog::TYPE_HOST_RESOLVER_IMPL)); 966 EXPECT_TRUE(LogContainsEndEvent( 967 entries, 1, NetLog::TYPE_HOST_RESOLVER_IMPL)); 968 969 EXPECT_EQ(1U, observer.start_log.size()); 970 EXPECT_EQ(1U, observer.finish_log.size()); 971 EXPECT_EQ(0U, observer.cancel_log.size()); 972 EXPECT_TRUE(observer.start_log[0] == 973 CapturingObserver::StartOrCancelEntry(0, info1)); 974 EXPECT_TRUE(observer.finish_log[0] == 975 CapturingObserver::FinishEntry(0, true, info1)); 976 977 // Resolve "host1" again -- this time it will be served from cache, but it 978 // should still notify of completion. 979 TestCompletionCallback callback; 980 rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, BoundNetLog()); 981 ASSERT_EQ(OK, rv); // Should complete synchronously. 982 983 EXPECT_EQ(2U, observer.start_log.size()); 984 EXPECT_EQ(2U, observer.finish_log.size()); 985 EXPECT_EQ(0U, observer.cancel_log.size()); 986 EXPECT_TRUE(observer.start_log[1] == 987 CapturingObserver::StartOrCancelEntry(1, info1)); 988 EXPECT_TRUE(observer.finish_log[1] == 989 CapturingObserver::FinishEntry(1, true, info1)); 990 991 // Resolve "host2", setting referrer to "http://foobar.com" 992 HostResolver::RequestInfo info2(HostPortPair("host2", 70)); 993 info2.set_referrer(GURL("http://foobar.com")); 994 rv = host_resolver->Resolve(info2, &addrlist, NULL, NULL, BoundNetLog()); 995 EXPECT_EQ(OK, rv); 996 997 EXPECT_EQ(3U, observer.start_log.size()); 998 EXPECT_EQ(3U, observer.finish_log.size()); 999 EXPECT_EQ(0U, observer.cancel_log.size()); 1000 EXPECT_TRUE(observer.start_log[2] == 1001 CapturingObserver::StartOrCancelEntry(2, info2)); 1002 EXPECT_TRUE(observer.finish_log[2] == 1003 CapturingObserver::FinishEntry(2, true, info2)); 1004 1005 // Unregister the observer. 1006 host_resolver->RemoveObserver(&observer); 1007 1008 // Resolve "host3" 1009 HostResolver::RequestInfo info3(HostPortPair("host3", 70)); 1010 host_resolver->Resolve(info3, &addrlist, NULL, NULL, BoundNetLog()); 1011 1012 // No effect this time, since observer was removed. 1013 EXPECT_EQ(3U, observer.start_log.size()); 1014 EXPECT_EQ(3U, observer.finish_log.size()); 1015 EXPECT_EQ(0U, observer.cancel_log.size()); 1016 } 1017 1018 // Tests that observers are sent OnCancelResolution() whenever a request is 1019 // cancelled. There are two ways to cancel a request: 1020 // (1) Delete the HostResolver while job is outstanding. 1021 // (2) Call HostResolver::CancelRequest() while a request is outstanding. 1022 TEST_F(HostResolverImplTest, CancellationObserver) { 1023 CapturingObserver observer; 1024 { 1025 // Create a host resolver and attach an observer. 1026 scoped_ptr<HostResolver> host_resolver( 1027 CreateHostResolverImpl(NULL)); 1028 host_resolver->AddObserver(&observer); 1029 1030 TestCompletionCallback callback; 1031 1032 EXPECT_EQ(0U, observer.start_log.size()); 1033 EXPECT_EQ(0U, observer.finish_log.size()); 1034 EXPECT_EQ(0U, observer.cancel_log.size()); 1035 1036 // Start an async resolve for (host1:70). 1037 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); 1038 HostResolver::RequestHandle req = NULL; 1039 AddressList addrlist; 1040 int rv = host_resolver->Resolve(info1, &addrlist, &callback, &req, 1041 BoundNetLog()); 1042 EXPECT_EQ(ERR_IO_PENDING, rv); 1043 EXPECT_TRUE(NULL != req); 1044 1045 EXPECT_EQ(1U, observer.start_log.size()); 1046 EXPECT_EQ(0U, observer.finish_log.size()); 1047 EXPECT_EQ(0U, observer.cancel_log.size()); 1048 1049 EXPECT_TRUE(observer.start_log[0] == 1050 CapturingObserver::StartOrCancelEntry(0, info1)); 1051 1052 // Cancel the request. 1053 host_resolver->CancelRequest(req); 1054 1055 EXPECT_EQ(1U, observer.start_log.size()); 1056 EXPECT_EQ(0U, observer.finish_log.size()); 1057 EXPECT_EQ(1U, observer.cancel_log.size()); 1058 1059 EXPECT_TRUE(observer.cancel_log[0] == 1060 CapturingObserver::StartOrCancelEntry(0, info1)); 1061 1062 // Start an async request for (host2:60) 1063 HostResolver::RequestInfo info2(HostPortPair("host2", 60)); 1064 rv = host_resolver->Resolve(info2, &addrlist, &callback, NULL, 1065 BoundNetLog()); 1066 EXPECT_EQ(ERR_IO_PENDING, rv); 1067 EXPECT_TRUE(NULL != req); 1068 1069 EXPECT_EQ(2U, observer.start_log.size()); 1070 EXPECT_EQ(0U, observer.finish_log.size()); 1071 EXPECT_EQ(1U, observer.cancel_log.size()); 1072 1073 EXPECT_TRUE(observer.start_log[1] == 1074 CapturingObserver::StartOrCancelEntry(1, info2)); 1075 1076 // Upon exiting this scope, HostResolver is destroyed, so all requests are 1077 // implicitly cancelled. 1078 } 1079 1080 // Check that destroying the HostResolver sent a notification for 1081 // cancellation of host2:60 request. 1082 1083 EXPECT_EQ(2U, observer.start_log.size()); 1084 EXPECT_EQ(0U, observer.finish_log.size()); 1085 EXPECT_EQ(2U, observer.cancel_log.size()); 1086 1087 HostResolver::RequestInfo info(HostPortPair("host2", 60)); 1088 EXPECT_TRUE(observer.cancel_log[1] == 1089 CapturingObserver::StartOrCancelEntry(1, info)); 1090 } 1091 1092 // Test that IP address changes flush the cache. 1093 TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { 1094 scoped_ptr<HostResolver> host_resolver( 1095 new HostResolverImpl(NULL, CreateDefaultCache(), kMaxJobs, NULL)); 1096 1097 AddressList addrlist; 1098 1099 // Resolve "host1". 1100 HostResolver::RequestInfo info1(HostPortPair("host1", 70)); 1101 TestCompletionCallback callback; 1102 int rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, 1103 BoundNetLog()); 1104 EXPECT_EQ(ERR_IO_PENDING, rv); 1105 EXPECT_EQ(OK, callback.WaitForResult()); 1106 1107 // Resolve "host1" again -- this time it will be served from cache, but it 1108 // should still notify of completion. 1109 rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, BoundNetLog()); 1110 ASSERT_EQ(OK, rv); // Should complete synchronously. 1111 1112 // Flush cache by triggering an IP address change. 1113 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1114 MessageLoop::current()->RunAllPending(); // Notification happens async. 1115 1116 // Resolve "host1" again -- this time it won't be served from cache, so it 1117 // will complete asynchronously. 1118 rv = host_resolver->Resolve(info1, &addrlist, &callback, NULL, BoundNetLog()); 1119 ASSERT_EQ(ERR_IO_PENDING, rv); // Should complete asynchronously. 1120 EXPECT_EQ(OK, callback.WaitForResult()); 1121 } 1122 1123 // Test that IP address changes send ERR_ABORTED to pending requests. 1124 TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { 1125 scoped_refptr<WaitingHostResolverProc> resolver_proc( 1126 new WaitingHostResolverProc(NULL)); 1127 HostCache* cache = CreateDefaultCache(); 1128 scoped_ptr<HostResolver> host_resolver( 1129 new HostResolverImpl(resolver_proc, cache, kMaxJobs, NULL)); 1130 1131 // Resolve "host1". 1132 HostResolver::RequestInfo info(HostPortPair("host1", 70)); 1133 TestCompletionCallback callback; 1134 AddressList addrlist; 1135 int rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, 1136 BoundNetLog()); 1137 EXPECT_EQ(ERR_IO_PENDING, rv); 1138 1139 // Triggering an IP address change. 1140 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1141 MessageLoop::current()->RunAllPending(); // Notification happens async. 1142 resolver_proc->Signal(); 1143 1144 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); 1145 EXPECT_EQ(0u, cache->size()); 1146 } 1147 1148 // Obey pool constraints after IP address has changed. 1149 TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { 1150 scoped_refptr<WaitingHostResolverProc> resolver_proc( 1151 new WaitingHostResolverProc(NULL)); 1152 scoped_ptr<MockHostResolver> host_resolver(new MockHostResolver()); 1153 host_resolver->Reset(resolver_proc); 1154 1155 const size_t kMaxOutstandingJobs = 1u; 1156 const size_t kMaxPendingRequests = 1000000u; // not relevant. 1157 host_resolver->SetPoolConstraints(HostResolverImpl::POOL_NORMAL, 1158 kMaxOutstandingJobs, 1159 kMaxPendingRequests); 1160 1161 // Resolve "host1". 1162 HostResolver::RequestInfo info(HostPortPair("host1", 70)); 1163 TestCompletionCallback callback; 1164 AddressList addrlist; 1165 int rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, 1166 BoundNetLog()); 1167 EXPECT_EQ(ERR_IO_PENDING, rv); 1168 1169 // Triggering an IP address change. 1170 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1171 MessageLoop::current()->RunAllPending(); // Notification happens async. 1172 resolver_proc->Signal(); 1173 1174 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); 1175 1176 // Don't bother with WaitingHostResolverProc anymore. 1177 host_resolver->Reset(NULL); 1178 1179 rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, 1180 BoundNetLog()); 1181 EXPECT_EQ(ERR_IO_PENDING, rv); 1182 EXPECT_EQ(OK, callback.WaitForResult()); 1183 } 1184 1185 class ResolveWithinCallback : public CallbackRunner< Tuple1<int> > { 1186 public: 1187 ResolveWithinCallback( 1188 MockHostResolver* host_resolver, 1189 const HostResolver::RequestInfo& info) 1190 : host_resolver_(host_resolver), 1191 info_(info) { 1192 DCHECK(host_resolver); 1193 } 1194 1195 virtual void RunWithParams(const Tuple1<int>& params) { 1196 // Ditch the WaitingHostResolverProc so that the subsequent request 1197 // succeeds. 1198 host_resolver_->Reset(NULL); 1199 callback_.RunWithParams(params); 1200 EXPECT_EQ(ERR_IO_PENDING, 1201 host_resolver_->Resolve(info_, &addrlist_, &nested_callback_, 1202 NULL, BoundNetLog())); 1203 } 1204 1205 int WaitForResult() { 1206 return callback_.WaitForResult(); 1207 } 1208 1209 int WaitForNestedResult() { 1210 return nested_callback_.WaitForResult(); 1211 } 1212 1213 private: 1214 MockHostResolver* const host_resolver_; 1215 const HostResolver::RequestInfo info_; 1216 AddressList addrlist_; 1217 TestCompletionCallback callback_; 1218 TestCompletionCallback nested_callback_; 1219 }; 1220 1221 TEST_F(HostResolverImplTest, OnlyAbortExistingRequestsOnIPAddressChange) { 1222 scoped_refptr<WaitingHostResolverProc> resolver_proc( 1223 new WaitingHostResolverProc(NULL)); 1224 scoped_ptr<MockHostResolver> host_resolver(new MockHostResolver()); 1225 host_resolver->Reset(resolver_proc); 1226 1227 // Resolve "host1". 1228 HostResolver::RequestInfo info(HostPortPair("host1", 70)); 1229 ResolveWithinCallback callback(host_resolver.get(), info); 1230 AddressList addrlist; 1231 int rv = host_resolver->Resolve(info, &addrlist, &callback, NULL, 1232 BoundNetLog()); 1233 EXPECT_EQ(ERR_IO_PENDING, rv); 1234 1235 // Triggering an IP address change. 1236 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 1237 MessageLoop::current()->RunAllPending(); // Notification happens async. 1238 1239 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult()); 1240 resolver_proc->Signal(); 1241 EXPECT_EQ(OK, callback.WaitForNestedResult()); 1242 } 1243 1244 // Tests that when the maximum threads is set to 1, requests are dequeued 1245 // in order of priority. 1246 TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) { 1247 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1248 new CapturingHostResolverProc(NULL)); 1249 1250 // This HostResolverImpl will only allow 1 outstanding resolve at a time. 1251 size_t kMaxJobs = 1u; 1252 scoped_ptr<HostResolver> host_resolver( 1253 new HostResolverImpl(resolver_proc, CreateDefaultCache(), kMaxJobs, 1254 NULL)); 1255 1256 CapturingObserver observer; 1257 host_resolver->AddObserver(&observer); 1258 1259 // Note that at this point the CapturingHostResolverProc is blocked, so any 1260 // requests we make will not complete. 1261 1262 HostResolver::RequestInfo req[] = { 1263 CreateResolverRequest("req0", LOW), 1264 CreateResolverRequest("req1", MEDIUM), 1265 CreateResolverRequest("req2", MEDIUM), 1266 CreateResolverRequest("req3", LOW), 1267 CreateResolverRequest("req4", HIGHEST), 1268 CreateResolverRequest("req5", LOW), 1269 CreateResolverRequest("req6", LOW), 1270 CreateResolverRequest("req5", HIGHEST), 1271 }; 1272 1273 TestCompletionCallback callback[arraysize(req)]; 1274 AddressList addrlist[arraysize(req)]; 1275 1276 // Start all of the requests. 1277 for (size_t i = 0; i < arraysize(req); ++i) { 1278 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1279 &callback[i], NULL, BoundNetLog()); 1280 EXPECT_EQ(ERR_IO_PENDING, rv); 1281 } 1282 1283 // Unblock the resolver thread so the requests can run. 1284 resolver_proc->Signal(); 1285 1286 // Wait for all the requests to complete succesfully. 1287 for (size_t i = 0; i < arraysize(req); ++i) { 1288 EXPECT_EQ(OK, callback[i].WaitForResult()) << "i=" << i; 1289 } 1290 1291 host_resolver->RemoveObserver(&observer); 1292 1293 // Since we have restricted to a single concurrent thread in the jobpool, 1294 // the requests should complete in order of priority (with the exception 1295 // of the first request, which gets started right away, since there is 1296 // nothing outstanding). 1297 CapturingHostResolverProc::CaptureList capture_list = 1298 resolver_proc->GetCaptureList(); 1299 ASSERT_EQ(7u, capture_list.size()); 1300 1301 EXPECT_EQ("req0", capture_list[0].hostname); 1302 EXPECT_EQ("req4", capture_list[1].hostname); 1303 EXPECT_EQ("req5", capture_list[2].hostname); 1304 EXPECT_EQ("req1", capture_list[3].hostname); 1305 EXPECT_EQ("req2", capture_list[4].hostname); 1306 EXPECT_EQ("req3", capture_list[5].hostname); 1307 EXPECT_EQ("req6", capture_list[6].hostname); 1308 1309 // Also check using the observer's trace. 1310 EXPECT_EQ(8U, observer.start_log.size()); 1311 EXPECT_EQ(8U, observer.finish_log.size()); 1312 EXPECT_EQ(0U, observer.cancel_log.size()); 1313 1314 EXPECT_EQ("req0", observer.finish_log[0].info.hostname()); 1315 EXPECT_EQ("req4", observer.finish_log[1].info.hostname()); 1316 1317 // There were two requests for "req5". The highest priority 1318 // one should have been dispatched earlier. 1319 EXPECT_EQ("req5", observer.finish_log[2].info.hostname()); 1320 EXPECT_EQ("req5", observer.finish_log[3].info.hostname()); 1321 EXPECT_EQ(HIGHEST, observer.finish_log[2].info.priority()); 1322 EXPECT_EQ(LOW, observer.finish_log[3].info.priority()); 1323 1324 EXPECT_EQ("req1", observer.finish_log[4].info.hostname()); 1325 EXPECT_EQ("req2", observer.finish_log[5].info.hostname()); 1326 EXPECT_EQ("req3", observer.finish_log[6].info.hostname()); 1327 EXPECT_EQ("req6", observer.finish_log[7].info.hostname()); 1328 } 1329 1330 // Try cancelling a request which has not been attached to a job yet. 1331 TEST_F(HostResolverImplTest, CancelPendingRequest) { 1332 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1333 new CapturingHostResolverProc(NULL)); 1334 1335 // This HostResolverImpl will only allow 1 outstanding resolve at a time. 1336 const size_t kMaxJobs = 1u; 1337 scoped_ptr<HostResolver> host_resolver( 1338 new HostResolverImpl(resolver_proc, CreateDefaultCache(), kMaxJobs, 1339 NULL)); 1340 1341 // Note that at this point the CapturingHostResolverProc is blocked, so any 1342 // requests we make will not complete. 1343 1344 HostResolver::RequestInfo req[] = { 1345 CreateResolverRequest("req0", LOWEST), 1346 CreateResolverRequest("req1", HIGHEST), // Will cancel. 1347 CreateResolverRequest("req2", MEDIUM), 1348 CreateResolverRequest("req3", LOW), 1349 CreateResolverRequest("req4", HIGHEST), // Will cancel. 1350 CreateResolverRequest("req5", LOWEST), // Will cancel. 1351 CreateResolverRequest("req6", MEDIUM), 1352 }; 1353 1354 TestCompletionCallback callback[arraysize(req)]; 1355 AddressList addrlist[arraysize(req)]; 1356 HostResolver::RequestHandle handle[arraysize(req)]; 1357 1358 // Start all of the requests. 1359 for (size_t i = 0; i < arraysize(req); ++i) { 1360 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1361 &callback[i], &handle[i], BoundNetLog()); 1362 EXPECT_EQ(ERR_IO_PENDING, rv); 1363 } 1364 1365 // Cancel some requests 1366 host_resolver->CancelRequest(handle[1]); 1367 host_resolver->CancelRequest(handle[4]); 1368 host_resolver->CancelRequest(handle[5]); 1369 handle[1] = handle[4] = handle[5] = NULL; 1370 1371 // Unblock the resolver thread so the requests can run. 1372 resolver_proc->Signal(); 1373 1374 // Wait for all the requests to complete succesfully. 1375 for (size_t i = 0; i < arraysize(req); ++i) { 1376 if (!handle[i]) 1377 continue; // Don't wait for the requests we cancelled. 1378 EXPECT_EQ(OK, callback[i].WaitForResult()); 1379 } 1380 1381 // Verify that they called out the the resolver proc (which runs on the 1382 // resolver thread) in the expected order. 1383 CapturingHostResolverProc::CaptureList capture_list = 1384 resolver_proc->GetCaptureList(); 1385 ASSERT_EQ(4u, capture_list.size()); 1386 1387 EXPECT_EQ("req0", capture_list[0].hostname); 1388 EXPECT_EQ("req2", capture_list[1].hostname); 1389 EXPECT_EQ("req6", capture_list[2].hostname); 1390 EXPECT_EQ("req3", capture_list[3].hostname); 1391 } 1392 1393 // Test that when too many requests are enqueued, old ones start to be aborted. 1394 TEST_F(HostResolverImplTest, QueueOverflow) { 1395 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1396 new CapturingHostResolverProc(NULL)); 1397 1398 // This HostResolverImpl will only allow 1 outstanding resolve at a time. 1399 const size_t kMaxOutstandingJobs = 1u; 1400 scoped_ptr<HostResolverImpl> host_resolver(new HostResolverImpl( 1401 resolver_proc, CreateDefaultCache(), kMaxOutstandingJobs, NULL)); 1402 1403 // Only allow up to 3 requests to be enqueued at a time. 1404 const size_t kMaxPendingRequests = 3u; 1405 host_resolver->SetPoolConstraints(HostResolverImpl::POOL_NORMAL, 1406 kMaxOutstandingJobs, 1407 kMaxPendingRequests); 1408 1409 // Note that at this point the CapturingHostResolverProc is blocked, so any 1410 // requests we make will not complete. 1411 1412 HostResolver::RequestInfo req[] = { 1413 CreateResolverRequest("req0", LOWEST), 1414 CreateResolverRequest("req1", HIGHEST), 1415 CreateResolverRequest("req2", MEDIUM), 1416 CreateResolverRequest("req3", MEDIUM), 1417 1418 // At this point, there are 3 enqueued requests. 1419 // Insertion of subsequent requests will cause evictions 1420 // based on priority. 1421 1422 CreateResolverRequest("req4", LOW), // Evicts itself! 1423 CreateResolverRequest("req5", MEDIUM), // Evicts req3 1424 CreateResolverRequest("req6", HIGHEST), // Evicts req5. 1425 CreateResolverRequest("req7", MEDIUM), // Evicts req2. 1426 }; 1427 1428 TestCompletionCallback callback[arraysize(req)]; 1429 AddressList addrlist[arraysize(req)]; 1430 HostResolver::RequestHandle handle[arraysize(req)]; 1431 1432 // Start all of the requests. 1433 for (size_t i = 0; i < arraysize(req); ++i) { 1434 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1435 &callback[i], &handle[i], BoundNetLog()); 1436 if (i == 4u) 1437 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, rv); 1438 else 1439 EXPECT_EQ(ERR_IO_PENDING, rv) << i; 1440 } 1441 1442 // Unblock the resolver thread so the requests can run. 1443 resolver_proc->Signal(); 1444 1445 // Requests 3, 5, 2 will have been evicted due to queue overflow. 1446 size_t reqs_expected_to_fail[] = { 2, 3, 5 }; 1447 for (size_t i = 0; i < arraysize(reqs_expected_to_fail); ++i) { 1448 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, 1449 callback[reqs_expected_to_fail[i]].WaitForResult()); 1450 } 1451 1452 // The rest should succeed. 1453 size_t reqs_expected_to_succeed[] = { 0, 1, 6, 7 }; 1454 for (size_t i = 0; i < arraysize(reqs_expected_to_succeed); ++i) { 1455 EXPECT_EQ(OK, callback[reqs_expected_to_succeed[i]].WaitForResult()); 1456 } 1457 1458 // Verify that they called out the the resolver proc (which runs on the 1459 // resolver thread) in the expected order. 1460 CapturingHostResolverProc::CaptureList capture_list = 1461 resolver_proc->GetCaptureList(); 1462 ASSERT_EQ(4u, capture_list.size()); 1463 1464 EXPECT_EQ("req0", capture_list[0].hostname); 1465 EXPECT_EQ("req1", capture_list[1].hostname); 1466 EXPECT_EQ("req6", capture_list[2].hostname); 1467 EXPECT_EQ("req7", capture_list[3].hostname); 1468 } 1469 1470 // Tests that after changing the default AddressFamily to IPV4, requests 1471 // with UNSPECIFIED address family map to IPV4. 1472 TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv4) { 1473 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1474 new CapturingHostResolverProc(new EchoingHostResolverProc)); 1475 1476 // This HostResolverImpl will only allow 1 outstanding resolve at a time. 1477 const size_t kMaxOutstandingJobs = 1u; 1478 scoped_ptr<HostResolverImpl> host_resolver(new HostResolverImpl( 1479 resolver_proc, CreateDefaultCache(), kMaxOutstandingJobs, NULL)); 1480 1481 host_resolver->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4); 1482 1483 // Note that at this point the CapturingHostResolverProc is blocked, so any 1484 // requests we make will not complete. 1485 1486 HostResolver::RequestInfo req[] = { 1487 CreateResolverRequestForAddressFamily("h1", MEDIUM, 1488 ADDRESS_FAMILY_UNSPECIFIED), 1489 CreateResolverRequestForAddressFamily("h1", MEDIUM, ADDRESS_FAMILY_IPV4), 1490 CreateResolverRequestForAddressFamily("h1", MEDIUM, ADDRESS_FAMILY_IPV6), 1491 }; 1492 1493 TestCompletionCallback callback[arraysize(req)]; 1494 AddressList addrlist[arraysize(req)]; 1495 HostResolver::RequestHandle handle[arraysize(req)]; 1496 1497 // Start all of the requests. 1498 for (size_t i = 0; i < arraysize(req); ++i) { 1499 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1500 &callback[i], &handle[i], BoundNetLog()); 1501 EXPECT_EQ(ERR_IO_PENDING, rv) << i; 1502 } 1503 1504 // Unblock the resolver thread so the requests can run. 1505 resolver_proc->Signal(); 1506 1507 // Wait for all the requests to complete. 1508 for (size_t i = 0u; i < arraysize(req); ++i) { 1509 EXPECT_EQ(OK, callback[i].WaitForResult()); 1510 } 1511 1512 // Since the requests all had the same priority and we limited the thread 1513 // count to 1, they should have completed in the same order as they were 1514 // requested. Moreover, request0 and request1 will have been serviced by 1515 // the same job. 1516 1517 CapturingHostResolverProc::CaptureList capture_list = 1518 resolver_proc->GetCaptureList(); 1519 ASSERT_EQ(2u, capture_list.size()); 1520 1521 EXPECT_EQ("h1", capture_list[0].hostname); 1522 EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[0].address_family); 1523 1524 EXPECT_EQ("h1", capture_list[1].hostname); 1525 EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[1].address_family); 1526 1527 // Now check that the correct resolved IP addresses were returned. 1528 // Addresses take the form: 192.x.y.z 1529 // x = length of hostname 1530 // y = ASCII value of hostname[0] 1531 // z = value of address family 1532 EXPECT_EQ("192.2.104.1", NetAddressToString(addrlist[0].head())); 1533 EXPECT_EQ("192.2.104.1", NetAddressToString(addrlist[1].head())); 1534 EXPECT_EQ("192.2.104.2", NetAddressToString(addrlist[2].head())); 1535 } 1536 1537 // This is the exact same test as SetDefaultAddressFamily_IPv4, except the order 1538 // of requests 0 and 1 is flipped, and the default is set to IPv6 in place of 1539 // IPv4. 1540 TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv6) { 1541 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1542 new CapturingHostResolverProc(new EchoingHostResolverProc)); 1543 1544 // This HostResolverImpl will only allow 1 outstanding resolve at a time. 1545 const size_t kMaxOutstandingJobs = 1u; 1546 scoped_ptr<HostResolverImpl> host_resolver(new HostResolverImpl( 1547 resolver_proc, CreateDefaultCache(), kMaxOutstandingJobs, NULL)); 1548 1549 host_resolver->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV6); 1550 1551 // Note that at this point the CapturingHostResolverProc is blocked, so any 1552 // requests we make will not complete. 1553 1554 HostResolver::RequestInfo req[] = { 1555 CreateResolverRequestForAddressFamily("h1", MEDIUM, ADDRESS_FAMILY_IPV6), 1556 CreateResolverRequestForAddressFamily("h1", MEDIUM, 1557 ADDRESS_FAMILY_UNSPECIFIED), 1558 CreateResolverRequestForAddressFamily("h1", MEDIUM, ADDRESS_FAMILY_IPV4), 1559 }; 1560 1561 TestCompletionCallback callback[arraysize(req)]; 1562 AddressList addrlist[arraysize(req)]; 1563 HostResolver::RequestHandle handle[arraysize(req)]; 1564 1565 // Start all of the requests. 1566 for (size_t i = 0; i < arraysize(req); ++i) { 1567 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1568 &callback[i], &handle[i], BoundNetLog()); 1569 EXPECT_EQ(ERR_IO_PENDING, rv) << i; 1570 } 1571 1572 // Unblock the resolver thread so the requests can run. 1573 resolver_proc->Signal(); 1574 1575 // Wait for all the requests to complete. 1576 for (size_t i = 0u; i < arraysize(req); ++i) { 1577 EXPECT_EQ(OK, callback[i].WaitForResult()); 1578 } 1579 1580 // Since the requests all had the same priority and we limited the thread 1581 // count to 1, they should have completed in the same order as they were 1582 // requested. Moreover, request0 and request1 will have been serviced by 1583 // the same job. 1584 1585 CapturingHostResolverProc::CaptureList capture_list = 1586 resolver_proc->GetCaptureList(); 1587 ASSERT_EQ(2u, capture_list.size()); 1588 1589 EXPECT_EQ("h1", capture_list[0].hostname); 1590 EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[0].address_family); 1591 1592 EXPECT_EQ("h1", capture_list[1].hostname); 1593 EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[1].address_family); 1594 1595 // Now check that the correct resolved IP addresses were returned. 1596 // Addresses take the form: 192.x.y.z 1597 // x = length of hostname 1598 // y = ASCII value of hostname[0] 1599 // z = value of address family 1600 EXPECT_EQ("192.2.104.2", NetAddressToString(addrlist[0].head())); 1601 EXPECT_EQ("192.2.104.2", NetAddressToString(addrlist[1].head())); 1602 EXPECT_EQ("192.2.104.1", NetAddressToString(addrlist[2].head())); 1603 } 1604 1605 // This tests that the default address family is respected for synchronous 1606 // resolutions. 1607 TEST_F(HostResolverImplTest, SetDefaultAddressFamily_Synchronous) { 1608 scoped_refptr<CapturingHostResolverProc> resolver_proc( 1609 new CapturingHostResolverProc(new EchoingHostResolverProc)); 1610 1611 const size_t kMaxOutstandingJobs = 10u; 1612 scoped_ptr<HostResolverImpl> host_resolver(new HostResolverImpl( 1613 resolver_proc, CreateDefaultCache(), kMaxOutstandingJobs, NULL)); 1614 1615 host_resolver->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4); 1616 1617 // Unblock the resolver thread so the requests can run. 1618 resolver_proc->Signal(); 1619 1620 HostResolver::RequestInfo req[] = { 1621 CreateResolverRequestForAddressFamily("b", MEDIUM, 1622 ADDRESS_FAMILY_UNSPECIFIED), 1623 CreateResolverRequestForAddressFamily("b", MEDIUM, ADDRESS_FAMILY_IPV6), 1624 CreateResolverRequestForAddressFamily("b", MEDIUM, 1625 ADDRESS_FAMILY_UNSPECIFIED), 1626 CreateResolverRequestForAddressFamily("b", MEDIUM, ADDRESS_FAMILY_IPV4), 1627 }; 1628 AddressList addrlist[arraysize(req)]; 1629 1630 // Start and run all of the requests synchronously. 1631 for (size_t i = 0; i < arraysize(req); ++i) { 1632 int rv = host_resolver->Resolve(req[i], &addrlist[i], 1633 NULL, NULL, BoundNetLog()); 1634 EXPECT_EQ(OK, rv) << i; 1635 } 1636 1637 // We should have sent 2 requests to the resolver -- 1638 // one for (b, IPv4), and one for (b, IPv6). 1639 CapturingHostResolverProc::CaptureList capture_list = 1640 resolver_proc->GetCaptureList(); 1641 ASSERT_EQ(2u, capture_list.size()); 1642 1643 EXPECT_EQ("b", capture_list[0].hostname); 1644 EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[0].address_family); 1645 1646 EXPECT_EQ("b", capture_list[1].hostname); 1647 EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[1].address_family); 1648 1649 // Now check that the correct resolved IP addresses were returned. 1650 // Addresses take the form: 192.x.y.z 1651 // x = length of hostname 1652 // y = ASCII value of hostname[0] 1653 // z = value of address family 1654 EXPECT_EQ("192.1.98.1", NetAddressToString(addrlist[0].head())); 1655 EXPECT_EQ("192.1.98.2", NetAddressToString(addrlist[1].head())); 1656 EXPECT_EQ("192.1.98.1", NetAddressToString(addrlist[2].head())); 1657 EXPECT_EQ("192.1.98.1", NetAddressToString(addrlist[3].head())); 1658 } 1659 1660 TEST_F(HostResolverImplTest, DisallowNonCachedResponses) { 1661 AddressList addrlist; 1662 const int kPortnum = 80; 1663 1664 scoped_refptr<RuleBasedHostResolverProc> resolver_proc( 1665 new RuleBasedHostResolverProc(NULL)); 1666 resolver_proc->AddRule("just.testing", "192.168.1.42"); 1667 1668 scoped_ptr<HostResolver> host_resolver( 1669 CreateHostResolverImpl(resolver_proc)); 1670 1671 // First hit will miss the cache. 1672 HostResolver::RequestInfo info(HostPortPair("just.testing", kPortnum)); 1673 info.set_only_use_cached_response(true); 1674 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 1675 int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); 1676 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); 1677 1678 // This time, we fetch normally. 1679 info.set_only_use_cached_response(false); 1680 err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); 1681 EXPECT_EQ(OK, err); 1682 1683 // Now we should be able to fetch from the cache. 1684 info.set_only_use_cached_response(true); 1685 err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); 1686 EXPECT_EQ(OK, err); 1687 1688 const struct addrinfo* ainfo = addrlist.head(); 1689 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 1690 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 1691 1692 const struct sockaddr* sa = ainfo->ai_addr; 1693 const struct sockaddr_in* sa_in = reinterpret_cast<const sockaddr_in*>(sa); 1694 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 1695 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); 1696 } 1697 // TODO(cbentzel): Test a mix of requests with different HostResolverFlags. 1698 1699 } // namespace 1700 1701 } // namespace net 1702