1// Copyright 2014 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/socket/websocket_transport_client_socket_pool.h" 6 7#include <queue> 8#include <vector> 9 10#include "base/bind.h" 11#include "base/bind_helpers.h" 12#include "base/callback.h" 13#include "base/macros.h" 14#include "base/message_loop/message_loop.h" 15#include "base/run_loop.h" 16#include "base/strings/stringprintf.h" 17#include "base/time/time.h" 18#include "net/base/capturing_net_log.h" 19#include "net/base/ip_endpoint.h" 20#include "net/base/load_timing_info.h" 21#include "net/base/load_timing_info_test_util.h" 22#include "net/base/net_errors.h" 23#include "net/base/net_util.h" 24#include "net/base/test_completion_callback.h" 25#include "net/dns/mock_host_resolver.h" 26#include "net/socket/client_socket_handle.h" 27#include "net/socket/client_socket_pool_histograms.h" 28#include "net/socket/socket_test_util.h" 29#include "net/socket/stream_socket.h" 30#include "net/socket/transport_client_socket_pool_test_util.h" 31#include "net/socket/websocket_endpoint_lock_manager.h" 32#include "testing/gtest/include/gtest/gtest.h" 33 34namespace net { 35 36namespace { 37 38const int kMaxSockets = 32; 39const int kMaxSocketsPerGroup = 6; 40const RequestPriority kDefaultPriority = LOW; 41 42// RunLoop doesn't support this natively but it is easy to emulate. 43void RunLoopForTimePeriod(base::TimeDelta period) { 44 base::RunLoop run_loop; 45 base::Closure quit_closure(run_loop.QuitClosure()); 46 base::MessageLoop::current()->PostDelayedTask( 47 FROM_HERE, quit_closure, period); 48 run_loop.Run(); 49} 50 51class WebSocketTransportClientSocketPoolTest : public testing::Test { 52 protected: 53 WebSocketTransportClientSocketPoolTest() 54 : params_(new TransportSocketParams( 55 HostPortPair("www.google.com", 80), 56 false, 57 false, 58 OnHostResolutionCallback(), 59 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), 60 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), 61 host_resolver_(new MockHostResolver), 62 client_socket_factory_(&net_log_), 63 pool_(kMaxSockets, 64 kMaxSocketsPerGroup, 65 histograms_.get(), 66 host_resolver_.get(), 67 &client_socket_factory_, 68 NULL) {} 69 70 virtual ~WebSocketTransportClientSocketPoolTest() { 71 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE); 72 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty()); 73 } 74 75 int StartRequest(const std::string& group_name, RequestPriority priority) { 76 scoped_refptr<TransportSocketParams> params( 77 new TransportSocketParams( 78 HostPortPair("www.google.com", 80), 79 false, 80 false, 81 OnHostResolutionCallback(), 82 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 83 return test_base_.StartRequestUsingPool( 84 &pool_, group_name, priority, params); 85 } 86 87 int GetOrderOfRequest(size_t index) { 88 return test_base_.GetOrderOfRequest(index); 89 } 90 91 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) { 92 return test_base_.ReleaseOneConnection(keep_alive); 93 } 94 95 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) { 96 test_base_.ReleaseAllConnections(keep_alive); 97 } 98 99 TestSocketRequest* request(int i) { return test_base_.request(i); } 100 101 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); } 102 size_t completion_count() const { return test_base_.completion_count(); } 103 104 CapturingNetLog net_log_; 105 scoped_refptr<TransportSocketParams> params_; 106 scoped_ptr<ClientSocketPoolHistograms> histograms_; 107 scoped_ptr<MockHostResolver> host_resolver_; 108 MockTransportClientSocketFactory client_socket_factory_; 109 WebSocketTransportClientSocketPool pool_; 110 ClientSocketPoolTest test_base_; 111 112 private: 113 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest); 114}; 115 116TEST_F(WebSocketTransportClientSocketPoolTest, Basic) { 117 TestCompletionCallback callback; 118 ClientSocketHandle handle; 119 int rv = handle.Init( 120 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog()); 121 EXPECT_EQ(ERR_IO_PENDING, rv); 122 EXPECT_FALSE(handle.is_initialized()); 123 EXPECT_FALSE(handle.socket()); 124 125 EXPECT_EQ(OK, callback.WaitForResult()); 126 EXPECT_TRUE(handle.is_initialized()); 127 EXPECT_TRUE(handle.socket()); 128 TestLoadTimingInfoConnectedNotReused(handle); 129} 130 131// Make sure that WebSocketTransportConnectJob passes on its priority to its 132// HostResolver request on Init. 133TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) { 134 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { 135 RequestPriority priority = static_cast<RequestPriority>(i); 136 TestCompletionCallback callback; 137 ClientSocketHandle handle; 138 EXPECT_EQ(ERR_IO_PENDING, 139 handle.Init("a", 140 params_, 141 priority, 142 callback.callback(), 143 &pool_, 144 BoundNetLog())); 145 EXPECT_EQ(priority, host_resolver_->last_request_priority()); 146 } 147} 148 149TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) { 150 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name"); 151 TestCompletionCallback callback; 152 ClientSocketHandle handle; 153 HostPortPair host_port_pair("unresolvable.host.name", 80); 154 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( 155 host_port_pair, false, false, OnHostResolutionCallback(), 156 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 157 EXPECT_EQ(ERR_IO_PENDING, 158 handle.Init("a", 159 dest, 160 kDefaultPriority, 161 callback.callback(), 162 &pool_, 163 BoundNetLog())); 164 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult()); 165} 166 167TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) { 168 client_socket_factory_.set_default_client_socket_type( 169 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET); 170 TestCompletionCallback callback; 171 ClientSocketHandle handle; 172 EXPECT_EQ(ERR_IO_PENDING, 173 handle.Init("a", 174 params_, 175 kDefaultPriority, 176 callback.callback(), 177 &pool_, 178 BoundNetLog())); 179 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); 180 181 // Make the host resolutions complete synchronously this time. 182 host_resolver_->set_synchronous_mode(true); 183 EXPECT_EQ(ERR_CONNECTION_FAILED, 184 handle.Init("a", 185 params_, 186 kDefaultPriority, 187 callback.callback(), 188 &pool_, 189 BoundNetLog())); 190} 191 192TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) { 193 // First request finishes asynchronously. 194 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 195 EXPECT_EQ(OK, request(0)->WaitForResult()); 196 197 // Make all subsequent host resolutions complete synchronously. 198 host_resolver_->set_synchronous_mode(true); 199 200 // Rest of them wait for the first socket to be released. 201 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 202 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 203 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 204 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 205 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 206 207 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE); 208 209 EXPECT_EQ(6, client_socket_factory_.allocation_count()); 210 211 // One initial asynchronous request and then 5 pending requests. 212 EXPECT_EQ(6U, completion_count()); 213 214 // The requests finish in FIFO order. 215 EXPECT_EQ(1, GetOrderOfRequest(1)); 216 EXPECT_EQ(2, GetOrderOfRequest(2)); 217 EXPECT_EQ(3, GetOrderOfRequest(3)); 218 EXPECT_EQ(4, GetOrderOfRequest(4)); 219 EXPECT_EQ(5, GetOrderOfRequest(5)); 220 EXPECT_EQ(6, GetOrderOfRequest(6)); 221 222 // Make sure we test order of all requests made. 223 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7)); 224} 225 226TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) { 227 // First request finishes asynchronously. 228 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 229 EXPECT_EQ(OK, request(0)->WaitForResult()); 230 231 // Make all subsequent host resolutions complete synchronously. 232 host_resolver_->set_synchronous_mode(true); 233 234 // Rest of them wait for the first socket to be released. 235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 238 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 239 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 240 241 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE); 242 243 // The pending requests should finish successfully. 244 EXPECT_EQ(OK, request(1)->WaitForResult()); 245 EXPECT_EQ(OK, request(2)->WaitForResult()); 246 EXPECT_EQ(OK, request(3)->WaitForResult()); 247 EXPECT_EQ(OK, request(4)->WaitForResult()); 248 EXPECT_EQ(OK, request(5)->WaitForResult()); 249 250 EXPECT_EQ(static_cast<int>(requests()->size()), 251 client_socket_factory_.allocation_count()); 252 253 // First asynchronous request, and then last 5 pending requests. 254 EXPECT_EQ(6U, completion_count()); 255} 256 257// This test will start up a RequestSocket() and then immediately Cancel() it. 258// The pending host resolution will eventually complete, and destroy the 259// ClientSocketPool which will crash if the group was not cleared properly. 260TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) { 261 TestCompletionCallback callback; 262 ClientSocketHandle handle; 263 EXPECT_EQ(ERR_IO_PENDING, 264 handle.Init("a", 265 params_, 266 kDefaultPriority, 267 callback.callback(), 268 &pool_, 269 BoundNetLog())); 270 handle.Reset(); 271} 272 273TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) { 274 ClientSocketHandle handle; 275 TestCompletionCallback callback; 276 ClientSocketHandle handle2; 277 TestCompletionCallback callback2; 278 279 EXPECT_EQ(ERR_IO_PENDING, 280 handle.Init("a", 281 params_, 282 kDefaultPriority, 283 callback.callback(), 284 &pool_, 285 BoundNetLog())); 286 EXPECT_EQ(ERR_IO_PENDING, 287 handle2.Init("a", 288 params_, 289 kDefaultPriority, 290 callback2.callback(), 291 &pool_, 292 BoundNetLog())); 293 294 handle.Reset(); 295 296 EXPECT_EQ(OK, callback2.WaitForResult()); 297 handle2.Reset(); 298} 299 300TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) { 301 client_socket_factory_.set_default_client_socket_type( 302 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); 303 ClientSocketHandle handle; 304 TestCompletionCallback callback; 305 EXPECT_EQ(ERR_IO_PENDING, 306 handle.Init("a", 307 params_, 308 kDefaultPriority, 309 callback.callback(), 310 &pool_, 311 BoundNetLog())); 312 313 handle.Reset(); 314 315 TestCompletionCallback callback2; 316 EXPECT_EQ(ERR_IO_PENDING, 317 handle.Init("a", 318 params_, 319 kDefaultPriority, 320 callback2.callback(), 321 &pool_, 322 BoundNetLog())); 323 324 host_resolver_->set_synchronous_mode(true); 325 // At this point, handle has two ConnectingSockets out for it. Due to the 326 // setting the mock resolver into synchronous mode, the host resolution for 327 // both will return in the same loop of the MessageLoop. The client socket 328 // is a pending socket, so the Connect() will asynchronously complete on the 329 // next loop of the MessageLoop. That means that the first 330 // ConnectingSocket will enter OnIOComplete, and then the second one will. 331 // If the first one is not cancelled, it will advance the load state, and 332 // then the second one will crash. 333 334 EXPECT_EQ(OK, callback2.WaitForResult()); 335 EXPECT_FALSE(callback.have_result()); 336 337 handle.Reset(); 338} 339 340TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) { 341 // First request finishes asynchronously. 342 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 343 EXPECT_EQ(OK, request(0)->WaitForResult()); 344 345 // Make all subsequent host resolutions complete synchronously. 346 host_resolver_->set_synchronous_mode(true); 347 348 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 349 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 350 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 351 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 352 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 353 354 // Cancel a request. 355 const size_t index_to_cancel = 2; 356 EXPECT_FALSE(request(index_to_cancel)->handle()->is_initialized()); 357 request(index_to_cancel)->handle()->Reset(); 358 359 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE); 360 361 EXPECT_EQ(5, client_socket_factory_.allocation_count()); 362 363 EXPECT_EQ(1, GetOrderOfRequest(1)); 364 EXPECT_EQ(2, GetOrderOfRequest(2)); 365 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, 366 GetOrderOfRequest(3)); // Canceled request. 367 EXPECT_EQ(3, GetOrderOfRequest(4)); 368 EXPECT_EQ(4, GetOrderOfRequest(5)); 369 EXPECT_EQ(5, GetOrderOfRequest(6)); 370 371 // Make sure we test order of all requests made. 372 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7)); 373} 374 375class RequestSocketCallback : public TestCompletionCallbackBase { 376 public: 377 RequestSocketCallback(ClientSocketHandle* handle, 378 WebSocketTransportClientSocketPool* pool) 379 : handle_(handle), 380 pool_(pool), 381 within_callback_(false), 382 callback_(base::Bind(&RequestSocketCallback::OnComplete, 383 base::Unretained(this))) {} 384 385 virtual ~RequestSocketCallback() {} 386 387 const CompletionCallback& callback() const { return callback_; } 388 389 private: 390 void OnComplete(int result) { 391 SetResult(result); 392 ASSERT_EQ(OK, result); 393 394 if (!within_callback_) { 395 // Don't allow reuse of the socket. Disconnect it and then release it and 396 // run through the MessageLoop once to get it completely released. 397 handle_->socket()->Disconnect(); 398 handle_->Reset(); 399 { 400 base::MessageLoop::ScopedNestableTaskAllower allow( 401 base::MessageLoop::current()); 402 base::MessageLoop::current()->RunUntilIdle(); 403 } 404 within_callback_ = true; 405 scoped_refptr<TransportSocketParams> dest( 406 new TransportSocketParams( 407 HostPortPair("www.google.com", 80), 408 false, 409 false, 410 OnHostResolutionCallback(), 411 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 412 int rv = 413 handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog()); 414 EXPECT_EQ(OK, rv); 415 } 416 } 417 418 ClientSocketHandle* const handle_; 419 WebSocketTransportClientSocketPool* const pool_; 420 bool within_callback_; 421 CompletionCallback callback_; 422 423 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback); 424}; 425 426TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) { 427 ClientSocketHandle handle; 428 RequestSocketCallback callback(&handle, &pool_); 429 scoped_refptr<TransportSocketParams> dest( 430 new TransportSocketParams( 431 HostPortPair("www.google.com", 80), 432 false, 433 false, 434 OnHostResolutionCallback(), 435 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); 436 int rv = handle.Init( 437 "a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog()); 438 ASSERT_EQ(ERR_IO_PENDING, rv); 439 440 // The callback is going to request "www.google.com". We want it to complete 441 // synchronously this time. 442 host_resolver_->set_synchronous_mode(true); 443 444 EXPECT_EQ(OK, callback.WaitForResult()); 445 446 handle.Reset(); 447} 448 449// Make sure that pending requests get serviced after active requests get 450// cancelled. 451TEST_F(WebSocketTransportClientSocketPoolTest, 452 CancelActiveRequestWithPendingRequests) { 453 client_socket_factory_.set_default_client_socket_type( 454 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET); 455 456 // Queue up all the requests 457 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 458 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 459 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 460 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 461 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 462 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 463 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 464 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 465 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 466 467 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them. 468 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size())); 469 for (int i = 0; i < kMaxSocketsPerGroup; i++) 470 request(i)->handle()->Reset(); 471 472 // Let's wait for the rest to complete now. 473 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) { 474 EXPECT_EQ(OK, request(i)->WaitForResult()); 475 request(i)->handle()->Reset(); 476 } 477 478 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count()); 479} 480 481// Make sure that pending requests get serviced after active requests fail. 482TEST_F(WebSocketTransportClientSocketPoolTest, 483 FailingActiveRequestWithPendingRequests) { 484 client_socket_factory_.set_default_client_socket_type( 485 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET); 486 487 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1; 488 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang. 489 490 // Queue up all the requests 491 for (int i = 0; i < kNumRequests; i++) 492 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 493 494 for (int i = 0; i < kNumRequests; i++) 495 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult()); 496} 497 498// The lock on the endpoint is released when a ClientSocketHandle is reset. 499TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) { 500 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 501 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 502 EXPECT_EQ(OK, request(0)->WaitForResult()); 503 EXPECT_FALSE(request(1)->handle()->is_initialized()); 504 request(0)->handle()->Reset(); 505 base::RunLoop().RunUntilIdle(); 506 EXPECT_TRUE(request(1)->handle()->is_initialized()); 507} 508 509// The lock on the endpoint is released when a ClientSocketHandle is deleted. 510TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) { 511 TestCompletionCallback callback; 512 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle); 513 int rv = handle->Init( 514 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog()); 515 EXPECT_EQ(ERR_IO_PENDING, rv); 516 517 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 518 EXPECT_EQ(OK, callback.WaitForResult()); 519 EXPECT_FALSE(request(0)->handle()->is_initialized()); 520 handle.reset(); 521 base::RunLoop().RunUntilIdle(); 522 EXPECT_TRUE(request(0)->handle()->is_initialized()); 523} 524 525// A new connection is performed when the lock on the previous connection is 526// explicitly released. 527TEST_F(WebSocketTransportClientSocketPoolTest, 528 ConnectionProceedsOnExplicitRelease) { 529 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 530 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 531 EXPECT_EQ(OK, request(0)->WaitForResult()); 532 EXPECT_FALSE(request(1)->handle()->is_initialized()); 533 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle()); 534 base::RunLoop().RunUntilIdle(); 535 EXPECT_TRUE(request(1)->handle()->is_initialized()); 536} 537 538// A connection which is cancelled before completion does not block subsequent 539// connections. 540TEST_F(WebSocketTransportClientSocketPoolTest, 541 CancelDuringConnectionReleasesLock) { 542 MockTransportClientSocketFactory::ClientSocketType case_types[] = { 543 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, 544 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET}; 545 546 client_socket_factory_.set_client_socket_types(case_types, 547 arraysize(case_types)); 548 549 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 550 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 551 base::RunLoop().RunUntilIdle(); 552 pool_.CancelRequest("a", request(0)->handle()); 553 EXPECT_EQ(OK, request(1)->WaitForResult()); 554} 555 556// Test the case of the IPv6 address stalling, and falling back to the IPv4 557// socket which finishes first. 558TEST_F(WebSocketTransportClientSocketPoolTest, 559 IPv6FallbackSocketIPv4FinishesFirst) { 560 WebSocketTransportClientSocketPool pool(kMaxSockets, 561 kMaxSocketsPerGroup, 562 histograms_.get(), 563 host_resolver_.get(), 564 &client_socket_factory_, 565 NULL); 566 567 MockTransportClientSocketFactory::ClientSocketType case_types[] = { 568 // This is the IPv6 socket. 569 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, 570 // This is the IPv4 socket. 571 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET}; 572 573 client_socket_factory_.set_client_socket_types(case_types, 2); 574 575 // Resolve an AddressList with an IPv6 address first and then an IPv4 address. 576 host_resolver_->rules()->AddIPLiteralRule( 577 "*", "2:abcd::3:4:ff,2.2.2.2", std::string()); 578 579 TestCompletionCallback callback; 580 ClientSocketHandle handle; 581 int rv = 582 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 583 EXPECT_EQ(ERR_IO_PENDING, rv); 584 EXPECT_FALSE(handle.is_initialized()); 585 EXPECT_FALSE(handle.socket()); 586 587 EXPECT_EQ(OK, callback.WaitForResult()); 588 EXPECT_TRUE(handle.is_initialized()); 589 EXPECT_TRUE(handle.socket()); 590 IPEndPoint endpoint; 591 handle.socket()->GetLocalAddress(&endpoint); 592 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size()); 593 EXPECT_EQ(2, client_socket_factory_.allocation_count()); 594} 595 596// Test the case of the IPv6 address being slow, thus falling back to trying to 597// connect to the IPv4 address, but having the connect to the IPv6 address 598// finish first. 599TEST_F(WebSocketTransportClientSocketPoolTest, 600 IPv6FallbackSocketIPv6FinishesFirst) { 601 WebSocketTransportClientSocketPool pool(kMaxSockets, 602 kMaxSocketsPerGroup, 603 histograms_.get(), 604 host_resolver_.get(), 605 &client_socket_factory_, 606 NULL); 607 608 MockTransportClientSocketFactory::ClientSocketType case_types[] = { 609 // This is the IPv6 socket. 610 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET, 611 // This is the IPv4 socket. 612 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET}; 613 614 client_socket_factory_.set_client_socket_types(case_types, 2); 615 client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds( 616 TransportConnectJobHelper::kIPv6FallbackTimerInMs + 50)); 617 618 // Resolve an AddressList with an IPv6 address first and then an IPv4 address. 619 host_resolver_->rules()->AddIPLiteralRule( 620 "*", "2:abcd::3:4:ff,2.2.2.2", std::string()); 621 622 TestCompletionCallback callback; 623 ClientSocketHandle handle; 624 int rv = 625 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 626 EXPECT_EQ(ERR_IO_PENDING, rv); 627 EXPECT_FALSE(handle.is_initialized()); 628 EXPECT_FALSE(handle.socket()); 629 630 EXPECT_EQ(OK, callback.WaitForResult()); 631 EXPECT_TRUE(handle.is_initialized()); 632 EXPECT_TRUE(handle.socket()); 633 IPEndPoint endpoint; 634 handle.socket()->GetLocalAddress(&endpoint); 635 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size()); 636 EXPECT_EQ(2, client_socket_factory_.allocation_count()); 637} 638 639TEST_F(WebSocketTransportClientSocketPoolTest, 640 IPv6NoIPv4AddressesToFallbackTo) { 641 WebSocketTransportClientSocketPool pool(kMaxSockets, 642 kMaxSocketsPerGroup, 643 histograms_.get(), 644 host_resolver_.get(), 645 &client_socket_factory_, 646 NULL); 647 648 client_socket_factory_.set_default_client_socket_type( 649 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); 650 651 // Resolve an AddressList with only IPv6 addresses. 652 host_resolver_->rules()->AddIPLiteralRule( 653 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string()); 654 655 TestCompletionCallback callback; 656 ClientSocketHandle handle; 657 int rv = 658 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 659 EXPECT_EQ(ERR_IO_PENDING, rv); 660 EXPECT_FALSE(handle.is_initialized()); 661 EXPECT_FALSE(handle.socket()); 662 663 EXPECT_EQ(OK, callback.WaitForResult()); 664 EXPECT_TRUE(handle.is_initialized()); 665 EXPECT_TRUE(handle.socket()); 666 IPEndPoint endpoint; 667 handle.socket()->GetLocalAddress(&endpoint); 668 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size()); 669 EXPECT_EQ(1, client_socket_factory_.allocation_count()); 670} 671 672TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) { 673 WebSocketTransportClientSocketPool pool(kMaxSockets, 674 kMaxSocketsPerGroup, 675 histograms_.get(), 676 host_resolver_.get(), 677 &client_socket_factory_, 678 NULL); 679 680 client_socket_factory_.set_default_client_socket_type( 681 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); 682 683 // Resolve an AddressList with only IPv4 addresses. 684 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string()); 685 686 TestCompletionCallback callback; 687 ClientSocketHandle handle; 688 int rv = 689 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 690 EXPECT_EQ(ERR_IO_PENDING, rv); 691 EXPECT_FALSE(handle.is_initialized()); 692 EXPECT_FALSE(handle.socket()); 693 694 EXPECT_EQ(OK, callback.WaitForResult()); 695 EXPECT_TRUE(handle.is_initialized()); 696 EXPECT_TRUE(handle.socket()); 697 IPEndPoint endpoint; 698 handle.socket()->GetLocalAddress(&endpoint); 699 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size()); 700 EXPECT_EQ(1, client_socket_factory_.allocation_count()); 701} 702 703// If all IPv6 addresses fail to connect synchronously, then IPv4 connections 704// proceeed immediately. 705TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) { 706 WebSocketTransportClientSocketPool pool(kMaxSockets, 707 kMaxSocketsPerGroup, 708 histograms_.get(), 709 host_resolver_.get(), 710 &client_socket_factory_, 711 NULL); 712 713 MockTransportClientSocketFactory::ClientSocketType case_types[] = { 714 // First IPv6 socket. 715 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET, 716 // Second IPv6 socket. 717 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET, 718 // This is the IPv4 socket. 719 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET}; 720 721 client_socket_factory_.set_client_socket_types(case_types, 722 arraysize(case_types)); 723 724 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address. 725 host_resolver_->rules()->AddIPLiteralRule( 726 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string()); 727 host_resolver_->set_synchronous_mode(true); 728 TestCompletionCallback callback; 729 ClientSocketHandle handle; 730 int rv = 731 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 732 EXPECT_EQ(OK, rv); 733 ASSERT_TRUE(handle.socket()); 734 735 IPEndPoint endpoint; 736 handle.socket()->GetPeerAddress(&endpoint); 737 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort()); 738} 739 740// If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4 741// connections proceed immediately. 742TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) { 743 WebSocketTransportClientSocketPool pool(kMaxSockets, 744 kMaxSocketsPerGroup, 745 histograms_.get(), 746 host_resolver_.get(), 747 &client_socket_factory_, 748 NULL); 749 750 MockTransportClientSocketFactory::ClientSocketType case_types[] = { 751 // First IPv6 socket. 752 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET, 753 // Second IPv6 socket. 754 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET, 755 // This is the IPv4 socket. 756 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET}; 757 758 client_socket_factory_.set_client_socket_types(case_types, 759 arraysize(case_types)); 760 761 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address. 762 host_resolver_->rules()->AddIPLiteralRule( 763 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string()); 764 765 TestCompletionCallback callback; 766 ClientSocketHandle handle; 767 int rv = 768 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 769 EXPECT_EQ(ERR_IO_PENDING, rv); 770 EXPECT_FALSE(handle.socket()); 771 772 base::Time start(base::Time::NowFromSystemTime()); 773 EXPECT_EQ(OK, callback.WaitForResult()); 774 EXPECT_LT(base::Time::NowFromSystemTime() - start, 775 base::TimeDelta::FromMilliseconds( 776 TransportConnectJobHelper::kIPv6FallbackTimerInMs)); 777 ASSERT_TRUE(handle.socket()); 778 779 IPEndPoint endpoint; 780 handle.socket()->GetPeerAddress(&endpoint); 781 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort()); 782} 783 784// If two sockets connect successfully, the one which connected first wins (this 785// can only happen if the sockets are different types, since sockets of the same 786// type do not race). 787TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) { 788 WebSocketTransportClientSocketPool pool(kMaxSockets, 789 kMaxSocketsPerGroup, 790 histograms_.get(), 791 host_resolver_.get(), 792 &client_socket_factory_, 793 NULL); 794 795 client_socket_factory_.set_default_client_socket_type( 796 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET); 797 798 // Resolve an AddressList with an IPv6 addresses and an IPv4 address. 799 host_resolver_->rules()->AddIPLiteralRule( 800 "*", "2:abcd::3:4:ff,2.2.2.2", std::string()); 801 802 TestCompletionCallback callback; 803 ClientSocketHandle handle; 804 int rv = 805 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 806 EXPECT_EQ(ERR_IO_PENDING, rv); 807 ASSERT_FALSE(handle.socket()); 808 809 base::Closure ipv6_connect_trigger = 810 client_socket_factory_.WaitForTriggerableSocketCreation(); 811 base::Closure ipv4_connect_trigger = 812 client_socket_factory_.WaitForTriggerableSocketCreation(); 813 814 ipv4_connect_trigger.Run(); 815 ipv6_connect_trigger.Run(); 816 817 EXPECT_EQ(OK, callback.WaitForResult()); 818 ASSERT_TRUE(handle.socket()); 819 820 IPEndPoint endpoint; 821 handle.socket()->GetPeerAddress(&endpoint); 822 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort()); 823} 824 825// We should not report failure until all connections have failed. 826TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) { 827 WebSocketTransportClientSocketPool pool(kMaxSockets, 828 kMaxSocketsPerGroup, 829 histograms_.get(), 830 host_resolver_.get(), 831 &client_socket_factory_, 832 NULL); 833 834 client_socket_factory_.set_default_client_socket_type( 835 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET); 836 base::TimeDelta delay = base::TimeDelta::FromMilliseconds( 837 TransportConnectJobHelper::kIPv6FallbackTimerInMs / 3); 838 client_socket_factory_.set_delay(delay); 839 840 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses. 841 host_resolver_->rules()->AddIPLiteralRule("*", 842 "1:abcd::3:4:ff,2:abcd::3:4:ff," 843 "3:abcd::3:4:ff,4:abcd::3:4:ff," 844 "1.1.1.1,2.2.2.2", 845 std::string()); 846 847 // Expected order of events: 848 // After 100ms: Connect to 1:abcd::3:4:ff times out 849 // After 200ms: Connect to 2:abcd::3:4:ff times out 850 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts 851 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out 852 // After 500ms: Connect to 2.2.2.2 times out 853 854 TestCompletionCallback callback; 855 ClientSocketHandle handle; 856 base::Time start(base::Time::NowFromSystemTime()); 857 int rv = 858 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 859 EXPECT_EQ(ERR_IO_PENDING, rv); 860 861 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); 862 863 EXPECT_GE(base::Time::NowFromSystemTime() - start, delay * 5); 864} 865 866// Global timeout for all connects applies. This test is disabled by default 867// because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you 868// want to run it. 869TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) { 870 WebSocketTransportClientSocketPool pool(kMaxSockets, 871 kMaxSocketsPerGroup, 872 histograms_.get(), 873 host_resolver_.get(), 874 &client_socket_factory_, 875 NULL); 876 const base::TimeDelta connect_job_timeout = pool.ConnectionTimeout(); 877 878 client_socket_factory_.set_default_client_socket_type( 879 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET); 880 client_socket_factory_.set_delay(base::TimeDelta::FromSeconds(1) + 881 connect_job_timeout / 6); 882 883 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 addresses. 884 host_resolver_->rules()->AddIPLiteralRule("*", 885 "1:abcd::3:4:ff,2:abcd::3:4:ff," 886 "3:abcd::3:4:ff,4:abcd::3:4:ff," 887 "5:abcd::3:4:ff,6:abcd::3:4:ff," 888 "1.1.1.1,2.2.2.2,3.3.3.3," 889 "4.4.4.4,5.5.5.5,6.6.6.6", 890 std::string()); 891 892 TestCompletionCallback callback; 893 ClientSocketHandle handle; 894 895 int rv = 896 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog()); 897 EXPECT_EQ(ERR_IO_PENDING, rv); 898 899 EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult()); 900} 901 902TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) { 903 host_resolver_->set_synchronous_mode(true); 904 for (int i = 0; i < kMaxSockets; ++i) { 905 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 906 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle()); 907 } 908 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 909} 910 911TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) { 912 for (int i = 0; i < kMaxSockets + 1; ++i) { 913 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 914 } 915 // Now there are 32 sockets waiting to connect, and one stalled. 916 for (int i = 0; i < kMaxSockets; ++i) { 917 base::RunLoop().RunUntilIdle(); 918 EXPECT_TRUE(request(i)->handle()->is_initialized()); 919 EXPECT_TRUE(request(i)->handle()->socket()); 920 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle()); 921 } 922 // Now there are 32 sockets connected, and one stalled. 923 base::RunLoop().RunUntilIdle(); 924 EXPECT_FALSE(request(kMaxSockets)->handle()->is_initialized()); 925 EXPECT_FALSE(request(kMaxSockets)->handle()->socket()); 926} 927 928TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) { 929 host_resolver_->set_synchronous_mode(true); 930 for (int i = 0; i < kMaxSockets; ++i) { 931 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 932 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle()); 933 } 934 935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 936 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE); 937 EXPECT_TRUE(request(kMaxSockets)->handle()->is_initialized()); 938 EXPECT_TRUE(request(kMaxSockets)->handle()->socket()); 939} 940 941TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) { 942 for (int i = 0; i < kMaxSockets + 1; ++i) { 943 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 944 } 945 EXPECT_EQ(OK, request(0)->WaitForResult()); 946 EXPECT_TRUE(pool_.IsStalled()); 947} 948 949TEST_F(WebSocketTransportClientSocketPoolTest, 950 CancellingPendingSocketUnstallsStalledSocket) { 951 for (int i = 0; i < kMaxSockets + 1; ++i) { 952 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 953 } 954 EXPECT_EQ(OK, request(0)->WaitForResult()); 955 request(1)->handle()->Reset(); 956 base::RunLoop().RunUntilIdle(); 957 EXPECT_FALSE(pool_.IsStalled()); 958} 959 960TEST_F(WebSocketTransportClientSocketPoolTest, 961 LoadStateOfStalledSocketIsWaitingForAvailableSocket) { 962 for (int i = 0; i < kMaxSockets + 1; ++i) { 963 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 964 } 965 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, 966 pool_.GetLoadState("a", request(kMaxSockets)->handle())); 967} 968 969TEST_F(WebSocketTransportClientSocketPoolTest, 970 CancellingStalledSocketUnstallsPool) { 971 for (int i = 0; i < kMaxSockets + 1; ++i) { 972 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 973 } 974 request(kMaxSockets)->handle()->Reset(); 975 EXPECT_FALSE(pool_.IsStalled()); 976} 977 978TEST_F(WebSocketTransportClientSocketPoolTest, 979 FlushWithErrorFlushesPendingConnections) { 980 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 981 pool_.FlushWithError(ERR_FAILED); 982 EXPECT_EQ(ERR_FAILED, request(0)->WaitForResult()); 983} 984 985TEST_F(WebSocketTransportClientSocketPoolTest, 986 FlushWithErrorFlushesStalledConnections) { 987 for (int i = 0; i < kMaxSockets + 1; ++i) { 988 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 989 } 990 pool_.FlushWithError(ERR_FAILED); 991 EXPECT_EQ(ERR_FAILED, request(kMaxSockets)->WaitForResult()); 992} 993 994TEST_F(WebSocketTransportClientSocketPoolTest, 995 AfterFlushWithErrorCanMakeNewConnections) { 996 for (int i = 0; i < kMaxSockets + 1; ++i) { 997 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 998 } 999 pool_.FlushWithError(ERR_FAILED); 1000 host_resolver_->set_synchronous_mode(true); 1001 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 1002} 1003 1004// Deleting pending connections can release the lock on the endpoint, which can 1005// in principle lead to other pending connections succeeding. However, when we 1006// call FlushWithError(), everything should fail. 1007TEST_F(WebSocketTransportClientSocketPoolTest, 1008 FlushWithErrorDoesNotCauseSuccessfulConnections) { 1009 host_resolver_->set_synchronous_mode(true); 1010 MockTransportClientSocketFactory::ClientSocketType first_type[] = { 1011 // First socket 1012 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET 1013 }; 1014 client_socket_factory_.set_client_socket_types(first_type, 1015 arraysize(first_type)); 1016 // The rest of the sockets will connect synchronously. 1017 client_socket_factory_.set_default_client_socket_type( 1018 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET); 1019 for (int i = 0; i < kMaxSockets; ++i) { 1020 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1021 } 1022 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in 1023 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the 1024 // lock, they will synchronously connect. 1025 pool_.FlushWithError(ERR_FAILED); 1026 for (int i = 0; i < kMaxSockets; ++i) { 1027 EXPECT_EQ(ERR_FAILED, request(i)->WaitForResult()); 1028 } 1029} 1030 1031// This is a regression test for the first attempted fix for 1032// FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can 1033// have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for 1034// the lock at the same time. 1035TEST_F(WebSocketTransportClientSocketPoolTest, 1036 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes) { 1037 host_resolver_->set_synchronous_mode(true); 1038 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have 1039 // one IPv4. 1040 std::vector<MockTransportClientSocketFactory::ClientSocketType> socket_types( 1041 kMaxSockets + 1, 1042 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET); 1043 client_socket_factory_.set_client_socket_types(&socket_types[0], 1044 socket_types.size()); 1045 // The rest of the sockets will connect synchronously. 1046 client_socket_factory_.set_default_client_socket_type( 1047 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET); 1048 for (int i = 0; i < kMaxSockets; ++i) { 1049 host_resolver_->rules()->ClearRules(); 1050 // Each connect job has a different IPv6 address but the same IPv4 address. 1051 // So the IPv6 connections happen in parallel but the IPv4 ones are 1052 // serialised. 1053 host_resolver_->rules()->AddIPLiteralRule("*", 1054 base::StringPrintf( 1055 "%x:abcd::3:4:ff," 1056 "1.1.1.1", 1057 i + 1), 1058 std::string()); 1059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1060 } 1061 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets 1062 // are started yet. 1063 RunLoopForTimePeriod(base::TimeDelta::FromMilliseconds( 1064 TransportConnectJobHelper::kIPv6FallbackTimerInMs)); 1065 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in 1066 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock. 1067 pool_.FlushWithError(ERR_FAILED); 1068 for (int i = 0; i < kMaxSockets; ++i) { 1069 EXPECT_EQ(ERR_FAILED, request(i)->WaitForResult()); 1070 } 1071} 1072 1073// Sockets that have had ownership transferred to a ClientSocketHandle should 1074// not be affected by FlushWithError. 1075TEST_F(WebSocketTransportClientSocketPoolTest, 1076 FlushWithErrorDoesNotAffectHandedOutSockets) { 1077 host_resolver_->set_synchronous_mode(true); 1078 MockTransportClientSocketFactory::ClientSocketType socket_types[] = { 1079 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET, 1080 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET}; 1081 client_socket_factory_.set_client_socket_types(socket_types, 1082 arraysize(socket_types)); 1083 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 1084 // Socket has been "handed out". 1085 EXPECT_TRUE(request(0)->handle()->socket()); 1086 1087 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1088 // Now we have one socket handed out, and one pending. 1089 pool_.FlushWithError(ERR_FAILED); 1090 EXPECT_EQ(ERR_FAILED, request(1)->WaitForResult()); 1091 // Socket owned by ClientSocketHandle is unaffected: 1092 EXPECT_TRUE(request(0)->handle()->socket()); 1093 // Return it to the pool (which deletes it). 1094 request(0)->handle()->Reset(); 1095} 1096 1097// Sockets should not be leaked if CancelRequest() is called in between 1098// SetSocket() being called on the ClientSocketHandle and InvokeUserCallback(). 1099TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestReclaimsSockets) { 1100 host_resolver_->set_synchronous_mode(true); 1101 MockTransportClientSocketFactory::ClientSocketType socket_types[] = { 1102 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET, 1103 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET}; 1104 1105 client_socket_factory_.set_client_socket_types(socket_types, 1106 arraysize(socket_types)); 1107 1108 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1109 1110 base::Closure connect_trigger = 1111 client_socket_factory_.WaitForTriggerableSocketCreation(); 1112 1113 connect_trigger.Run(); // Calls InvokeUserCallbackLater() 1114 1115 request(0)->handle()->Reset(); // calls CancelRequest() 1116 1117 // We should now be able to create a new connection without blocking on the 1118 // endpoint lock. 1119 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 1120} 1121 1122// A handshake completing and then the WebSocket closing should only release one 1123// Endpoint, not two. 1124TEST_F(WebSocketTransportClientSocketPoolTest, EndpointLockIsOnlyReleasedOnce) { 1125 host_resolver_->set_synchronous_mode(true); 1126 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); 1127 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1128 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority)); 1129 // First socket completes handshake. 1130 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle()); 1131 // First socket is closed. 1132 request(0)->handle()->Reset(); 1133 // Second socket should have been released. 1134 EXPECT_EQ(OK, request(1)->WaitForResult()); 1135 // Third socket should still be waiting for endpoint. 1136 ASSERT_FALSE(request(2)->handle()->is_initialized()); 1137 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET, 1138 request(2)->handle()->GetLoadState()); 1139} 1140 1141} // namespace 1142 1143} // namespace net 1144