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

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

Issue 125107: * Move the global "DnsResolutionObserver" code depended on by DNS prefetcher,... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Address jar's comments 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
« no previous file with comments | « net/base/tcp_client_socket_pool.cc ('k') | net/base/tcp_client_socket_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/tcp_client_socket_pool.h" 5 #include "net/base/tcp_client_socket_pool.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "net/base/client_socket.h" 9 #include "net/base/client_socket.h"
10 #include "net/base/client_socket_factory.h" 10 #include "net/base/client_socket_factory.h"
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 ScopedHostMapper scoped_host_mapper_; 225 ScopedHostMapper scoped_host_mapper_;
226 HostResolver host_resolver_; 226 HostResolver host_resolver_;
227 MockClientSocketFactory client_socket_factory_; 227 MockClientSocketFactory client_socket_factory_;
228 scoped_refptr<ClientSocketPool> pool_; 228 scoped_refptr<ClientSocketPool> pool_;
229 std::vector<TestSocketRequest*> request_order_; 229 std::vector<TestSocketRequest*> request_order_;
230 }; 230 };
231 231
232 TEST_F(TCPClientSocketPoolTest, Basic) { 232 TEST_F(TCPClientSocketPoolTest, Basic) {
233 TestCompletionCallback callback; 233 TestCompletionCallback callback;
234 ClientSocketHandle handle(pool_.get()); 234 ClientSocketHandle handle(pool_.get());
235 int rv = handle.Init("a", "www.google.com", 80, 0, &callback); 235 HostResolver::RequestInfo info("www.google.com", 80);
236 int rv = handle.Init("a", info, 0, &callback);
236 EXPECT_EQ(ERR_IO_PENDING, rv); 237 EXPECT_EQ(ERR_IO_PENDING, rv);
237 EXPECT_FALSE(handle.is_initialized()); 238 EXPECT_FALSE(handle.is_initialized());
238 EXPECT_FALSE(handle.socket()); 239 EXPECT_FALSE(handle.socket());
239 240
240 EXPECT_EQ(OK, callback.WaitForResult()); 241 EXPECT_EQ(OK, callback.WaitForResult());
241 EXPECT_TRUE(handle.is_initialized()); 242 EXPECT_TRUE(handle.is_initialized());
242 EXPECT_TRUE(handle.socket()); 243 EXPECT_TRUE(handle.socket());
243 244
244 handle.Reset(); 245 handle.Reset();
245 246
246 // The handle's Reset method may have posted a task. 247 // The handle's Reset method may have posted a task.
247 MessageLoop::current()->RunAllPending(); 248 MessageLoop::current()->RunAllPending();
248 } 249 }
249 250
250 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) { 251 TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) {
251 RuleBasedHostMapper* host_mapper = new RuleBasedHostMapper; 252 RuleBasedHostMapper* host_mapper = new RuleBasedHostMapper;
252 host_mapper->AddSimulatedFailure("unresolvable.host.name"); 253 host_mapper->AddSimulatedFailure("unresolvable.host.name");
253 ScopedHostMapper scoped_host_mapper(host_mapper); 254 ScopedHostMapper scoped_host_mapper(host_mapper);
254 TestSocketRequest req(pool_.get(), &request_order_); 255 TestSocketRequest req(pool_.get(), &request_order_);
255 EXPECT_EQ(ERR_IO_PENDING, 256 HostResolver::RequestInfo info("unresolvable.host.name", 80);
256 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req)); 257 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
257 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult()); 258 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult());
258 } 259 }
259 260
260 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) { 261 TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) {
261 client_socket_factory_.set_client_socket_type( 262 client_socket_factory_.set_client_socket_type(
262 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); 263 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
263 TestSocketRequest req(pool_.get(), &request_order_); 264 TestSocketRequest req(pool_.get(), &request_order_);
265 HostResolver::RequestInfo info("unresolvable.host.name", 80);
264 EXPECT_EQ(ERR_IO_PENDING, 266 EXPECT_EQ(ERR_IO_PENDING,
265 req.handle.Init("a", "unresolvable.host.name", 80, 5, &req)); 267 req.handle.Init("a", info, 5, &req));
266 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult()); 268 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
267 } 269 }
268 270
269 TEST_F(TCPClientSocketPoolTest, PendingRequests) { 271 TEST_F(TCPClientSocketPoolTest, PendingRequests) {
270 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 272 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
271 273
272 for (size_t i = 0; i < arraysize(reqs); ++i) 274 for (size_t i = 0; i < arraysize(reqs); ++i)
273 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 275 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
274 276
275 // Create connections or queue up requests. 277 // Create connections or queue up requests.
276 278
277 // First request finishes asynchronously. 279 // First request finishes asynchronously.
278 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); 280 HostResolver::RequestInfo info("www.google.com", 80);
281 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
279 EXPECT_EQ(ERR_IO_PENDING, rv); 282 EXPECT_EQ(ERR_IO_PENDING, rv);
280 EXPECT_EQ(OK, reqs[0]->WaitForResult()); 283 EXPECT_EQ(OK, reqs[0]->WaitForResult());
281 284
282 // Rest of them finish synchronously, since they're in the HostCache. 285 // Rest of them finish synchronously, since they're in the HostCache.
283 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { 286 for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
284 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); 287 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
285 EXPECT_EQ(OK, rv); 288 EXPECT_EQ(OK, rv);
286 request_order_.push_back(reqs[i].get()); 289 request_order_.push_back(reqs[i].get());
287 } 290 }
288 291
289 // The rest are pending since we've used all active sockets. 292 // The rest are pending since we've used all active sockets.
290 for (int i = 0; i < kNumPendingRequests; ++i) { 293 for (int i = 0; i < kNumPendingRequests; ++i) {
291 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( 294 rv = reqs[kMaxSocketsPerGroup + i]->handle.Init(
292 "a", "www.google.com", 80, kPriorities[i], 295 "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get());
293 reqs[kMaxSocketsPerGroup + i].get());
294 EXPECT_EQ(ERR_IO_PENDING, rv); 296 EXPECT_EQ(ERR_IO_PENDING, rv);
295 } 297 }
296 298
297 // Release any connections until we have no connections. 299 // Release any connections until we have no connections.
298 bool released_one; 300 bool released_one;
299 do { 301 do {
300 released_one = false; 302 released_one = false;
301 for (size_t i = 0; i < arraysize(reqs); ++i) { 303 for (size_t i = 0; i < arraysize(reqs); ++i) {
302 if (reqs[i]->handle.is_initialized()) { 304 if (reqs[i]->handle.is_initialized()) {
303 reqs[i]->handle.Reset(); 305 reqs[i]->handle.Reset();
(...skipping 25 matching lines...) Expand all
329 } 331 }
330 332
331 TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) { 333 TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
332 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 334 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
333 for (size_t i = 0; i < arraysize(reqs); ++i) 335 for (size_t i = 0; i < arraysize(reqs); ++i)
334 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 336 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
335 337
336 // Create connections or queue up requests. 338 // Create connections or queue up requests.
337 339
338 // First request finishes asynchronously. 340 // First request finishes asynchronously.
339 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); 341 HostResolver::RequestInfo info("www.google.com", 80);
342 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
340 EXPECT_EQ(ERR_IO_PENDING, rv); 343 EXPECT_EQ(ERR_IO_PENDING, rv);
341 EXPECT_EQ(OK, reqs[0]->WaitForResult()); 344 EXPECT_EQ(OK, reqs[0]->WaitForResult());
342 345
343 // Rest of them finish synchronously, since they're in the HostCache. 346 // Rest of them finish synchronously, since they're in the HostCache.
344 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { 347 for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
345 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); 348 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
346 EXPECT_EQ(OK, rv); 349 EXPECT_EQ(OK, rv);
347 request_order_.push_back(reqs[i].get()); 350 request_order_.push_back(reqs[i].get());
348 } 351 }
349 352
350 // The rest are pending since we've used all active sockets. 353 // The rest are pending since we've used all active sockets.
351 for (int i = 0; i < kNumPendingRequests; ++i) { 354 for (int i = 0; i < kNumPendingRequests; ++i) {
352 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( 355 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
353 "a", "www.google.com", 80, 0, reqs[kMaxSocketsPerGroup + i].get())); 356 "a", info, 0, reqs[kMaxSocketsPerGroup + i].get()));
354 } 357 }
355 358
356 // Release any connections until we have no connections. 359 // Release any connections until we have no connections.
357 bool released_one; 360 bool released_one;
358 do { 361 do {
359 released_one = false; 362 released_one = false;
360 for (size_t i = 0; i < arraysize(reqs); ++i) { 363 for (size_t i = 0; i < arraysize(reqs); ++i) {
361 if (reqs[i]->handle.is_initialized()) { 364 if (reqs[i]->handle.is_initialized()) {
362 reqs[i]->handle.socket()->Disconnect(); // No keep alive. 365 reqs[i]->handle.socket()->Disconnect(); // No keep alive.
363 reqs[i]->handle.Reset(); 366 reqs[i]->handle.Reset();
364 MessageLoop::current()->RunAllPending(); 367 MessageLoop::current()->RunAllPending();
365 released_one = true; 368 released_one = true;
366 } 369 }
367 } 370 }
368 } while (released_one); 371 } while (released_one);
369 372
370 for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i) 373 for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i)
371 EXPECT_EQ(OK, reqs[i]->WaitForResult()); 374 EXPECT_EQ(OK, reqs[i]->WaitForResult());
372 375
373 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count()); 376 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count());
374 EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count); 377 EXPECT_EQ(kNumPendingRequests + 1, TestSocketRequest::completion_count);
375 } 378 }
376 379
377 // This test will start up a RequestSocket() and then immediately Cancel() it. 380 // This test will start up a RequestSocket() and then immediately Cancel() it.
378 // The pending host resolution will eventually complete, and destroy the 381 // The pending host resolution will eventually complete, and destroy the
379 // ClientSocketPool which will crash if the group was not cleared properly. 382 // ClientSocketPool which will crash if the group was not cleared properly.
380 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) { 383 TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) {
381 TestSocketRequest req(pool_.get(), &request_order_); 384 TestSocketRequest req(pool_.get(), &request_order_);
382 EXPECT_EQ(ERR_IO_PENDING, 385 HostResolver::RequestInfo info("www.google.com", 80);
383 req.handle.Init("a", "www.google.com", 80, 5, &req)); 386 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
384 req.handle.Reset(); 387 req.handle.Reset();
385 388
386 PlatformThread::Sleep(100); 389 PlatformThread::Sleep(100);
387 390
388 // There is a race condition here. If the worker pool doesn't post the task 391 // There is a race condition here. If the worker pool doesn't post the task
389 // before we get here, then this might not run ConnectingSocket::OnIOComplete 392 // before we get here, then this might not run ConnectingSocket::OnIOComplete
390 // and therefore leak the canceled ConnectingSocket. However, other tests 393 // and therefore leak the canceled ConnectingSocket. However, other tests
391 // after this will call MessageLoop::RunAllPending() which should prevent a 394 // after this will call MessageLoop::RunAllPending() which should prevent a
392 // leak, unless the worker thread takes longer than all of them. 395 // leak, unless the worker thread takes longer than all of them.
393 MessageLoop::current()->RunAllPending(); 396 MessageLoop::current()->RunAllPending();
394 } 397 }
395 398
396 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) { 399 TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) {
397 TestSocketRequest req(pool_.get(), &request_order_); 400 TestSocketRequest req(pool_.get(), &request_order_);
398 TestSocketRequest req2(pool_.get(), &request_order_); 401 TestSocketRequest req2(pool_.get(), &request_order_);
399 402
400 EXPECT_EQ(ERR_IO_PENDING, 403 HostResolver::RequestInfo info("www.google.com", 80);
401 req.handle.Init("a", "www.google.com", 80, 5, &req)); 404 EXPECT_EQ(ERR_IO_PENDING, req.handle.Init("a", info, 5, &req));
402 EXPECT_EQ(ERR_IO_PENDING, 405 EXPECT_EQ(ERR_IO_PENDING, req2.handle.Init("a", info, 5, &req2));
403 req2.handle.Init("a", "www.google.com", 80, 5, &req2));
404 406
405 req.handle.Reset(); 407 req.handle.Reset();
406 408
407 EXPECT_EQ(OK, req2.WaitForResult()); 409 EXPECT_EQ(OK, req2.WaitForResult());
408 req2.handle.Reset(); 410 req2.handle.Reset();
409 // The handle's Reset method may have posted a task. 411 // The handle's Reset method may have posted a task.
410 MessageLoop::current()->RunAllPending(); 412 MessageLoop::current()->RunAllPending();
411 } 413 }
412 414
413 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) { 415 TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) {
414 client_socket_factory_.set_client_socket_type( 416 client_socket_factory_.set_client_socket_type(
415 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); 417 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
416 ClientSocketHandle handle(pool_.get()); 418 ClientSocketHandle handle(pool_.get());
417 TestCompletionCallback callback; 419 TestCompletionCallback callback;
418 TestSocketRequest req(pool_.get(), &request_order_); 420 TestSocketRequest req(pool_.get(), &request_order_);
419 421
420 EXPECT_EQ(ERR_IO_PENDING, 422 HostResolver::RequestInfo info("www.google.com", 80);
421 handle.Init("a", "www.google.com", 80, 5, &callback)); 423 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback));
422 424
423 handle.Reset(); 425 handle.Reset();
424 426
425 TestCompletionCallback callback2; 427 TestCompletionCallback callback2;
426 EXPECT_EQ(ERR_IO_PENDING, 428 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", info, 5, &callback2));
427 handle.Init("a", "www.google.com", 80, 5, &callback2));
428 429
429 // At this point, handle has two ConnectingSockets out for it. Due to the 430 // At this point, handle has two ConnectingSockets out for it. Due to the
430 // host cache, the host resolution for both will return in the same loop of 431 // host cache, the host resolution for both will return in the same loop of
431 // the MessageLoop. The client socket is a pending socket, so the Connect() 432 // the MessageLoop. The client socket is a pending socket, so the Connect()
432 // will asynchronously complete on the next loop of the MessageLoop. That 433 // will asynchronously complete on the next loop of the MessageLoop. That
433 // means that the first ConnectingSocket will enter OnIOComplete, and then the 434 // means that the first ConnectingSocket will enter OnIOComplete, and then the
434 // second one will. If the first one is not cancelled, it will advance the 435 // second one will. If the first one is not cancelled, it will advance the
435 // load state, and then the second one will crash. 436 // load state, and then the second one will crash.
436 437
437 EXPECT_EQ(OK, callback2.WaitForResult()); 438 EXPECT_EQ(OK, callback2.WaitForResult());
438 EXPECT_FALSE(callback.have_result()); 439 EXPECT_FALSE(callback.have_result());
439 440
440 handle.Reset(); 441 handle.Reset();
441 // The handle's Reset method may have posted a task. 442 // The handle's Reset method may have posted a task.
442 MessageLoop::current()->RunAllPending(); 443 MessageLoop::current()->RunAllPending();
443 } 444 }
444 445
445 TEST_F(TCPClientSocketPoolTest, CancelRequest) { 446 TEST_F(TCPClientSocketPoolTest, CancelRequest) {
446 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 447 scoped_ptr<TestSocketRequest> reqs[kNumRequests];
447 448
448 for (size_t i = 0; i < arraysize(reqs); ++i) 449 for (size_t i = 0; i < arraysize(reqs); ++i)
449 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 450 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
450 451
451 // Create connections or queue up requests. 452 // Create connections or queue up requests.
453 HostResolver::RequestInfo info("www.google.com", 80);
452 454
453 // First request finishes asynchronously. 455 // First request finishes asynchronously.
454 int rv = reqs[0]->handle.Init("a", "www.google.com", 80, 5, reqs[0].get()); 456 int rv = reqs[0]->handle.Init("a", info, 5, reqs[0].get());
455 EXPECT_EQ(ERR_IO_PENDING, rv); 457 EXPECT_EQ(ERR_IO_PENDING, rv);
456 EXPECT_EQ(OK, reqs[0]->WaitForResult()); 458 EXPECT_EQ(OK, reqs[0]->WaitForResult());
457 459
458 // Rest of them finish synchronously, since they're in the HostCache. 460 // Rest of them finish synchronously, since they're in the HostCache.
459 for (int i = 1; i < kMaxSocketsPerGroup; ++i) { 461 for (int i = 1; i < kMaxSocketsPerGroup; ++i) {
460 rv = reqs[i]->handle.Init("a", "www.google.com", 80, 5, reqs[i].get()); 462 rv = reqs[i]->handle.Init("a", info, 5, reqs[i].get());
461 EXPECT_EQ(OK, rv); 463 EXPECT_EQ(OK, rv);
462 request_order_.push_back(reqs[i].get()); 464 request_order_.push_back(reqs[i].get());
463 } 465 }
464 466
465 // The rest are pending since we've used all active sockets. 467 // The rest are pending since we've used all active sockets.
466 for (int i = 0; i < kNumPendingRequests; ++i) { 468 for (int i = 0; i < kNumPendingRequests; ++i) {
467 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init( 469 EXPECT_EQ(ERR_IO_PENDING, reqs[kMaxSocketsPerGroup + i]->handle.Init(
468 "a", "www.google.com", 80, kPriorities[i], 470 "a", info, kPriorities[i], reqs[kMaxSocketsPerGroup + i].get()));
469 reqs[kMaxSocketsPerGroup + i].get()));
470 } 471 }
471 472
472 // Cancel a request. 473 // Cancel a request.
473 size_t index_to_cancel = kMaxSocketsPerGroup + 2; 474 size_t index_to_cancel = kMaxSocketsPerGroup + 2;
474 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized()); 475 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized());
475 reqs[index_to_cancel]->handle.Reset(); 476 reqs[index_to_cancel]->handle.Reset();
476 477
477 // Release any connections until we have no connections. 478 // Release any connections until we have no connections.
478 bool released_one; 479 bool released_one;
479 do { 480 do {
(...skipping 27 matching lines...) Expand all
507 508
508 EXPECT_EQ(request_order_[arraysize(reqs) - 2], 509 EXPECT_EQ(request_order_[arraysize(reqs) - 2],
509 reqs[arraysize(reqs) - 1].get()) << 510 reqs[arraysize(reqs) - 1].get()) <<
510 "The last request with priority 1 should not have been inserted " 511 "The last request with priority 1 should not have been inserted "
511 "earlier into the queue."; 512 "earlier into the queue.";
512 } 513 }
513 514
514 } // namespace 515 } // namespace
515 516
516 } // namespace net 517 } // namespace net
OLDNEW
« no previous file with comments | « net/base/tcp_client_socket_pool.cc ('k') | net/base/tcp_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698