| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 <algorithm> | |
| 8 #include <string> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/bind_helpers.h" | |
| 12 #include "base/memory/ref_counted.h" | |
| 13 #include "base/memory/scoped_vector.h" | |
| 14 #include "base/message_loop.h" | |
| 15 #include "base/string_util.h" | |
| 16 #include "base/stringprintf.h" | |
| 17 #include "base/synchronization/condition_variable.h" | |
| 18 #include "base/synchronization/lock.h" | |
| 19 #include "base/test/test_timeouts.h" | |
| 20 #include "base/time.h" | |
| 21 #include "net/base/address_list.h" | |
| 22 #include "net/base/host_cache.h" | |
| 23 #include "net/base/mock_host_resolver.h" | |
| 24 #include "net/base/net_errors.h" | |
| 25 #include "net/base/net_util.h" | |
| 26 #include "net/dns/dns_client.h" | |
| 27 #include "net/dns/dns_test_util.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 | |
| 30 namespace net { | |
| 31 | |
| 32 namespace { | |
| 33 | |
| 34 const size_t kMaxJobs = 10u; | |
| 35 const size_t kMaxRetryAttempts = 4u; | |
| 36 | |
| 37 PrioritizedDispatcher::Limits DefaultLimits() { | |
| 38 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, kMaxJobs); | |
| 39 return limits; | |
| 40 } | |
| 41 | |
| 42 HostResolverImpl::ProcTaskParams DefaultParams( | |
| 43 HostResolverProc* resolver_proc) { | |
| 44 return HostResolverImpl::ProcTaskParams(resolver_proc, kMaxRetryAttempts); | |
| 45 } | |
| 46 | |
| 47 // A HostResolverProc that pushes each host mapped into a list and allows | |
| 48 // waiting for a specific number of requests. Unlike RuleBasedHostResolverProc | |
| 49 // it never calls SystemHostResolverProc. By default resolves all hostnames to | |
| 50 // "127.0.0.1". After AddRule(), it resolves only names explicitly specified. | |
| 51 class MockHostResolverProc : public HostResolverProc { | |
| 52 public: | |
| 53 struct ResolveKey { | |
| 54 ResolveKey(const std::string& hostname, AddressFamily address_family) | |
| 55 : hostname(hostname), address_family(address_family) {} | |
| 56 bool operator<(const ResolveKey& other) const { | |
| 57 return address_family < other.address_family || | |
| 58 (address_family == other.address_family && hostname < other.hostname); | |
| 59 } | |
| 60 std::string hostname; | |
| 61 AddressFamily address_family; | |
| 62 }; | |
| 63 | |
| 64 typedef std::vector<ResolveKey> CaptureList; | |
| 65 | |
| 66 MockHostResolverProc() | |
| 67 : HostResolverProc(NULL), | |
| 68 num_requests_waiting_(0), | |
| 69 num_slots_available_(0), | |
| 70 requests_waiting_(&lock_), | |
| 71 slots_available_(&lock_) { | |
| 72 } | |
| 73 | |
| 74 // Waits until |count| calls to |Resolve| are blocked. Returns false when | |
| 75 // timed out. | |
| 76 bool WaitFor(unsigned count) { | |
| 77 base::AutoLock lock(lock_); | |
| 78 base::Time start_time = base::Time::Now(); | |
| 79 while (num_requests_waiting_ < count) { | |
| 80 requests_waiting_.TimedWait(TestTimeouts::action_timeout()); | |
| 81 if (base::Time::Now() > start_time + TestTimeouts::action_timeout()) | |
| 82 return false; | |
| 83 } | |
| 84 return true; | |
| 85 } | |
| 86 | |
| 87 // Signals |count| waiting calls to |Resolve|. First come first served. | |
| 88 void SignalMultiple(unsigned count) { | |
| 89 base::AutoLock lock(lock_); | |
| 90 num_slots_available_ += count; | |
| 91 slots_available_.Broadcast(); | |
| 92 } | |
| 93 | |
| 94 // Signals all waiting calls to |Resolve|. Beware of races. | |
| 95 void SignalAll() { | |
| 96 base::AutoLock lock(lock_); | |
| 97 num_slots_available_ = num_requests_waiting_; | |
| 98 slots_available_.Broadcast(); | |
| 99 } | |
| 100 | |
| 101 void AddRule(const std::string& hostname, AddressFamily family, | |
| 102 const AddressList& result) { | |
| 103 base::AutoLock lock(lock_); | |
| 104 rules_[ResolveKey(hostname, family)] = result; | |
| 105 } | |
| 106 | |
| 107 void AddRule(const std::string& hostname, AddressFamily family, | |
| 108 const std::string& ip_list) { | |
| 109 AddressList result; | |
| 110 int rv = ParseAddressList(ip_list, "", &result); | |
| 111 DCHECK_EQ(OK, rv); | |
| 112 AddRule(hostname, family, result); | |
| 113 } | |
| 114 | |
| 115 void AddRuleForAllFamilies(const std::string& hostname, | |
| 116 const std::string& ip_list) { | |
| 117 AddressList result; | |
| 118 int rv = ParseAddressList(ip_list, "", &result); | |
| 119 DCHECK_EQ(OK, rv); | |
| 120 AddRule(hostname, ADDRESS_FAMILY_UNSPECIFIED, result); | |
| 121 AddRule(hostname, ADDRESS_FAMILY_IPV4, result); | |
| 122 AddRule(hostname, ADDRESS_FAMILY_IPV6, result); | |
| 123 } | |
| 124 | |
| 125 virtual int Resolve(const std::string& hostname, | |
| 126 AddressFamily address_family, | |
| 127 HostResolverFlags host_resolver_flags, | |
| 128 AddressList* addrlist, | |
| 129 int* os_error) OVERRIDE { | |
| 130 base::AutoLock lock(lock_); | |
| 131 capture_list_.push_back(ResolveKey(hostname, address_family)); | |
| 132 ++num_requests_waiting_; | |
| 133 requests_waiting_.Broadcast(); | |
| 134 while (!num_slots_available_) | |
| 135 slots_available_.Wait(); | |
| 136 DCHECK_GT(num_requests_waiting_, 0u); | |
| 137 --num_slots_available_; | |
| 138 --num_requests_waiting_; | |
| 139 if (rules_.empty()) { | |
| 140 int rv = ParseAddressList("127.0.0.1", "", addrlist); | |
| 141 DCHECK_EQ(OK, rv); | |
| 142 return OK; | |
| 143 } | |
| 144 ResolveKey key(hostname, address_family); | |
| 145 if (rules_.count(key) == 0) | |
| 146 return ERR_NAME_NOT_RESOLVED; | |
| 147 *addrlist = rules_[key]; | |
| 148 return OK; | |
| 149 } | |
| 150 | |
| 151 CaptureList GetCaptureList() const { | |
| 152 CaptureList copy; | |
| 153 { | |
| 154 base::AutoLock lock(lock_); | |
| 155 copy = capture_list_; | |
| 156 } | |
| 157 return copy; | |
| 158 } | |
| 159 | |
| 160 bool HasBlockedRequests() const { | |
| 161 base::AutoLock lock(lock_); | |
| 162 return num_requests_waiting_ > num_slots_available_; | |
| 163 } | |
| 164 | |
| 165 protected: | |
| 166 virtual ~MockHostResolverProc() {} | |
| 167 | |
| 168 private: | |
| 169 mutable base::Lock lock_; | |
| 170 std::map<ResolveKey, AddressList> rules_; | |
| 171 CaptureList capture_list_; | |
| 172 unsigned num_requests_waiting_; | |
| 173 unsigned num_slots_available_; | |
| 174 base::ConditionVariable requests_waiting_; | |
| 175 base::ConditionVariable slots_available_; | |
| 176 | |
| 177 DISALLOW_COPY_AND_ASSIGN(MockHostResolverProc); | |
| 178 }; | |
| 179 | |
| 180 // A wrapper for requests to a HostResolver. | |
| 181 class Request { | |
| 182 public: | |
| 183 // Base class of handlers to be executed on completion of requests. | |
| 184 struct Handler { | |
| 185 virtual ~Handler() {} | |
| 186 virtual void Handle(Request* request) = 0; | |
| 187 }; | |
| 188 | |
| 189 Request(const HostResolver::RequestInfo& info, | |
| 190 size_t index, | |
| 191 HostResolver* resolver, | |
| 192 Handler* handler) | |
| 193 : info_(info), | |
| 194 index_(index), | |
| 195 resolver_(resolver), | |
| 196 handler_(handler), | |
| 197 quit_on_complete_(false), | |
| 198 result_(ERR_UNEXPECTED), | |
| 199 handle_(NULL) {} | |
| 200 | |
| 201 int Resolve() { | |
| 202 DCHECK(resolver_); | |
| 203 DCHECK(!handle_); | |
| 204 list_ = AddressList(); | |
| 205 result_ = resolver_->Resolve( | |
| 206 info_, &list_, base::Bind(&Request::OnComplete, base::Unretained(this)), | |
| 207 &handle_, BoundNetLog()); | |
| 208 if (!list_.empty()) | |
| 209 EXPECT_EQ(OK, result_); | |
| 210 return result_; | |
| 211 } | |
| 212 | |
| 213 int ResolveFromCache() { | |
| 214 DCHECK(resolver_); | |
| 215 DCHECK(!handle_); | |
| 216 return resolver_->ResolveFromCache(info_, &list_, BoundNetLog()); | |
| 217 } | |
| 218 | |
| 219 void Cancel() { | |
| 220 DCHECK(resolver_); | |
| 221 DCHECK(handle_); | |
| 222 resolver_->CancelRequest(handle_); | |
| 223 handle_ = NULL; | |
| 224 } | |
| 225 | |
| 226 const HostResolver::RequestInfo& info() const { return info_; } | |
| 227 size_t index() const { return index_; } | |
| 228 const AddressList& list() const { return list_; } | |
| 229 int result() const { return result_; } | |
| 230 bool completed() const { return result_ != ERR_IO_PENDING; } | |
| 231 bool pending() const { return handle_ != NULL; } | |
| 232 | |
| 233 bool HasAddress(const std::string& address, int port) const { | |
| 234 IPAddressNumber ip; | |
| 235 bool rv = ParseIPLiteralToNumber(address, &ip); | |
| 236 DCHECK(rv); | |
| 237 return std::find(list_.begin(), | |
| 238 list_.end(), | |
| 239 IPEndPoint(ip, port)) != list_.end(); | |
| 240 } | |
| 241 | |
| 242 // Returns the number of addresses in |list_|. | |
| 243 unsigned NumberOfAddresses() const { | |
| 244 return list_.size(); | |
| 245 } | |
| 246 | |
| 247 bool HasOneAddress(const std::string& address, int port) const { | |
| 248 return HasAddress(address, port) && (NumberOfAddresses() == 1u); | |
| 249 } | |
| 250 | |
| 251 // Returns ERR_UNEXPECTED if timed out. | |
| 252 int WaitForResult() { | |
| 253 if (completed()) | |
| 254 return result_; | |
| 255 base::CancelableClosure closure(MessageLoop::QuitClosure()); | |
| 256 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 257 closure.callback(), | |
| 258 TestTimeouts::action_max_timeout()); | |
| 259 quit_on_complete_ = true; | |
| 260 MessageLoop::current()->Run(); | |
| 261 bool did_quit = !quit_on_complete_; | |
| 262 quit_on_complete_ = false; | |
| 263 closure.Cancel(); | |
| 264 if (did_quit) | |
| 265 return result_; | |
| 266 else | |
| 267 return ERR_UNEXPECTED; | |
| 268 } | |
| 269 | |
| 270 private: | |
| 271 void OnComplete(int rv) { | |
| 272 EXPECT_TRUE(pending()); | |
| 273 EXPECT_EQ(ERR_IO_PENDING, result_); | |
| 274 EXPECT_NE(ERR_IO_PENDING, rv); | |
| 275 result_ = rv; | |
| 276 handle_ = NULL; | |
| 277 if (!list_.empty()) { | |
| 278 EXPECT_EQ(OK, result_); | |
| 279 EXPECT_EQ(info_.port(), list_.front().port()); | |
| 280 } | |
| 281 if (handler_) | |
| 282 handler_->Handle(this); | |
| 283 if (quit_on_complete_) { | |
| 284 MessageLoop::current()->Quit(); | |
| 285 quit_on_complete_ = false; | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 HostResolver::RequestInfo info_; | |
| 290 size_t index_; | |
| 291 HostResolver* resolver_; | |
| 292 Handler* handler_; | |
| 293 bool quit_on_complete_; | |
| 294 | |
| 295 AddressList list_; | |
| 296 int result_; | |
| 297 HostResolver::RequestHandle handle_; | |
| 298 | |
| 299 DISALLOW_COPY_AND_ASSIGN(Request); | |
| 300 }; | |
| 301 | |
| 302 // Using LookupAttemptHostResolverProc simulate very long lookups, and control | |
| 303 // which attempt resolves the host. | |
| 304 class LookupAttemptHostResolverProc : public HostResolverProc { | |
| 305 public: | |
| 306 LookupAttemptHostResolverProc(HostResolverProc* previous, | |
| 307 int attempt_number_to_resolve, | |
| 308 int total_attempts) | |
| 309 : HostResolverProc(previous), | |
| 310 attempt_number_to_resolve_(attempt_number_to_resolve), | |
| 311 current_attempt_number_(0), | |
| 312 total_attempts_(total_attempts), | |
| 313 total_attempts_resolved_(0), | |
| 314 resolved_attempt_number_(0), | |
| 315 all_done_(&lock_) { | |
| 316 } | |
| 317 | |
| 318 // Test harness will wait for all attempts to finish before checking the | |
| 319 // results. | |
| 320 void WaitForAllAttemptsToFinish(const base::TimeDelta& wait_time) { | |
| 321 base::TimeTicks end_time = base::TimeTicks::Now() + wait_time; | |
| 322 { | |
| 323 base::AutoLock auto_lock(lock_); | |
| 324 while (total_attempts_resolved_ != total_attempts_ && | |
| 325 base::TimeTicks::Now() < end_time) { | |
| 326 all_done_.TimedWait(end_time - base::TimeTicks::Now()); | |
| 327 } | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 // All attempts will wait for an attempt to resolve the host. | |
| 332 void WaitForAnAttemptToComplete() { | |
| 333 base::TimeDelta wait_time = base::TimeDelta::FromSeconds(60); | |
| 334 base::TimeTicks end_time = base::TimeTicks::Now() + wait_time; | |
| 335 { | |
| 336 base::AutoLock auto_lock(lock_); | |
| 337 while (resolved_attempt_number_ == 0 && base::TimeTicks::Now() < end_time) | |
| 338 all_done_.TimedWait(end_time - base::TimeTicks::Now()); | |
| 339 } | |
| 340 all_done_.Broadcast(); // Tell all waiting attempts to proceed. | |
| 341 } | |
| 342 | |
| 343 // Returns the number of attempts that have finished the Resolve() method. | |
| 344 int total_attempts_resolved() { return total_attempts_resolved_; } | |
| 345 | |
| 346 // Returns the first attempt that that has resolved the host. | |
| 347 int resolved_attempt_number() { return resolved_attempt_number_; } | |
| 348 | |
| 349 // HostResolverProc methods. | |
| 350 virtual int Resolve(const std::string& host, | |
| 351 AddressFamily address_family, | |
| 352 HostResolverFlags host_resolver_flags, | |
| 353 AddressList* addrlist, | |
| 354 int* os_error) OVERRIDE { | |
| 355 bool wait_for_right_attempt_to_complete = true; | |
| 356 { | |
| 357 base::AutoLock auto_lock(lock_); | |
| 358 ++current_attempt_number_; | |
| 359 if (current_attempt_number_ == attempt_number_to_resolve_) { | |
| 360 resolved_attempt_number_ = current_attempt_number_; | |
| 361 wait_for_right_attempt_to_complete = false; | |
| 362 } | |
| 363 } | |
| 364 | |
| 365 if (wait_for_right_attempt_to_complete) | |
| 366 // Wait for the attempt_number_to_resolve_ attempt to resolve. | |
| 367 WaitForAnAttemptToComplete(); | |
| 368 | |
| 369 int result = ResolveUsingPrevious(host, address_family, host_resolver_flags, | |
| 370 addrlist, os_error); | |
| 371 | |
| 372 { | |
| 373 base::AutoLock auto_lock(lock_); | |
| 374 ++total_attempts_resolved_; | |
| 375 } | |
| 376 | |
| 377 all_done_.Broadcast(); // Tell all attempts to proceed. | |
| 378 | |
| 379 // Since any negative number is considered a network error, with -1 having | |
| 380 // special meaning (ERR_IO_PENDING). We could return the attempt that has | |
| 381 // resolved the host as a negative number. For example, if attempt number 3 | |
| 382 // resolves the host, then this method returns -4. | |
| 383 if (result == OK) | |
| 384 return -1 - resolved_attempt_number_; | |
| 385 else | |
| 386 return result; | |
| 387 } | |
| 388 | |
| 389 protected: | |
| 390 virtual ~LookupAttemptHostResolverProc() {} | |
| 391 | |
| 392 private: | |
| 393 int attempt_number_to_resolve_; | |
| 394 int current_attempt_number_; // Incremented whenever Resolve is called. | |
| 395 int total_attempts_; | |
| 396 int total_attempts_resolved_; | |
| 397 int resolved_attempt_number_; | |
| 398 | |
| 399 // All attempts wait for right attempt to be resolve. | |
| 400 base::Lock lock_; | |
| 401 base::ConditionVariable all_done_; | |
| 402 }; | |
| 403 | |
| 404 } // namespace | |
| 405 | |
| 406 class HostResolverImplTest : public testing::Test { | |
| 407 public: | |
| 408 static const int kDefaultPort = 80; | |
| 409 | |
| 410 HostResolverImplTest() : proc_(new MockHostResolverProc()) {} | |
| 411 | |
| 412 protected: | |
| 413 // A Request::Handler which is a proxy to the HostResolverImplTest fixture. | |
| 414 struct Handler : public Request::Handler { | |
| 415 virtual ~Handler() {} | |
| 416 | |
| 417 // Proxy functions so that classes derived from Handler can access them. | |
| 418 Request* CreateRequest(const HostResolver::RequestInfo& info) { | |
| 419 return test->CreateRequest(info); | |
| 420 } | |
| 421 Request* CreateRequest(const std::string& hostname, int port) { | |
| 422 return test->CreateRequest(hostname, port); | |
| 423 } | |
| 424 Request* CreateRequest(const std::string& hostname) { | |
| 425 return test->CreateRequest(hostname); | |
| 426 } | |
| 427 ScopedVector<Request>& requests() { return test->requests_; } | |
| 428 | |
| 429 void DeleteResolver() { test->resolver_.reset(); } | |
| 430 | |
| 431 HostResolverImplTest* test; | |
| 432 }; | |
| 433 | |
| 434 void CreateResolver() { | |
| 435 resolver_.reset(new HostResolverImpl( | |
| 436 HostCache::CreateDefaultCache(), | |
| 437 DefaultLimits(), | |
| 438 DefaultParams(proc_), | |
| 439 NULL)); | |
| 440 } | |
| 441 | |
| 442 // This HostResolverImpl will only allow 1 outstanding resolve at a time and | |
| 443 // perform no retries. | |
| 444 void CreateSerialResolver() { | |
| 445 HostResolverImpl::ProcTaskParams params = DefaultParams(proc_); | |
| 446 params.max_retry_attempts = 0u; | |
| 447 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, 1); | |
| 448 resolver_.reset(new HostResolverImpl( | |
| 449 HostCache::CreateDefaultCache(), | |
| 450 limits, | |
| 451 params, | |
| 452 NULL)); | |
| 453 } | |
| 454 | |
| 455 // The Request will not be made until a call to |Resolve()|, and the Job will | |
| 456 // not start until released by |proc_->SignalXXX|. | |
| 457 Request* CreateRequest(const HostResolver::RequestInfo& info) { | |
| 458 Request* req = new Request(info, requests_.size(), resolver_.get(), | |
| 459 handler_.get()); | |
| 460 requests_.push_back(req); | |
| 461 return req; | |
| 462 } | |
| 463 | |
| 464 Request* CreateRequest(const std::string& hostname, | |
| 465 int port, | |
| 466 RequestPriority priority, | |
| 467 AddressFamily family) { | |
| 468 HostResolver::RequestInfo info(HostPortPair(hostname, port)); | |
| 469 info.set_priority(priority); | |
| 470 info.set_address_family(family); | |
| 471 return CreateRequest(info); | |
| 472 } | |
| 473 | |
| 474 Request* CreateRequest(const std::string& hostname, | |
| 475 int port, | |
| 476 RequestPriority priority) { | |
| 477 return CreateRequest(hostname, port, priority, ADDRESS_FAMILY_UNSPECIFIED); | |
| 478 } | |
| 479 | |
| 480 Request* CreateRequest(const std::string& hostname, int port) { | |
| 481 return CreateRequest(hostname, port, MEDIUM); | |
| 482 } | |
| 483 | |
| 484 Request* CreateRequest(const std::string& hostname) { | |
| 485 return CreateRequest(hostname, kDefaultPort); | |
| 486 } | |
| 487 | |
| 488 virtual void SetUp() OVERRIDE { | |
| 489 CreateResolver(); | |
| 490 } | |
| 491 | |
| 492 virtual void TearDown() OVERRIDE { | |
| 493 if (resolver_.get()) | |
| 494 EXPECT_EQ(0u, resolver_->num_running_jobs_for_tests()); | |
| 495 EXPECT_FALSE(proc_->HasBlockedRequests()); | |
| 496 } | |
| 497 | |
| 498 void set_handler(Handler* handler) { | |
| 499 handler_.reset(handler); | |
| 500 handler_->test = this; | |
| 501 } | |
| 502 | |
| 503 // Friendship is not inherited, so use proxies to access those. | |
| 504 size_t num_running_jobs() const { | |
| 505 DCHECK(resolver_.get()); | |
| 506 return resolver_->num_running_jobs_for_tests(); | |
| 507 } | |
| 508 | |
| 509 scoped_refptr<MockHostResolverProc> proc_; | |
| 510 scoped_ptr<HostResolverImpl> resolver_; | |
| 511 ScopedVector<Request> requests_; | |
| 512 | |
| 513 scoped_ptr<Handler> handler_; | |
| 514 }; | |
| 515 | |
| 516 TEST_F(HostResolverImplTest, AsynchronousLookup) { | |
| 517 proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42"); | |
| 518 proc_->SignalMultiple(1u); | |
| 519 | |
| 520 Request* req = CreateRequest("just.testing", 80); | |
| 521 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 522 EXPECT_EQ(OK, req->WaitForResult()); | |
| 523 | |
| 524 EXPECT_TRUE(req->HasOneAddress("192.168.1.42", 80)); | |
| 525 | |
| 526 EXPECT_EQ("just.testing", proc_->GetCaptureList()[0].hostname); | |
| 527 } | |
| 528 | |
| 529 TEST_F(HostResolverImplTest, FailedAsynchronousLookup) { | |
| 530 proc_->AddRuleForAllFamilies("", "0.0.0.0"); // Default to failures. | |
| 531 proc_->SignalMultiple(1u); | |
| 532 | |
| 533 Request* req = CreateRequest("just.testing", 80); | |
| 534 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 535 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req->WaitForResult()); | |
| 536 | |
| 537 EXPECT_EQ("just.testing", proc_->GetCaptureList()[0].hostname); | |
| 538 | |
| 539 // Also test that the error is not cached. | |
| 540 EXPECT_EQ(ERR_DNS_CACHE_MISS, req->ResolveFromCache()); | |
| 541 } | |
| 542 | |
| 543 TEST_F(HostResolverImplTest, AbortedAsynchronousLookup) { | |
| 544 Request* req0 = CreateRequest("just.testing", 80); | |
| 545 EXPECT_EQ(ERR_IO_PENDING, req0->Resolve()); | |
| 546 | |
| 547 EXPECT_TRUE(proc_->WaitFor(1u)); | |
| 548 | |
| 549 // Resolver is destroyed while job is running on WorkerPool. | |
| 550 resolver_.reset(); | |
| 551 | |
| 552 proc_->SignalAll(); | |
| 553 | |
| 554 // To ensure there was no spurious callback, complete with a new resolver. | |
| 555 CreateResolver(); | |
| 556 Request* req1 = CreateRequest("just.testing", 80); | |
| 557 EXPECT_EQ(ERR_IO_PENDING, req1->Resolve()); | |
| 558 | |
| 559 proc_->SignalMultiple(2u); | |
| 560 | |
| 561 EXPECT_EQ(OK, req1->WaitForResult()); | |
| 562 | |
| 563 // This request was canceled. | |
| 564 EXPECT_FALSE(req0->completed()); | |
| 565 } | |
| 566 | |
| 567 TEST_F(HostResolverImplTest, NumericIPv4Address) { | |
| 568 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in. | |
| 569 Request* req = CreateRequest("127.1.2.3", 5555); | |
| 570 EXPECT_EQ(OK, req->Resolve()); | |
| 571 | |
| 572 EXPECT_TRUE(req->HasOneAddress("127.1.2.3", 5555)); | |
| 573 } | |
| 574 | |
| 575 TEST_F(HostResolverImplTest, NumericIPv6Address) { | |
| 576 // Resolve a plain IPv6 address. Don't worry about [brackets], because | |
| 577 // the caller should have removed them. | |
| 578 Request* req = CreateRequest("2001:db8::1", 5555); | |
| 579 EXPECT_EQ(OK, req->Resolve()); | |
| 580 | |
| 581 EXPECT_TRUE(req->HasOneAddress("2001:db8::1", 5555)); | |
| 582 } | |
| 583 | |
| 584 TEST_F(HostResolverImplTest, EmptyHost) { | |
| 585 Request* req = CreateRequest("", 5555); | |
| 586 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req->Resolve()); | |
| 587 } | |
| 588 | |
| 589 TEST_F(HostResolverImplTest, LongHost) { | |
| 590 Request* req = CreateRequest(std::string(4097, 'a'), 5555); | |
| 591 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req->Resolve()); | |
| 592 } | |
| 593 | |
| 594 TEST_F(HostResolverImplTest, DeDupeRequests) { | |
| 595 // Start 5 requests, duplicating hosts "a" and "b". Since the resolver_proc is | |
| 596 // blocked, these should all pile up until we signal it. | |
| 597 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80)->Resolve()); | |
| 598 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 80)->Resolve()); | |
| 599 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 81)->Resolve()); | |
| 600 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 82)->Resolve()); | |
| 601 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 83)->Resolve()); | |
| 602 | |
| 603 proc_->SignalMultiple(2u); // One for "a", one for "b". | |
| 604 | |
| 605 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 606 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 607 } | |
| 608 } | |
| 609 | |
| 610 TEST_F(HostResolverImplTest, CancelMultipleRequests) { | |
| 611 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80)->Resolve()); | |
| 612 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 80)->Resolve()); | |
| 613 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 81)->Resolve()); | |
| 614 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 82)->Resolve()); | |
| 615 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 83)->Resolve()); | |
| 616 | |
| 617 // Cancel everything except request for ("a", 82). | |
| 618 requests_[0]->Cancel(); | |
| 619 requests_[1]->Cancel(); | |
| 620 requests_[2]->Cancel(); | |
| 621 requests_[4]->Cancel(); | |
| 622 | |
| 623 proc_->SignalMultiple(2u); // One for "a", one for "b". | |
| 624 | |
| 625 EXPECT_EQ(OK, requests_[3]->WaitForResult()); | |
| 626 } | |
| 627 | |
| 628 TEST_F(HostResolverImplTest, CanceledRequestsReleaseJobSlots) { | |
| 629 // Fill up the dispatcher and queue. | |
| 630 for (unsigned i = 0; i < kMaxJobs + 1; ++i) { | |
| 631 std::string hostname = "a_"; | |
| 632 hostname[1] = 'a' + i; | |
| 633 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(hostname, 80)->Resolve()); | |
| 634 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(hostname, 81)->Resolve()); | |
| 635 } | |
| 636 | |
| 637 EXPECT_TRUE(proc_->WaitFor(kMaxJobs)); | |
| 638 | |
| 639 // Cancel all but last two. | |
| 640 for (unsigned i = 0; i < requests_.size() - 2; ++i) { | |
| 641 requests_[i]->Cancel(); | |
| 642 } | |
| 643 | |
| 644 EXPECT_TRUE(proc_->WaitFor(kMaxJobs + 1)); | |
| 645 | |
| 646 proc_->SignalAll(); | |
| 647 | |
| 648 size_t num_requests = requests_.size(); | |
| 649 EXPECT_EQ(OK, requests_[num_requests - 1]->WaitForResult()); | |
| 650 EXPECT_EQ(OK, requests_[num_requests - 2]->result()); | |
| 651 } | |
| 652 | |
| 653 TEST_F(HostResolverImplTest, CancelWithinCallback) { | |
| 654 struct MyHandler : public Handler { | |
| 655 virtual void Handle(Request* req) OVERRIDE { | |
| 656 // Port 80 is the first request that the callback will be invoked for. | |
| 657 // While we are executing within that callback, cancel the other requests | |
| 658 // in the job and start another request. | |
| 659 if (req->index() == 0) { | |
| 660 // Once "a:80" completes, it will cancel "a:81" and "a:82". | |
| 661 requests()[1]->Cancel(); | |
| 662 requests()[2]->Cancel(); | |
| 663 } | |
| 664 } | |
| 665 }; | |
| 666 set_handler(new MyHandler()); | |
| 667 | |
| 668 for (size_t i = 0; i < 4; ++i) { | |
| 669 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80 + i)->Resolve()) << i; | |
| 670 } | |
| 671 | |
| 672 proc_->SignalMultiple(2u); // One for "a". One for "finalrequest". | |
| 673 | |
| 674 EXPECT_EQ(OK, requests_[0]->WaitForResult()); | |
| 675 | |
| 676 Request* final_request = CreateRequest("finalrequest", 70); | |
| 677 EXPECT_EQ(ERR_IO_PENDING, final_request->Resolve()); | |
| 678 EXPECT_EQ(OK, final_request->WaitForResult()); | |
| 679 EXPECT_TRUE(requests_[3]->completed()); | |
| 680 } | |
| 681 | |
| 682 TEST_F(HostResolverImplTest, DeleteWithinCallback) { | |
| 683 struct MyHandler : public Handler { | |
| 684 virtual void Handle(Request* req) OVERRIDE { | |
| 685 EXPECT_EQ("a", req->info().hostname()); | |
| 686 EXPECT_EQ(80, req->info().port()); | |
| 687 | |
| 688 DeleteResolver(); | |
| 689 | |
| 690 // Quit after returning from OnCompleted (to give it a chance at | |
| 691 // incorrectly running the cancelled tasks). | |
| 692 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
| 693 } | |
| 694 }; | |
| 695 set_handler(new MyHandler()); | |
| 696 | |
| 697 for (size_t i = 0; i < 4; ++i) { | |
| 698 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80 + i)->Resolve()) << i; | |
| 699 } | |
| 700 | |
| 701 proc_->SignalMultiple(1u); // One for "a". | |
| 702 | |
| 703 // |MyHandler| will send quit message once all the requests have finished. | |
| 704 MessageLoop::current()->Run(); | |
| 705 } | |
| 706 | |
| 707 TEST_F(HostResolverImplTest, DeleteWithinAbortedCallback) { | |
| 708 struct MyHandler : public Handler { | |
| 709 virtual void Handle(Request* req) OVERRIDE { | |
| 710 EXPECT_EQ("a", req->info().hostname()); | |
| 711 EXPECT_EQ(80, req->info().port()); | |
| 712 | |
| 713 DeleteResolver(); | |
| 714 | |
| 715 // Quit after returning from OnCompleted (to give it a chance at | |
| 716 // incorrectly running the cancelled tasks). | |
| 717 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
| 718 } | |
| 719 }; | |
| 720 set_handler(new MyHandler()); | |
| 721 | |
| 722 // This test assumes that the Jobs will be Aborted in order ["a", "b"] | |
| 723 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80)->Resolve()); | |
| 724 // HostResolverImpl will be deleted before later Requests can complete. | |
| 725 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 81)->Resolve()); | |
| 726 // Job for 'b' will be aborted before it can complete. | |
| 727 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 82)->Resolve()); | |
| 728 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b", 83)->Resolve()); | |
| 729 | |
| 730 EXPECT_TRUE(proc_->WaitFor(1u)); | |
| 731 | |
| 732 // Triggering an IP address change. | |
| 733 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 734 | |
| 735 // |MyHandler| will send quit message once all the requests have finished. | |
| 736 MessageLoop::current()->Run(); | |
| 737 | |
| 738 EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->result()); | |
| 739 EXPECT_EQ(ERR_IO_PENDING, requests_[1]->result()); | |
| 740 EXPECT_EQ(ERR_IO_PENDING, requests_[2]->result()); | |
| 741 EXPECT_EQ(ERR_IO_PENDING, requests_[3]->result()); | |
| 742 // Clean up. | |
| 743 proc_->SignalMultiple(requests_.size()); | |
| 744 } | |
| 745 | |
| 746 TEST_F(HostResolverImplTest, StartWithinCallback) { | |
| 747 struct MyHandler : public Handler { | |
| 748 virtual void Handle(Request* req) OVERRIDE { | |
| 749 if (req->index() == 0) { | |
| 750 // On completing the first request, start another request for "a". | |
| 751 // Since caching is disabled, this will result in another async request. | |
| 752 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 70)->Resolve()); | |
| 753 } | |
| 754 } | |
| 755 }; | |
| 756 set_handler(new MyHandler()); | |
| 757 | |
| 758 // Turn off caching for this host resolver. | |
| 759 resolver_.reset(new HostResolverImpl( | |
| 760 scoped_ptr<HostCache>(), | |
| 761 DefaultLimits(), | |
| 762 DefaultParams(proc_), | |
| 763 NULL)); | |
| 764 | |
| 765 for (size_t i = 0; i < 4; ++i) { | |
| 766 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80 + i)->Resolve()) << i; | |
| 767 } | |
| 768 | |
| 769 proc_->SignalMultiple(2u); // One for "a". One for the second "a". | |
| 770 | |
| 771 EXPECT_EQ(OK, requests_[0]->WaitForResult()); | |
| 772 ASSERT_EQ(5u, requests_.size()); | |
| 773 EXPECT_EQ(OK, requests_.back()->WaitForResult()); | |
| 774 | |
| 775 EXPECT_EQ(2u, proc_->GetCaptureList().size()); | |
| 776 } | |
| 777 | |
| 778 TEST_F(HostResolverImplTest, BypassCache) { | |
| 779 struct MyHandler : public Handler { | |
| 780 virtual void Handle(Request* req) OVERRIDE { | |
| 781 if (req->index() == 0) { | |
| 782 // On completing the first request, start another request for "a". | |
| 783 // Since caching is enabled, this should complete synchronously. | |
| 784 std::string hostname = req->info().hostname(); | |
| 785 EXPECT_EQ(OK, CreateRequest(hostname, 70)->Resolve()); | |
| 786 EXPECT_EQ(OK, CreateRequest(hostname, 75)->ResolveFromCache()); | |
| 787 | |
| 788 // Ok good. Now make sure that if we ask to bypass the cache, it can no | |
| 789 // longer service the request synchronously. | |
| 790 HostResolver::RequestInfo info(HostPortPair(hostname, 71)); | |
| 791 info.set_allow_cached_response(false); | |
| 792 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(info)->Resolve()); | |
| 793 } else if (71 == req->info().port()) { | |
| 794 // Test is done. | |
| 795 MessageLoop::current()->Quit(); | |
| 796 } else { | |
| 797 FAIL() << "Unexpected request"; | |
| 798 } | |
| 799 } | |
| 800 }; | |
| 801 set_handler(new MyHandler()); | |
| 802 | |
| 803 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a", 80)->Resolve()); | |
| 804 proc_->SignalMultiple(3u); // Only need two, but be generous. | |
| 805 | |
| 806 // |verifier| will send quit message once all the requests have finished. | |
| 807 MessageLoop::current()->Run(); | |
| 808 EXPECT_EQ(2u, proc_->GetCaptureList().size()); | |
| 809 } | |
| 810 | |
| 811 // Test that IP address changes flush the cache. | |
| 812 TEST_F(HostResolverImplTest, FlushCacheOnIPAddressChange) { | |
| 813 proc_->SignalMultiple(2u); // One before the flush, one after. | |
| 814 | |
| 815 Request* req = CreateRequest("host1", 70); | |
| 816 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 817 EXPECT_EQ(OK, req->WaitForResult()); | |
| 818 | |
| 819 req = CreateRequest("host1", 75); | |
| 820 EXPECT_EQ(OK, req->Resolve()); // Should complete synchronously. | |
| 821 | |
| 822 // Flush cache by triggering an IP address change. | |
| 823 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 824 MessageLoop::current()->RunUntilIdle(); // Notification happens async. | |
| 825 | |
| 826 // Resolve "host1" again -- this time it won't be served from cache, so it | |
| 827 // will complete asynchronously. | |
| 828 req = CreateRequest("host1", 80); | |
| 829 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 830 EXPECT_EQ(OK, req->WaitForResult()); | |
| 831 } | |
| 832 | |
| 833 // Test that IP address changes send ERR_NETWORK_CHANGED to pending requests. | |
| 834 TEST_F(HostResolverImplTest, AbortOnIPAddressChanged) { | |
| 835 Request* req = CreateRequest("host1", 70); | |
| 836 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 837 | |
| 838 EXPECT_TRUE(proc_->WaitFor(1u)); | |
| 839 // Triggering an IP address change. | |
| 840 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 841 MessageLoop::current()->RunUntilIdle(); // Notification happens async. | |
| 842 proc_->SignalAll(); | |
| 843 | |
| 844 EXPECT_EQ(ERR_NETWORK_CHANGED, req->WaitForResult()); | |
| 845 EXPECT_EQ(0u, resolver_->GetHostCache()->size()); | |
| 846 } | |
| 847 | |
| 848 // Obey pool constraints after IP address has changed. | |
| 849 TEST_F(HostResolverImplTest, ObeyPoolConstraintsAfterIPAddressChange) { | |
| 850 // Runs at most one job at a time. | |
| 851 CreateSerialResolver(); | |
| 852 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("a")->Resolve()); | |
| 853 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("b")->Resolve()); | |
| 854 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("c")->Resolve()); | |
| 855 | |
| 856 EXPECT_TRUE(proc_->WaitFor(1u)); | |
| 857 // Triggering an IP address change. | |
| 858 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 859 MessageLoop::current()->RunUntilIdle(); // Notification happens async. | |
| 860 proc_->SignalMultiple(3u); // Let the false-start go so that we can catch it. | |
| 861 | |
| 862 EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->WaitForResult()); | |
| 863 | |
| 864 EXPECT_EQ(1u, num_running_jobs()); | |
| 865 | |
| 866 EXPECT_FALSE(requests_[1]->completed()); | |
| 867 EXPECT_FALSE(requests_[2]->completed()); | |
| 868 | |
| 869 EXPECT_EQ(OK, requests_[2]->WaitForResult()); | |
| 870 EXPECT_EQ(OK, requests_[1]->result()); | |
| 871 } | |
| 872 | |
| 873 // Tests that a new Request made from the callback of a previously aborted one | |
| 874 // will not be aborted. | |
| 875 TEST_F(HostResolverImplTest, AbortOnlyExistingRequestsOnIPAddressChange) { | |
| 876 struct MyHandler : public Handler { | |
| 877 virtual void Handle(Request* req) OVERRIDE { | |
| 878 // Start new request for a different hostname to ensure that the order | |
| 879 // of jobs in HostResolverImpl is not stable. | |
| 880 std::string hostname; | |
| 881 if (req->index() == 0) | |
| 882 hostname = "zzz"; | |
| 883 else if (req->index() == 1) | |
| 884 hostname = "aaa"; | |
| 885 else if (req->index() == 2) | |
| 886 hostname = "eee"; | |
| 887 else | |
| 888 return; // A request started from within MyHandler. | |
| 889 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(hostname)->Resolve()) << hostname; | |
| 890 } | |
| 891 }; | |
| 892 set_handler(new MyHandler()); | |
| 893 | |
| 894 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("bbb")->Resolve()); | |
| 895 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("eee")->Resolve()); | |
| 896 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ccc")->Resolve()); | |
| 897 | |
| 898 // Wait until all are blocked; | |
| 899 EXPECT_TRUE(proc_->WaitFor(3u)); | |
| 900 // Trigger an IP address change. | |
| 901 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
| 902 // This should abort all running jobs. | |
| 903 MessageLoop::current()->RunUntilIdle(); | |
| 904 EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[0]->result()); | |
| 905 EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[1]->result()); | |
| 906 EXPECT_EQ(ERR_NETWORK_CHANGED, requests_[2]->result()); | |
| 907 ASSERT_EQ(6u, requests_.size()); | |
| 908 // Unblock all calls to proc. | |
| 909 proc_->SignalMultiple(requests_.size()); | |
| 910 // Run until the re-started requests finish. | |
| 911 EXPECT_EQ(OK, requests_[3]->WaitForResult()); | |
| 912 EXPECT_EQ(OK, requests_[4]->WaitForResult()); | |
| 913 EXPECT_EQ(OK, requests_[5]->WaitForResult()); | |
| 914 // Verify that results of aborted Jobs were not cached. | |
| 915 EXPECT_EQ(6u, proc_->GetCaptureList().size()); | |
| 916 EXPECT_EQ(3u, resolver_->GetHostCache()->size()); | |
| 917 } | |
| 918 | |
| 919 // Tests that when the maximum threads is set to 1, requests are dequeued | |
| 920 // in order of priority. | |
| 921 TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) { | |
| 922 CreateSerialResolver(); | |
| 923 | |
| 924 // Note that at this point the MockHostResolverProc is blocked, so any | |
| 925 // requests we make will not complete. | |
| 926 CreateRequest("req0", 80, LOW); | |
| 927 CreateRequest("req1", 80, MEDIUM); | |
| 928 CreateRequest("req2", 80, MEDIUM); | |
| 929 CreateRequest("req3", 80, LOW); | |
| 930 CreateRequest("req4", 80, HIGHEST); | |
| 931 CreateRequest("req5", 80, LOW); | |
| 932 CreateRequest("req6", 80, LOW); | |
| 933 CreateRequest("req5", 80, HIGHEST); | |
| 934 | |
| 935 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 936 EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i; | |
| 937 } | |
| 938 | |
| 939 // Unblock the resolver thread so the requests can run. | |
| 940 proc_->SignalMultiple(requests_.size()); // More than needed. | |
| 941 | |
| 942 // Wait for all the requests to complete succesfully. | |
| 943 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 944 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 945 } | |
| 946 | |
| 947 // Since we have restricted to a single concurrent thread in the jobpool, | |
| 948 // the requests should complete in order of priority (with the exception | |
| 949 // of the first request, which gets started right away, since there is | |
| 950 // nothing outstanding). | |
| 951 MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); | |
| 952 ASSERT_EQ(7u, capture_list.size()); | |
| 953 | |
| 954 EXPECT_EQ("req0", capture_list[0].hostname); | |
| 955 EXPECT_EQ("req4", capture_list[1].hostname); | |
| 956 EXPECT_EQ("req5", capture_list[2].hostname); | |
| 957 EXPECT_EQ("req1", capture_list[3].hostname); | |
| 958 EXPECT_EQ("req2", capture_list[4].hostname); | |
| 959 EXPECT_EQ("req3", capture_list[5].hostname); | |
| 960 EXPECT_EQ("req6", capture_list[6].hostname); | |
| 961 } | |
| 962 | |
| 963 // Try cancelling a job which has not started yet. | |
| 964 TEST_F(HostResolverImplTest, CancelPendingRequest) { | |
| 965 CreateSerialResolver(); | |
| 966 | |
| 967 CreateRequest("req0", 80, LOWEST); | |
| 968 CreateRequest("req1", 80, HIGHEST); // Will cancel. | |
| 969 CreateRequest("req2", 80, MEDIUM); | |
| 970 CreateRequest("req3", 80, LOW); | |
| 971 CreateRequest("req4", 80, HIGHEST); // Will cancel. | |
| 972 CreateRequest("req5", 80, LOWEST); // Will cancel. | |
| 973 CreateRequest("req6", 80, MEDIUM); | |
| 974 | |
| 975 // Start all of the requests. | |
| 976 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 977 EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i; | |
| 978 } | |
| 979 | |
| 980 // Cancel some requests | |
| 981 requests_[1]->Cancel(); | |
| 982 requests_[4]->Cancel(); | |
| 983 requests_[5]->Cancel(); | |
| 984 | |
| 985 // Unblock the resolver thread so the requests can run. | |
| 986 proc_->SignalMultiple(requests_.size()); // More than needed. | |
| 987 | |
| 988 // Wait for all the requests to complete succesfully. | |
| 989 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 990 if (!requests_[i]->pending()) | |
| 991 continue; // Don't wait for the requests we cancelled. | |
| 992 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 993 } | |
| 994 | |
| 995 // Verify that they called out the the resolver proc (which runs on the | |
| 996 // resolver thread) in the expected order. | |
| 997 MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); | |
| 998 ASSERT_EQ(4u, capture_list.size()); | |
| 999 | |
| 1000 EXPECT_EQ("req0", capture_list[0].hostname); | |
| 1001 EXPECT_EQ("req2", capture_list[1].hostname); | |
| 1002 EXPECT_EQ("req6", capture_list[2].hostname); | |
| 1003 EXPECT_EQ("req3", capture_list[3].hostname); | |
| 1004 } | |
| 1005 | |
| 1006 // Test that when too many requests are enqueued, old ones start to be aborted. | |
| 1007 TEST_F(HostResolverImplTest, QueueOverflow) { | |
| 1008 CreateSerialResolver(); | |
| 1009 | |
| 1010 // Allow only 3 queued jobs. | |
| 1011 const size_t kMaxPendingJobs = 3u; | |
| 1012 resolver_->SetMaxQueuedJobs(kMaxPendingJobs); | |
| 1013 | |
| 1014 // Note that at this point the MockHostResolverProc is blocked, so any | |
| 1015 // requests we make will not complete. | |
| 1016 | |
| 1017 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req0", 80, LOWEST)->Resolve()); | |
| 1018 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req1", 80, HIGHEST)->Resolve()); | |
| 1019 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req2", 80, MEDIUM)->Resolve()); | |
| 1020 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req3", 80, MEDIUM)->Resolve()); | |
| 1021 | |
| 1022 // At this point, there are 3 enqueued jobs. | |
| 1023 // Insertion of subsequent requests will cause evictions | |
| 1024 // based on priority. | |
| 1025 | |
| 1026 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, | |
| 1027 CreateRequest("req4", 80, LOW)->Resolve()); // Evicts itself! | |
| 1028 | |
| 1029 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req5", 80, MEDIUM)->Resolve()); | |
| 1030 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, requests_[2]->result()); | |
| 1031 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req6", 80, HIGHEST)->Resolve()); | |
| 1032 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, requests_[3]->result()); | |
| 1033 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("req7", 80, MEDIUM)->Resolve()); | |
| 1034 EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, requests_[5]->result()); | |
| 1035 | |
| 1036 // Unblock the resolver thread so the requests can run. | |
| 1037 proc_->SignalMultiple(4u); | |
| 1038 | |
| 1039 // The rest should succeed. | |
| 1040 EXPECT_EQ(OK, requests_[7]->WaitForResult()); | |
| 1041 EXPECT_EQ(OK, requests_[0]->result()); | |
| 1042 EXPECT_EQ(OK, requests_[1]->result()); | |
| 1043 EXPECT_EQ(OK, requests_[6]->result()); | |
| 1044 | |
| 1045 // Verify that they called out the the resolver proc (which runs on the | |
| 1046 // resolver thread) in the expected order. | |
| 1047 MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); | |
| 1048 ASSERT_EQ(4u, capture_list.size()); | |
| 1049 | |
| 1050 EXPECT_EQ("req0", capture_list[0].hostname); | |
| 1051 EXPECT_EQ("req1", capture_list[1].hostname); | |
| 1052 EXPECT_EQ("req6", capture_list[2].hostname); | |
| 1053 EXPECT_EQ("req7", capture_list[3].hostname); | |
| 1054 | |
| 1055 // Verify that the evicted (incomplete) requests were not cached. | |
| 1056 EXPECT_EQ(4u, resolver_->GetHostCache()->size()); | |
| 1057 | |
| 1058 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 1059 EXPECT_TRUE(requests_[i]->completed()) << i; | |
| 1060 } | |
| 1061 } | |
| 1062 | |
| 1063 // Tests that after changing the default AddressFamily to IPV4, requests | |
| 1064 // with UNSPECIFIED address family map to IPV4. | |
| 1065 TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv4) { | |
| 1066 CreateSerialResolver(); // To guarantee order of resolutions. | |
| 1067 | |
| 1068 proc_->AddRule("h1", ADDRESS_FAMILY_IPV4, "1.0.0.1"); | |
| 1069 proc_->AddRule("h1", ADDRESS_FAMILY_IPV6, "::2"); | |
| 1070 | |
| 1071 resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4); | |
| 1072 | |
| 1073 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_UNSPECIFIED); | |
| 1074 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV4); | |
| 1075 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV6); | |
| 1076 | |
| 1077 // Start all of the requests. | |
| 1078 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 1079 EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i; | |
| 1080 } | |
| 1081 | |
| 1082 proc_->SignalMultiple(requests_.size()); | |
| 1083 | |
| 1084 // Wait for all the requests to complete. | |
| 1085 for (size_t i = 0u; i < requests_.size(); ++i) { | |
| 1086 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1087 } | |
| 1088 | |
| 1089 // Since the requests all had the same priority and we limited the thread | |
| 1090 // count to 1, they should have completed in the same order as they were | |
| 1091 // requested. Moreover, request0 and request1 will have been serviced by | |
| 1092 // the same job. | |
| 1093 | |
| 1094 MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); | |
| 1095 ASSERT_EQ(2u, capture_list.size()); | |
| 1096 | |
| 1097 EXPECT_EQ("h1", capture_list[0].hostname); | |
| 1098 EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[0].address_family); | |
| 1099 | |
| 1100 EXPECT_EQ("h1", capture_list[1].hostname); | |
| 1101 EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[1].address_family); | |
| 1102 | |
| 1103 // Now check that the correct resolved IP addresses were returned. | |
| 1104 EXPECT_TRUE(requests_[0]->HasOneAddress("1.0.0.1", 80)); | |
| 1105 EXPECT_TRUE(requests_[1]->HasOneAddress("1.0.0.1", 80)); | |
| 1106 EXPECT_TRUE(requests_[2]->HasOneAddress("::2", 80)); | |
| 1107 } | |
| 1108 | |
| 1109 // This is the exact same test as SetDefaultAddressFamily_IPv4, except the | |
| 1110 // default family is set to IPv6 and the family of requests is flipped where | |
| 1111 // specified. | |
| 1112 TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv6) { | |
| 1113 CreateSerialResolver(); // To guarantee order of resolutions. | |
| 1114 | |
| 1115 // Don't use IPv6 replacements here since some systems don't support it. | |
| 1116 proc_->AddRule("h1", ADDRESS_FAMILY_IPV4, "1.0.0.1"); | |
| 1117 proc_->AddRule("h1", ADDRESS_FAMILY_IPV6, "::2"); | |
| 1118 | |
| 1119 resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV6); | |
| 1120 | |
| 1121 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_UNSPECIFIED); | |
| 1122 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV6); | |
| 1123 CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV4); | |
| 1124 | |
| 1125 // Start all of the requests. | |
| 1126 for (size_t i = 0; i < requests_.size(); ++i) { | |
| 1127 EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i; | |
| 1128 } | |
| 1129 | |
| 1130 proc_->SignalMultiple(requests_.size()); | |
| 1131 | |
| 1132 // Wait for all the requests to complete. | |
| 1133 for (size_t i = 0u; i < requests_.size(); ++i) { | |
| 1134 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1135 } | |
| 1136 | |
| 1137 // Since the requests all had the same priority and we limited the thread | |
| 1138 // count to 1, they should have completed in the same order as they were | |
| 1139 // requested. Moreover, request0 and request1 will have been serviced by | |
| 1140 // the same job. | |
| 1141 | |
| 1142 MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList(); | |
| 1143 ASSERT_EQ(2u, capture_list.size()); | |
| 1144 | |
| 1145 EXPECT_EQ("h1", capture_list[0].hostname); | |
| 1146 EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[0].address_family); | |
| 1147 | |
| 1148 EXPECT_EQ("h1", capture_list[1].hostname); | |
| 1149 EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[1].address_family); | |
| 1150 | |
| 1151 // Now check that the correct resolved IP addresses were returned. | |
| 1152 EXPECT_TRUE(requests_[0]->HasOneAddress("::2", 80)); | |
| 1153 EXPECT_TRUE(requests_[1]->HasOneAddress("::2", 80)); | |
| 1154 EXPECT_TRUE(requests_[2]->HasOneAddress("1.0.0.1", 80)); | |
| 1155 } | |
| 1156 | |
| 1157 TEST_F(HostResolverImplTest, ResolveFromCache) { | |
| 1158 proc_->AddRuleForAllFamilies("just.testing", "192.168.1.42"); | |
| 1159 proc_->SignalMultiple(1u); // Need only one. | |
| 1160 | |
| 1161 HostResolver::RequestInfo info(HostPortPair("just.testing", 80)); | |
| 1162 | |
| 1163 // First hit will miss the cache. | |
| 1164 EXPECT_EQ(ERR_DNS_CACHE_MISS, CreateRequest(info)->ResolveFromCache()); | |
| 1165 | |
| 1166 // This time, we fetch normally. | |
| 1167 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(info)->Resolve()); | |
| 1168 EXPECT_EQ(OK, requests_[1]->WaitForResult()); | |
| 1169 | |
| 1170 // Now we should be able to fetch from the cache. | |
| 1171 EXPECT_EQ(OK, CreateRequest(info)->ResolveFromCache()); | |
| 1172 EXPECT_TRUE(requests_[2]->HasOneAddress("192.168.1.42", 80)); | |
| 1173 } | |
| 1174 | |
| 1175 // Test the retry attempts simulating host resolver proc that takes too long. | |
| 1176 TEST_F(HostResolverImplTest, MultipleAttempts) { | |
| 1177 // Total number of attempts would be 3 and we want the 3rd attempt to resolve | |
| 1178 // the host. First and second attempt will be forced to sleep until they get | |
| 1179 // word that a resolution has completed. The 3rd resolution attempt will try | |
| 1180 // to get done ASAP, and won't sleep.. | |
| 1181 int kAttemptNumberToResolve = 3; | |
| 1182 int kTotalAttempts = 3; | |
| 1183 | |
| 1184 scoped_refptr<LookupAttemptHostResolverProc> resolver_proc( | |
| 1185 new LookupAttemptHostResolverProc( | |
| 1186 NULL, kAttemptNumberToResolve, kTotalAttempts)); | |
| 1187 | |
| 1188 HostResolverImpl::ProcTaskParams params = DefaultParams(resolver_proc.get()); | |
| 1189 | |
| 1190 // Specify smaller interval for unresponsive_delay_ for HostResolverImpl so | |
| 1191 // that unit test runs faster. For example, this test finishes in 1.5 secs | |
| 1192 // (500ms * 3). | |
| 1193 params.unresponsive_delay = base::TimeDelta::FromMilliseconds(500); | |
| 1194 | |
| 1195 resolver_.reset( | |
| 1196 new HostResolverImpl(HostCache::CreateDefaultCache(), | |
| 1197 DefaultLimits(), | |
| 1198 params, | |
| 1199 NULL)); | |
| 1200 | |
| 1201 // Resolve "host1". | |
| 1202 HostResolver::RequestInfo info(HostPortPair("host1", 70)); | |
| 1203 Request* req = CreateRequest(info); | |
| 1204 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 1205 | |
| 1206 // Resolve returns -4 to indicate that 3rd attempt has resolved the host. | |
| 1207 EXPECT_EQ(-4, req->WaitForResult()); | |
| 1208 | |
| 1209 resolver_proc->WaitForAllAttemptsToFinish( | |
| 1210 base::TimeDelta::FromMilliseconds(60000)); | |
| 1211 MessageLoop::current()->RunUntilIdle(); | |
| 1212 | |
| 1213 EXPECT_EQ(resolver_proc->total_attempts_resolved(), kTotalAttempts); | |
| 1214 EXPECT_EQ(resolver_proc->resolved_attempt_number(), kAttemptNumberToResolve); | |
| 1215 } | |
| 1216 | |
| 1217 DnsConfig CreateValidDnsConfig() { | |
| 1218 IPAddressNumber dns_ip; | |
| 1219 bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip); | |
| 1220 EXPECT_TRUE(rv); | |
| 1221 | |
| 1222 DnsConfig config; | |
| 1223 config.nameservers.push_back(IPEndPoint(dns_ip, dns_protocol::kDefaultPort)); | |
| 1224 EXPECT_TRUE(config.IsValid()); | |
| 1225 return config; | |
| 1226 } | |
| 1227 | |
| 1228 // Specialized fixture for tests of DnsTask. | |
| 1229 class HostResolverImplDnsTest : public HostResolverImplTest { | |
| 1230 protected: | |
| 1231 virtual void SetUp() OVERRIDE { | |
| 1232 AddDnsRule("er", dns_protocol::kTypeA, MockDnsClientRule::FAIL_SYNC); | |
| 1233 AddDnsRule("er", dns_protocol::kTypeAAAA, MockDnsClientRule::FAIL_SYNC); | |
| 1234 AddDnsRule("nx", dns_protocol::kTypeA, MockDnsClientRule::FAIL_ASYNC); | |
| 1235 AddDnsRule("nx", dns_protocol::kTypeAAAA, MockDnsClientRule::FAIL_ASYNC); | |
| 1236 AddDnsRule("ok", dns_protocol::kTypeA, MockDnsClientRule::OK); | |
| 1237 AddDnsRule("ok", dns_protocol::kTypeAAAA, MockDnsClientRule::OK); | |
| 1238 AddDnsRule("4ok", dns_protocol::kTypeA, MockDnsClientRule::OK); | |
| 1239 AddDnsRule("4ok", dns_protocol::kTypeAAAA, MockDnsClientRule::EMPTY); | |
| 1240 AddDnsRule("6ok", dns_protocol::kTypeA, MockDnsClientRule::EMPTY); | |
| 1241 AddDnsRule("6ok", dns_protocol::kTypeAAAA, MockDnsClientRule::OK); | |
| 1242 AddDnsRule("4nx", dns_protocol::kTypeA, MockDnsClientRule::OK); | |
| 1243 AddDnsRule("4nx", dns_protocol::kTypeAAAA, MockDnsClientRule::FAIL_ASYNC); | |
| 1244 CreateResolver(); | |
| 1245 } | |
| 1246 | |
| 1247 void CreateResolver() { | |
| 1248 resolver_.reset(new HostResolverImpl( | |
| 1249 HostCache::CreateDefaultCache(), | |
| 1250 DefaultLimits(), | |
| 1251 DefaultParams(proc_), | |
| 1252 NULL)); | |
| 1253 resolver_->SetDnsClient(CreateMockDnsClient(DnsConfig(), dns_rules_)); | |
| 1254 } | |
| 1255 | |
| 1256 // Adds a rule to |dns_rules_|. Must be followed by |CreateResolver| to apply. | |
| 1257 void AddDnsRule(const std::string& prefix, | |
| 1258 uint16 qtype, | |
| 1259 MockDnsClientRule::Result result) { | |
| 1260 dns_rules_.push_back(MockDnsClientRule(prefix, qtype, result)); | |
| 1261 } | |
| 1262 | |
| 1263 void ChangeDnsConfig(const DnsConfig& config) { | |
| 1264 NetworkChangeNotifier::SetDnsConfig(config); | |
| 1265 // Notification is delivered asynchronously. | |
| 1266 MessageLoop::current()->RunUntilIdle(); | |
| 1267 } | |
| 1268 | |
| 1269 MockDnsClientRuleList dns_rules_; | |
| 1270 }; | |
| 1271 | |
| 1272 // TODO(szym): Test AbortAllInProgressJobs due to DnsConfig change. | |
| 1273 | |
| 1274 // TODO(cbentzel): Test a mix of requests with different HostResolverFlags. | |
| 1275 | |
| 1276 // Test successful and fallback resolutions in HostResolverImpl::DnsTask. | |
| 1277 TEST_F(HostResolverImplDnsTest, DnsTask) { | |
| 1278 resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4); | |
| 1279 | |
| 1280 proc_->AddRuleForAllFamilies("er_succeed", "192.168.1.101"); | |
| 1281 proc_->AddRuleForAllFamilies("nx_succeed", "192.168.1.102"); | |
| 1282 // All other hostnames will fail in proc_. | |
| 1283 | |
| 1284 // Initially there is no config, so client should not be invoked. | |
| 1285 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok_fail", 80)->Resolve()); | |
| 1286 proc_->SignalMultiple(requests_.size()); | |
| 1287 | |
| 1288 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, requests_[0]->WaitForResult()); | |
| 1289 | |
| 1290 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1291 | |
| 1292 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok_fail", 80)->Resolve()); | |
| 1293 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("er_fail", 80)->Resolve()); | |
| 1294 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("nx_fail", 80)->Resolve()); | |
| 1295 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("er_succeed", 80)->Resolve()); | |
| 1296 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("nx_succeed", 80)->Resolve()); | |
| 1297 | |
| 1298 proc_->SignalMultiple(requests_.size()); | |
| 1299 | |
| 1300 for (size_t i = 1; i < requests_.size(); ++i) | |
| 1301 EXPECT_NE(ERR_UNEXPECTED, requests_[i]->WaitForResult()) << i; | |
| 1302 | |
| 1303 EXPECT_EQ(OK, requests_[1]->result()); | |
| 1304 // Resolved by MockDnsClient. | |
| 1305 EXPECT_TRUE(requests_[1]->HasOneAddress("127.0.0.1", 80)); | |
| 1306 // Fallback to ProcTask. | |
| 1307 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, requests_[2]->result()); | |
| 1308 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, requests_[3]->result()); | |
| 1309 EXPECT_EQ(OK, requests_[4]->result()); | |
| 1310 EXPECT_TRUE(requests_[4]->HasOneAddress("192.168.1.101", 80)); | |
| 1311 EXPECT_EQ(OK, requests_[5]->result()); | |
| 1312 EXPECT_TRUE(requests_[5]->HasOneAddress("192.168.1.102", 80)); | |
| 1313 } | |
| 1314 | |
| 1315 TEST_F(HostResolverImplDnsTest, DnsTaskUnspec) { | |
| 1316 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1317 | |
| 1318 proc_->AddRuleForAllFamilies("4nx", "192.168.1.101"); | |
| 1319 // All other hostnames will fail in proc_. | |
| 1320 | |
| 1321 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok", 80)->Resolve()); | |
| 1322 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("4ok", 80)->Resolve()); | |
| 1323 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("6ok", 80)->Resolve()); | |
| 1324 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("4nx", 80)->Resolve()); | |
| 1325 | |
| 1326 proc_->SignalMultiple(requests_.size()); | |
| 1327 | |
| 1328 for (size_t i = 0; i < requests_.size(); ++i) | |
| 1329 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1330 | |
| 1331 EXPECT_EQ(2u, requests_[0]->NumberOfAddresses()); | |
| 1332 EXPECT_TRUE(requests_[0]->HasAddress("127.0.0.1", 80)); | |
| 1333 EXPECT_TRUE(requests_[0]->HasAddress("::1", 80)); | |
| 1334 EXPECT_EQ(1u, requests_[1]->NumberOfAddresses()); | |
| 1335 EXPECT_TRUE(requests_[1]->HasAddress("127.0.0.1", 80)); | |
| 1336 EXPECT_EQ(1u, requests_[2]->NumberOfAddresses()); | |
| 1337 EXPECT_TRUE(requests_[2]->HasAddress("::1", 80)); | |
| 1338 EXPECT_EQ(1u, requests_[3]->NumberOfAddresses()); | |
| 1339 EXPECT_TRUE(requests_[3]->HasAddress("192.168.1.101", 80)); | |
| 1340 } | |
| 1341 | |
| 1342 TEST_F(HostResolverImplDnsTest, ServeFromHosts) { | |
| 1343 // Initially, use empty HOSTS file. | |
| 1344 DnsConfig config = CreateValidDnsConfig(); | |
| 1345 ChangeDnsConfig(config); | |
| 1346 | |
| 1347 proc_->AddRuleForAllFamilies("", ""); // Default to failures. | |
| 1348 proc_->SignalMultiple(1u); // For the first request which misses. | |
| 1349 | |
| 1350 Request* req0 = CreateRequest("er_ipv4", 80); | |
| 1351 EXPECT_EQ(ERR_IO_PENDING, req0->Resolve()); | |
| 1352 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req0->WaitForResult()); | |
| 1353 | |
| 1354 IPAddressNumber local_ipv4, local_ipv6; | |
| 1355 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &local_ipv4)); | |
| 1356 ASSERT_TRUE(ParseIPLiteralToNumber("::1", &local_ipv6)); | |
| 1357 | |
| 1358 DnsHosts hosts; | |
| 1359 hosts[DnsHostsKey("er_ipv4", ADDRESS_FAMILY_IPV4)] = local_ipv4; | |
| 1360 hosts[DnsHostsKey("er_ipv6", ADDRESS_FAMILY_IPV6)] = local_ipv6; | |
| 1361 hosts[DnsHostsKey("er_both", ADDRESS_FAMILY_IPV4)] = local_ipv4; | |
| 1362 hosts[DnsHostsKey("er_both", ADDRESS_FAMILY_IPV6)] = local_ipv6; | |
| 1363 | |
| 1364 // Update HOSTS file. | |
| 1365 config.hosts = hosts; | |
| 1366 ChangeDnsConfig(config); | |
| 1367 | |
| 1368 Request* req1 = CreateRequest("er_ipv4", 80); | |
| 1369 EXPECT_EQ(OK, req1->Resolve()); | |
| 1370 EXPECT_TRUE(req1->HasOneAddress("127.0.0.1", 80)); | |
| 1371 | |
| 1372 Request* req2 = CreateRequest("er_ipv6", 80); | |
| 1373 EXPECT_EQ(OK, req2->Resolve()); | |
| 1374 EXPECT_TRUE(req2->HasOneAddress("::1", 80)); | |
| 1375 | |
| 1376 Request* req3 = CreateRequest("er_both", 80); | |
| 1377 EXPECT_EQ(OK, req3->Resolve()); | |
| 1378 EXPECT_TRUE(req3->HasOneAddress("127.0.0.1", 80) || | |
| 1379 req3->HasOneAddress("::1", 80)); | |
| 1380 | |
| 1381 // Requests with specified AddressFamily. | |
| 1382 Request* req4 = CreateRequest("er_ipv4", 80, MEDIUM, ADDRESS_FAMILY_IPV4); | |
| 1383 EXPECT_EQ(OK, req4->Resolve()); | |
| 1384 EXPECT_TRUE(req4->HasOneAddress("127.0.0.1", 80)); | |
| 1385 | |
| 1386 Request* req5 = CreateRequest("er_ipv6", 80, MEDIUM, ADDRESS_FAMILY_IPV6); | |
| 1387 EXPECT_EQ(OK, req5->Resolve()); | |
| 1388 EXPECT_TRUE(req5->HasOneAddress("::1", 80)); | |
| 1389 | |
| 1390 // Request with upper case. | |
| 1391 Request* req6 = CreateRequest("er_IPV4", 80); | |
| 1392 EXPECT_EQ(OK, req6->Resolve()); | |
| 1393 EXPECT_TRUE(req6->HasOneAddress("127.0.0.1", 80)); | |
| 1394 } | |
| 1395 | |
| 1396 TEST_F(HostResolverImplDnsTest, BypassDnsTask) { | |
| 1397 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1398 | |
| 1399 proc_->AddRuleForAllFamilies("", ""); // Default to failures. | |
| 1400 | |
| 1401 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok.local", 80)->Resolve()); | |
| 1402 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok.local.", 80)->Resolve()); | |
| 1403 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("oklocal", 80)->Resolve()); | |
| 1404 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("oklocal.", 80)->Resolve()); | |
| 1405 EXPECT_EQ(ERR_IO_PENDING, CreateRequest("ok", 80)->Resolve()); | |
| 1406 | |
| 1407 proc_->SignalMultiple(requests_.size()); | |
| 1408 | |
| 1409 for (size_t i = 0; i < 2; ++i) | |
| 1410 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, requests_[i]->WaitForResult()) << i; | |
| 1411 | |
| 1412 for (size_t i = 2; i < requests_.size(); ++i) | |
| 1413 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1414 } | |
| 1415 | |
| 1416 TEST_F(HostResolverImplDnsTest, DisableDnsClientOnPersistentFailure) { | |
| 1417 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1418 | |
| 1419 proc_->AddRuleForAllFamilies("", ""); // Default to failures. | |
| 1420 | |
| 1421 // Check that DnsTask works. | |
| 1422 Request* req = CreateRequest("ok_1", 80); | |
| 1423 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 1424 EXPECT_EQ(OK, req->WaitForResult()); | |
| 1425 | |
| 1426 for (unsigned i = 0; i < 20; ++i) { | |
| 1427 // Use custom names to require separate Jobs. | |
| 1428 std::string hostname = base::StringPrintf("err_%u", i); | |
| 1429 // Ensure fallback to ProcTask succeeds. | |
| 1430 proc_->AddRuleForAllFamilies(hostname, "192.168.1.101"); | |
| 1431 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(hostname, 80)->Resolve()) << i; | |
| 1432 } | |
| 1433 | |
| 1434 proc_->SignalMultiple(requests_.size()); | |
| 1435 | |
| 1436 for (size_t i = 0; i < requests_.size(); ++i) | |
| 1437 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1438 | |
| 1439 ASSERT_FALSE(proc_->HasBlockedRequests()); | |
| 1440 | |
| 1441 // DnsTask should be disabled by now. | |
| 1442 req = CreateRequest("ok_2", 80); | |
| 1443 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 1444 proc_->SignalMultiple(1u); | |
| 1445 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req->WaitForResult()); | |
| 1446 | |
| 1447 // Check that it is re-enabled after DNS change. | |
| 1448 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1449 req = CreateRequest("ok_3", 80); | |
| 1450 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 1451 EXPECT_EQ(OK, req->WaitForResult()); | |
| 1452 } | |
| 1453 | |
| 1454 TEST_F(HostResolverImplDnsTest, DontDisableDnsClientOnSporadicFailure) { | |
| 1455 ChangeDnsConfig(CreateValidDnsConfig()); | |
| 1456 | |
| 1457 // |proc_| defaults to successes. | |
| 1458 | |
| 1459 // 20 failures interleaved with 20 successes. | |
| 1460 for (unsigned i = 0; i < 40; ++i) { | |
| 1461 // Use custom names to require separate Jobs. | |
| 1462 std::string hostname = (i % 2) == 0 ? base::StringPrintf("err_%u", i) | |
| 1463 : base::StringPrintf("ok_%u", i); | |
| 1464 EXPECT_EQ(ERR_IO_PENDING, CreateRequest(hostname, 80)->Resolve()) << i; | |
| 1465 } | |
| 1466 | |
| 1467 proc_->SignalMultiple(requests_.size()); | |
| 1468 | |
| 1469 for (size_t i = 0; i < requests_.size(); ++i) | |
| 1470 EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i; | |
| 1471 | |
| 1472 // Make |proc_| default to failures. | |
| 1473 proc_->AddRuleForAllFamilies("", ""); | |
| 1474 | |
| 1475 // DnsTask should still be enabled. | |
| 1476 Request* req = CreateRequest("ok_last", 80); | |
| 1477 EXPECT_EQ(ERR_IO_PENDING, req->Resolve()); | |
| 1478 EXPECT_EQ(OK, req->WaitForResult()); | |
| 1479 } | |
| 1480 | |
| 1481 } // namespace net | |
| OLD | NEW |