Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(881)

Side by Side Diff: net/base/host_resolver_unittest.cc

Issue 118100: Avoid doing concurrent DNS resolves of the same hostname (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Get compiling on mac Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/host_resolver.h" 5 #include "net/base/host_resolver.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <ws2tcpip.h> 8 #include <ws2tcpip.h>
9 #include <wspiapi.h> 9 #include <wspiapi.h>
10 #elif defined(OS_POSIX) 10 #elif defined(OS_POSIX)
11 #include <netdb.h> 11 #include <netdb.h>
12 #endif 12 #endif
13 13
14 #include <string> 14 #include <string>
15 15
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/ref_counted.h" 18 #include "base/ref_counted.h"
19 #include "net/base/address_list.h" 19 #include "net/base/address_list.h"
20 #include "net/base/completion_callback.h" 20 #include "net/base/completion_callback.h"
21 #include "net/base/host_resolver_unittest.h" 21 #include "net/base/host_resolver_unittest.h"
22 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
23 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
24 24
25 using net::RuleBasedHostMapper; 25 using net::RuleBasedHostMapper;
26 using net::ScopedHostMapper; 26 using net::ScopedHostMapper;
27 using net::WaitingHostMapper; 27 using net::WaitingHostMapper;
28 28
29 // TODO(eroman):
30 // - Test mixing async with sync (in particular how does sync update the
31 // cache while an async is already pending).
32
29 namespace { 33 namespace {
30 34
35 // A variant of WaitingHostMapper that pushes each host mapped into a list.
36 // (and uses a manual-reset event rather than auto-reset).
37 class CapturingHostMapper : public net::HostMapper {
38 public:
39 CapturingHostMapper() : event_(true, false) {
40 }
41
42 void Signal() {
43 event_.Signal();
44 }
45
46 virtual std::string Map(const std::string& host) {
47 event_.Wait();
48 {
49 AutoLock l(lock_);
50 capture_list_.push_back(host);
51 }
52 return MapUsingPrevious(host);
53 }
54
55 std::vector<std::string> GetCaptureList() const {
56 std::vector<std::string> copy;
57 {
58 AutoLock l(lock_);
59 copy = capture_list_;
60 }
61 return copy;
62 }
63
64 private:
65 std::vector<std::string> capture_list_;
66 mutable Lock lock_;
67 base::WaitableEvent event_;
68 };
69
70 // Helper that represents a single Resolve() result, used to inspect all the
71 // resolve results by forwarding them to Delegate.
72 class ResolveRequest {
73 public:
74 // Delegate interface, for notification when the ResolveRequest completes.
75 class Delegate {
76 public:
77 virtual ~Delegate() {}
78 virtual void OnCompleted(ResolveRequest* resolve) = 0;
79 };
80
81 ResolveRequest(net::HostResolver* resolver,
82 const std::string& hostname,
83 int port,
84 Delegate* delegate)
85 : hostname_(hostname), port_(port), resolver_(resolver),
86 delegate_(delegate),
87 ALLOW_THIS_IN_INITIALIZER_LIST(
88 callback_(this, &ResolveRequest::OnLookupFinished)) {
89 // Start the request.
90 int err = resolver->Resolve(hostname, port, &addrlist_, &callback_, &req_);
91 EXPECT_EQ(net::ERR_IO_PENDING, err);
92 }
93
94 void Cancel() {
95 resolver_->CancelRequest(req_);
96 }
97
98 const std::string& hostname() const {
99 return hostname_;
100 }
101
102 int port() const {
103 return port_;
104 }
105
106 int result() const {
107 return result_;
108 }
109
110 const net::AddressList& addrlist() const {
111 return addrlist_;
112 }
113
114 net::HostResolver* resolver() const {
115 return resolver_;
116 }
117
118 private:
119 void OnLookupFinished(int result) {
120 result_ = result;
121 delegate_->OnCompleted(this);
122 }
123
124 // The request details.
125 std::string hostname_;
126 int port_;
127 net::HostResolver::Request* req_;
128
129 // The result of the resolve.
130 int result_;
131 net::AddressList addrlist_;
132
133 net::HostResolver* resolver_;
134
135 Delegate* delegate_;
136 net::CompletionCallbackImpl<ResolveRequest> callback_;
137
138 DISALLOW_COPY_AND_ASSIGN(ResolveRequest);
139 };
140
31 class HostResolverTest : public testing::Test { 141 class HostResolverTest : public testing::Test {
32 public: 142 public:
33 HostResolverTest() 143 HostResolverTest()
34 : callback_called_(false), 144 : callback_called_(false),
35 ALLOW_THIS_IN_INITIALIZER_LIST( 145 ALLOW_THIS_IN_INITIALIZER_LIST(
36 callback_(this, &HostResolverTest::OnLookupFinished)) { 146 callback_(this, &HostResolverTest::OnLookupFinished)) {
37 } 147 }
38 148
39 protected: 149 protected:
40 bool callback_called_; 150 bool callback_called_;
(...skipping 10 matching lines...) Expand all
51 161
52 TEST_F(HostResolverTest, SynchronousLookup) { 162 TEST_F(HostResolverTest, SynchronousLookup) {
53 net::HostResolver host_resolver; 163 net::HostResolver host_resolver;
54 net::AddressList adrlist; 164 net::AddressList adrlist;
55 const int kPortnum = 80; 165 const int kPortnum = 80;
56 166
57 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); 167 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper();
58 mapper->AddRule("just.testing", "192.168.1.42"); 168 mapper->AddRule("just.testing", "192.168.1.42");
59 ScopedHostMapper scoped_mapper(mapper.get()); 169 ScopedHostMapper scoped_mapper(mapper.get());
60 170
61 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, NULL); 171 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, NULL,
172 NULL);
62 EXPECT_EQ(net::OK, err); 173 EXPECT_EQ(net::OK, err);
63 174
64 const struct addrinfo* ainfo = adrlist.head(); 175 const struct addrinfo* ainfo = adrlist.head();
65 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 176 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
66 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 177 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
67 178
68 const struct sockaddr* sa = ainfo->ai_addr; 179 const struct sockaddr* sa = ainfo->ai_addr;
69 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 180 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
70 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 181 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
71 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); 182 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr);
72 } 183 }
73 184
74 TEST_F(HostResolverTest, AsynchronousLookup) { 185 TEST_F(HostResolverTest, AsynchronousLookup) {
75 net::HostResolver host_resolver; 186 net::HostResolver host_resolver;
76 net::AddressList adrlist; 187 net::AddressList adrlist;
77 const int kPortnum = 80; 188 const int kPortnum = 80;
78 189
79 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); 190 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper();
80 mapper->AddRule("just.testing", "192.168.1.42"); 191 mapper->AddRule("just.testing", "192.168.1.42");
81 ScopedHostMapper scoped_mapper(mapper.get()); 192 ScopedHostMapper scoped_mapper(mapper.get());
82 193
83 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, 194 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist,
84 &callback_); 195 &callback_, NULL);
85 EXPECT_EQ(net::ERR_IO_PENDING, err); 196 EXPECT_EQ(net::ERR_IO_PENDING, err);
86 197
87 MessageLoop::current()->Run(); 198 MessageLoop::current()->Run();
88 199
89 ASSERT_TRUE(callback_called_); 200 ASSERT_TRUE(callback_called_);
90 ASSERT_EQ(net::OK, callback_result_); 201 ASSERT_EQ(net::OK, callback_result_);
91 202
92 const struct addrinfo* ainfo = adrlist.head(); 203 const struct addrinfo* ainfo = adrlist.head();
93 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 204 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
94 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 205 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
95 206
96 const struct sockaddr* sa = ainfo->ai_addr; 207 const struct sockaddr* sa = ainfo->ai_addr;
97 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 208 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
98 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 209 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
99 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr); 210 EXPECT_TRUE(htonl(0xc0a8012a) == sa_in->sin_addr.s_addr);
100 } 211 }
101 212
102 TEST_F(HostResolverTest, CanceledAsynchronousLookup) { 213 TEST_F(HostResolverTest, CanceledAsynchronousLookup) {
103 scoped_refptr<WaitingHostMapper> mapper = new WaitingHostMapper(); 214 scoped_refptr<WaitingHostMapper> mapper = new WaitingHostMapper();
104 ScopedHostMapper scoped_mapper(mapper.get()); 215 ScopedHostMapper scoped_mapper(mapper.get());
105 216
106 { 217 {
107 net::HostResolver host_resolver; 218 net::HostResolver host_resolver;
108 net::AddressList adrlist; 219 net::AddressList adrlist;
109 const int kPortnum = 80; 220 const int kPortnum = 80;
110 221
111 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, 222 int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist,
112 &callback_); 223 &callback_, NULL);
113 EXPECT_EQ(net::ERR_IO_PENDING, err); 224 EXPECT_EQ(net::ERR_IO_PENDING, err);
114 225
115 // Make sure we will exit the queue even when callback is not called. 226 // Make sure we will exit the queue even when callback is not called.
116 MessageLoop::current()->PostDelayedTask(FROM_HERE, 227 MessageLoop::current()->PostDelayedTask(FROM_HERE,
117 new MessageLoop::QuitTask(), 228 new MessageLoop::QuitTask(),
118 1000); 229 1000);
119 MessageLoop::current()->Run(); 230 MessageLoop::current()->Run();
120 } 231 }
121 232
122 mapper->Signal(); 233 mapper->Signal();
123 234
124 EXPECT_FALSE(callback_called_); 235 EXPECT_FALSE(callback_called_);
125 } 236 }
126 237
127 TEST_F(HostResolverTest, NumericIPv4Address) { 238 TEST_F(HostResolverTest, NumericIPv4Address) {
128 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in. 239 // Stevens says dotted quads with AI_UNSPEC resolve to a single sockaddr_in.
129 240
130 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); 241 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper();
131 mapper->AllowDirectLookup("*"); 242 mapper->AllowDirectLookup("*");
132 ScopedHostMapper scoped_mapper(mapper.get()); 243 ScopedHostMapper scoped_mapper(mapper.get());
133 244
134 net::HostResolver host_resolver; 245 net::HostResolver host_resolver;
135 net::AddressList adrlist; 246 net::AddressList adrlist;
136 const int kPortnum = 5555; 247 const int kPortnum = 5555;
137 int err = host_resolver.Resolve("127.1.2.3", kPortnum, &adrlist, NULL); 248 int err = host_resolver.Resolve("127.1.2.3", kPortnum, &adrlist, NULL, NULL);
138 EXPECT_EQ(net::OK, err); 249 EXPECT_EQ(net::OK, err);
139 250
140 const struct addrinfo* ainfo = adrlist.head(); 251 const struct addrinfo* ainfo = adrlist.head();
141 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 252 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
142 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); 253 EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen);
143 254
144 const struct sockaddr* sa = ainfo->ai_addr; 255 const struct sockaddr* sa = ainfo->ai_addr;
145 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; 256 const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa;
146 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port); 257 EXPECT_TRUE(htons(kPortnum) == sa_in->sin_port);
147 EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr); 258 EXPECT_TRUE(htonl(0x7f010203) == sa_in->sin_addr.s_addr);
148 } 259 }
149 260
150 TEST_F(HostResolverTest, NumericIPv6Address) { 261 TEST_F(HostResolverTest, NumericIPv6Address) {
151 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); 262 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper();
152 mapper->AllowDirectLookup("*"); 263 mapper->AllowDirectLookup("*");
153 ScopedHostMapper scoped_mapper(mapper.get()); 264 ScopedHostMapper scoped_mapper(mapper.get());
154 265
155 // Resolve a plain IPv6 address. Don't worry about [brackets], because 266 // Resolve a plain IPv6 address. Don't worry about [brackets], because
156 // the caller should have removed them. 267 // the caller should have removed them.
157 net::HostResolver host_resolver; 268 net::HostResolver host_resolver;
158 net::AddressList adrlist; 269 net::AddressList adrlist;
159 const int kPortnum = 5555; 270 const int kPortnum = 5555;
160 int err = host_resolver.Resolve("2001:db8::1", kPortnum, &adrlist, NULL); 271 int err = host_resolver.Resolve("2001:db8::1", kPortnum, &adrlist, NULL,
272 NULL);
161 // On computers without IPv6 support, getaddrinfo cannot convert IPv6 273 // On computers without IPv6 support, getaddrinfo cannot convert IPv6
162 // address literals to addresses (getaddrinfo returns EAI_NONAME). So this 274 // address literals to addresses (getaddrinfo returns EAI_NONAME). So this
163 // test has to allow host_resolver.Resolve to fail. 275 // test has to allow host_resolver.Resolve to fail.
164 if (err == net::ERR_NAME_NOT_RESOLVED) 276 if (err == net::ERR_NAME_NOT_RESOLVED)
165 return; 277 return;
166 EXPECT_EQ(net::OK, err); 278 EXPECT_EQ(net::OK, err);
167 279
168 const struct addrinfo* ainfo = adrlist.head(); 280 const struct addrinfo* ainfo = adrlist.head();
169 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next); 281 EXPECT_EQ(static_cast<addrinfo*>(NULL), ainfo->ai_next);
170 EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen); 282 EXPECT_EQ(sizeof(struct sockaddr_in6), ainfo->ai_addrlen);
(...skipping 12 matching lines...) Expand all
183 } 295 }
184 296
185 TEST_F(HostResolverTest, EmptyHost) { 297 TEST_F(HostResolverTest, EmptyHost) {
186 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper(); 298 scoped_refptr<RuleBasedHostMapper> mapper = new RuleBasedHostMapper();
187 mapper->AllowDirectLookup("*"); 299 mapper->AllowDirectLookup("*");
188 ScopedHostMapper scoped_mapper(mapper.get()); 300 ScopedHostMapper scoped_mapper(mapper.get());
189 301
190 net::HostResolver host_resolver; 302 net::HostResolver host_resolver;
191 net::AddressList adrlist; 303 net::AddressList adrlist;
192 const int kPortnum = 5555; 304 const int kPortnum = 5555;
193 int err = host_resolver.Resolve("", kPortnum, &adrlist, NULL); 305 int err = host_resolver.Resolve("", kPortnum, &adrlist, NULL, NULL);
194 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err); 306 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err);
195 } 307 }
196 308
309 // Helper class used by HostResolverTest.DeDupeRequests. It receives request
310 // completion notifications for all the resolves, so it can tally up and
311 // determine when we are done.
312 class DeDupeRequestsVerifier : public ResolveRequest::Delegate {
313 public:
314 explicit DeDupeRequestsVerifier(CapturingHostMapper* mapper)
315 : count_a_(0), count_b_(0), mapper_(mapper) {}
316
317 // The test does 5 resolves (which can complete in any order).
318 virtual void OnCompleted(ResolveRequest* resolve) {
319 // Tally up how many requests we have seen.
320 if (resolve->hostname() == "a") {
321 count_a_++;
322 } else if (resolve->hostname() == "b") {
323 count_b_++;
324 } else {
325 FAIL() << "Unexpected hostname: " << resolve->hostname();
326 }
327
328 // Check that the port was set correctly.
329 EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort());
330
331 // Check whether all the requests have finished yet.
332 int total_completions = count_a_ + count_b_;
333 if (total_completions == 5) {
334 EXPECT_EQ(2, count_a_);
335 EXPECT_EQ(3, count_b_);
336
337 // The mapper should have been called only twice -- once with "a", once
338 // with "b".
339 std::vector<std::string> capture_list = mapper_->GetCaptureList();
340 EXPECT_EQ(2U, capture_list.size());
341
342 // End this test, we are done.
343 MessageLoop::current()->Quit();
344 }
345 }
346
347 private:
348 int count_a_;
349 int count_b_;
350 CapturingHostMapper* mapper_;
351
352 DISALLOW_COPY_AND_ASSIGN(DeDupeRequestsVerifier);
353 };
354
355 TEST_F(HostResolverTest, DeDupeRequests) {
356 // Use a capturing mapper, since the verifier needs to know what calls
357 // reached Map(). Also, the capturing mapper is initially blocked.
358 scoped_refptr<CapturingHostMapper> mapper = new CapturingHostMapper();
359 ScopedHostMapper scoped_mapper(mapper.get());
360
361 net::HostResolver host_resolver;
362
363 // The class will receive callbacks for when each resolve completes. It
364 // checks that the right things happened.
365 DeDupeRequestsVerifier verifier(mapper.get());
366
367 // Start 5 requests, duplicating hosts "a" and "b". Since the mapper is
368 // blocked, these should all pile up until we signal it.
369
370 ResolveRequest req1(&host_resolver, "a", 80, &verifier);
371 ResolveRequest req2(&host_resolver, "b", 80, &verifier);
372 ResolveRequest req3(&host_resolver, "b", 81, &verifier);
373 ResolveRequest req4(&host_resolver, "a", 82, &verifier);
374 ResolveRequest req5(&host_resolver, "b", 83, &verifier);
375
376 // Ready, Set, GO!!!
377 mapper->Signal();
378
379 // |verifier| will send quit message once all the requests have finished.
380 MessageLoop::current()->Run();
381 }
382
383 // Helper class used by HostResolverTest.CancelMultipleRequests.
384 class CancelMultipleRequestsVerifier : public ResolveRequest::Delegate {
385 public:
386 CancelMultipleRequestsVerifier() {}
387
388 // The cancels kill all but one request.
389 virtual void OnCompleted(ResolveRequest* resolve) {
390 EXPECT_EQ("a", resolve->hostname());
391 EXPECT_EQ(82, resolve->port());
392
393 // Check that the port was set correctly.
394 EXPECT_EQ(resolve->port(), resolve->addrlist().GetPort());
395
396 // End this test, we are done.
397 MessageLoop::current()->Quit();
398 }
399
400 private:
401 DISALLOW_COPY_AND_ASSIGN(CancelMultipleRequestsVerifier);
402 };
403
404 TEST_F(HostResolverTest, CancelMultipleRequests) {
405 // Use a capturing mapper, since the verifier needs to know what calls
406 // reached Map(). Also, the capturing mapper is initially blocked.
407 scoped_refptr<CapturingHostMapper> mapper = new CapturingHostMapper();
408 ScopedHostMapper scoped_mapper(mapper.get());
409
410 net::HostResolver host_resolver;
411
412 // The class will receive callbacks for when each resolve completes. It
413 // checks that the right things happened.
414 CancelMultipleRequestsVerifier verifier;
415
416 // Start 5 requests, duplicating hosts "a" and "b". Since the mapper is
417 // blocked, these should all pile up until we signal it.
418
419 ResolveRequest req1(&host_resolver, "a", 80, &verifier);
420 ResolveRequest req2(&host_resolver, "b", 80, &verifier);
421 ResolveRequest req3(&host_resolver, "b", 81, &verifier);
422 ResolveRequest req4(&host_resolver, "a", 82, &verifier);
423 ResolveRequest req5(&host_resolver, "b", 83, &verifier);
424
425 // Cancel everything except request 4.
426 req1.Cancel();
427 req2.Cancel();
428 req3.Cancel();
429 req5.Cancel();
430
431 // Ready, Set, GO!!!
432 mapper->Signal();
433
434 // |verifier| will send quit message once all the requests have finished.
435 MessageLoop::current()->Run();
436 }
437
438 // Helper class used by HostResolverTest.CancelWithinCallback.
439 class CancelWithinCallbackVerifier : public ResolveRequest::Delegate {
440 public:
441 CancelWithinCallbackVerifier()
442 : req_to_cancel1_(NULL), req_to_cancel2_(NULL), num_completions_(0) {
443 }
444
445 virtual void OnCompleted(ResolveRequest* resolve) {
446 num_completions_++;
447
448 // Port 80 is the first request that the callback will be invoked for.
449 // While we are executing within that callback, cancel the other requests
450 // in the job and start another request.
451 if (80 == resolve->port()) {
452 EXPECT_EQ("a", resolve->hostname());
453
454 req_to_cancel1_->Cancel();
455 req_to_cancel2_->Cancel();
456
457 // Start a request (so we can make sure the canceled requests don't
458 // complete before "finalrequest" finishes.
459 final_request_.reset(new ResolveRequest(
460 resolve->resolver(), "finalrequest", 70, this));
461
462 } else if (83 == resolve->port()) {
463 EXPECT_EQ("a", resolve->hostname());
464 } else if (resolve->hostname() == "finalrequest") {
465 EXPECT_EQ(70, resolve->addrlist().GetPort());
466
467 // End this test, we are done.
468 MessageLoop::current()->Quit();
469 } else {
470 FAIL() << "Unexpected completion: " << resolve->hostname() << ", "
471 << resolve->port();
472 }
473 }
474
475 void SetRequestsToCancel(ResolveRequest* req_to_cancel1,
476 ResolveRequest* req_to_cancel2) {
477 req_to_cancel1_ = req_to_cancel1;
478 req_to_cancel2_ = req_to_cancel2;
479 }
480
481 private:
482 scoped_ptr<ResolveRequest> final_request_;
483 ResolveRequest* req_to_cancel1_;
484 ResolveRequest* req_to_cancel2_;
485 int num_completions_;
486 DISALLOW_COPY_AND_ASSIGN(CancelWithinCallbackVerifier);
487 };
488
489 TEST_F(HostResolverTest, CancelWithinCallback) {
490 // Use a capturing mapper, since the verifier needs to know what calls
491 // reached Map(). Also, the capturing mapper is initially blocked.
492 scoped_refptr<CapturingHostMapper> mapper = new CapturingHostMapper();
493 ScopedHostMapper scoped_mapper(mapper.get());
494
495 net::HostResolver host_resolver;
496
497 // The class will receive callbacks for when each resolve completes. It
498 // checks that the right things happened.
499 CancelWithinCallbackVerifier verifier;
500
501 // Start 4 requests, duplicating hosts "a". Since the mapper is
502 // blocked, these should all pile up until we signal it.
503
504 ResolveRequest req1(&host_resolver, "a", 80, &verifier);
505 ResolveRequest req2(&host_resolver, "a", 81, &verifier);
506 ResolveRequest req3(&host_resolver, "a", 82, &verifier);
507 ResolveRequest req4(&host_resolver, "a", 83, &verifier);
508
509 // Once "a:80" completes, it will cancel "a:81" and "a:82".
510 verifier.SetRequestsToCancel(&req2, &req3);
511
512 // Ready, Set, GO!!!
513 mapper->Signal();
514
515 // |verifier| will send quit message once all the requests have finished.
516 MessageLoop::current()->Run();
517 }
518
519 // Helper class used by HostResolverTest.DeleteWithinCallback.
520 class DeleteWithinCallbackVerifier : public ResolveRequest::Delegate {
521 public:
522 DeleteWithinCallbackVerifier() {}
523
524 virtual void OnCompleted(ResolveRequest* resolve) {
525 EXPECT_EQ("a", resolve->hostname());
526 EXPECT_EQ(80, resolve->port());
527 delete resolve->resolver();
528
529 // Quit after returning from OnCompleted (to give it a chance at
530 // incorrectly running the cancelled tasks).
531 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
532 }
533
534 private:
535 DISALLOW_COPY_AND_ASSIGN(DeleteWithinCallbackVerifier);
536 };
537
538 TEST_F(HostResolverTest, DeleteWithinCallback) {
539 // Use a capturing mapper, since the verifier needs to know what calls
540 // reached Map(). Also, the capturing mapper is initially blocked.
541 scoped_refptr<CapturingHostMapper> mapper = new CapturingHostMapper();
542 ScopedHostMapper scoped_mapper(mapper.get());
543
544 // This should be deleted by DeleteWithinCallbackVerifier -- if it leaks
545 // then the test has failed.
546 net::HostResolver* host_resolver = new net::HostResolver;
547
548 // The class will receive callbacks for when each resolve completes. It
549 // checks that the right things happened.
550 DeleteWithinCallbackVerifier verifier;
551
552 // Start 4 requests, duplicating hosts "a". Since the mapper is
553 // blocked, these should all pile up until we signal it.
554
555 ResolveRequest req1(host_resolver, "a", 80, &verifier);
556 ResolveRequest req2(host_resolver, "a", 81, &verifier);
557 ResolveRequest req3(host_resolver, "a", 82, &verifier);
558 ResolveRequest req4(host_resolver, "a", 83, &verifier);
559
560 // Ready, Set, GO!!!
561 mapper->Signal();
562
563 // |verifier| will send quit message once all the requests have finished.
564 MessageLoop::current()->Run();
565 }
566
567 // Helper class used by HostResolverTest.StartWithinCallback.
568 class StartWithinCallbackVerifier : public ResolveRequest::Delegate {
569 public:
570 StartWithinCallbackVerifier() : num_requests_(0) {}
571
572 virtual void OnCompleted(ResolveRequest* resolve) {
573 EXPECT_EQ("a", resolve->hostname());
574
575 if (80 == resolve->port()) {
576 // On completing the first request, start another request for "a".
577 // Since caching is disabled, this will result in another async request.
578 final_request_.reset(new ResolveRequest(
579 resolve->resolver(), "a", 70, this));
580 }
581 if (++num_requests_ == 5) {
582 // Test is done.
583 MessageLoop::current()->Quit();
584 }
585 }
586
587 private:
588 int num_requests_;
589 scoped_ptr<ResolveRequest> final_request_;
590 DISALLOW_COPY_AND_ASSIGN(StartWithinCallbackVerifier);
591 };
592
593 TEST_F(HostResolverTest, StartWithinCallback) {
594 // Use a capturing mapper, since the verifier needs to know what calls
595 // reached Map(). Also, the capturing mapper is initially blocked.
596 scoped_refptr<CapturingHostMapper> mapper = new CapturingHostMapper();
597 ScopedHostMapper scoped_mapper(mapper.get());
598
599 // Turn off caching for this host resolver.
600 net::HostResolver host_resolver(0, 0);
601
602 // The class will receive callbacks for when each resolve completes. It
603 // checks that the right things happened.
604 StartWithinCallbackVerifier verifier;
605
606 // Start 4 requests, duplicating hosts "a". Since the mapper is
607 // blocked, these should all pile up until we signal it.
608
609 ResolveRequest req1(&host_resolver, "a", 80, &verifier);
610 ResolveRequest req2(&host_resolver, "a", 81, &verifier);
611 ResolveRequest req3(&host_resolver, "a", 82, &verifier);
612 ResolveRequest req4(&host_resolver, "a", 83, &verifier);
613
614 // Ready, Set, GO!!!
615 mapper->Signal();
616
617 // |verifier| will send quit message once all the requests have finished.
618 MessageLoop::current()->Run();
619 }
620
197 } // namespace 621 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698