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.
5 #include "net/socket/websocket_transport_client_socket_pool.h"
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"
38 const int kMaxSockets
= 32;
39 const int kMaxSocketsPerGroup
= 6;
40 const RequestPriority kDefaultPriority
= LOW
;
42 // RunLoop doesn't support this natively but it is easy to emulate.
43 void 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
);
51 class WebSocketTransportClientSocketPoolTest
: public testing::Test
{
53 WebSocketTransportClientSocketPoolTest()
54 : params_(new TransportSocketParams(
55 HostPortPair("www.google.com", 80),
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_
),
67 &client_socket_factory_
,
70 virtual ~WebSocketTransportClientSocketPoolTest() {
71 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
72 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
75 int StartRequest(const std::string
& group_name
, RequestPriority priority
) {
76 scoped_refptr
<TransportSocketParams
> params(
77 new TransportSocketParams(
78 HostPortPair("www.google.com", 80),
81 OnHostResolutionCallback(),
82 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
83 return test_base_
.StartRequestUsingPool(
84 &pool_
, group_name
, priority
, params
);
87 int GetOrderOfRequest(size_t index
) {
88 return test_base_
.GetOrderOfRequest(index
);
91 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive
) {
92 return test_base_
.ReleaseOneConnection(keep_alive
);
95 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive
) {
96 test_base_
.ReleaseAllConnections(keep_alive
);
99 TestSocketRequest
* request(int i
) { return test_base_
.request(i
); }
101 ScopedVector
<TestSocketRequest
>* requests() { return test_base_
.requests(); }
102 size_t completion_count() const { return test_base_
.completion_count(); }
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_
;
113 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest
);
116 TEST_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());
125 EXPECT_EQ(OK
, callback
.WaitForResult());
126 EXPECT_TRUE(handle
.is_initialized());
127 EXPECT_TRUE(handle
.socket());
128 TestLoadTimingInfoConnectedNotReused(handle
);
131 // Make sure that WebSocketTransportConnectJob passes on its priority to its
132 // HostResolver request on Init.
133 TEST_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
,
145 EXPECT_EQ(priority
, host_resolver_
->last_request_priority());
149 TEST_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
,
164 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, callback
.WaitForResult());
167 TEST_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
,
179 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
181 // Make the host resolutions complete synchronously this time.
182 host_resolver_
->set_synchronous_mode(true);
183 EXPECT_EQ(ERR_CONNECTION_FAILED
,
192 TEST_F(WebSocketTransportClientSocketPoolTest
, PendingRequestsFinishFifo
) {
193 // First request finishes asynchronously.
194 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
195 EXPECT_EQ(OK
, request(0)->WaitForResult());
197 // Make all subsequent host resolutions complete synchronously.
198 host_resolver_
->set_synchronous_mode(true);
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
));
207 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
209 EXPECT_EQ(6, client_socket_factory_
.allocation_count());
211 // One initial asynchronous request and then 5 pending requests.
212 EXPECT_EQ(6U, completion_count());
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));
222 // Make sure we test order of all requests made.
223 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
226 TEST_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());
231 // Make all subsequent host resolutions complete synchronously.
232 host_resolver_
->set_synchronous_mode(true);
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
));
241 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
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());
250 EXPECT_EQ(static_cast<int>(requests()->size()),
251 client_socket_factory_
.allocation_count());
253 // First asynchronous request, and then last 5 pending requests.
254 EXPECT_EQ(6U, completion_count());
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.
260 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequestClearGroup
) {
261 TestCompletionCallback callback
;
262 ClientSocketHandle handle
;
263 EXPECT_EQ(ERR_IO_PENDING
,
273 TEST_F(WebSocketTransportClientSocketPoolTest
, TwoRequestsCancelOne
) {
274 ClientSocketHandle handle
;
275 TestCompletionCallback callback
;
276 ClientSocketHandle handle2
;
277 TestCompletionCallback callback2
;
279 EXPECT_EQ(ERR_IO_PENDING
,
286 EXPECT_EQ(ERR_IO_PENDING
,
290 callback2
.callback(),
296 EXPECT_EQ(OK
, callback2
.WaitForResult());
300 TEST_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
,
315 TestCompletionCallback callback2
;
316 EXPECT_EQ(ERR_IO_PENDING
,
320 callback2
.callback(),
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.
334 EXPECT_EQ(OK
, callback2
.WaitForResult());
335 EXPECT_FALSE(callback
.have_result());
340 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequest
) {
341 // First request finishes asynchronously.
342 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
343 EXPECT_EQ(OK
, request(0)->WaitForResult());
345 // Make all subsequent host resolutions complete synchronously.
346 host_resolver_
->set_synchronous_mode(true);
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
));
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();
359 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
361 EXPECT_EQ(5, client_socket_factory_
.allocation_count());
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));
371 // Make sure we test order of all requests made.
372 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
375 class RequestSocketCallback
: public TestCompletionCallbackBase
{
377 RequestSocketCallback(ClientSocketHandle
* handle
,
378 WebSocketTransportClientSocketPool
* pool
)
381 within_callback_(false),
382 callback_(base::Bind(&RequestSocketCallback::OnComplete
,
383 base::Unretained(this))) {}
385 virtual ~RequestSocketCallback() {}
387 const CompletionCallback
& callback() const { return callback_
; }
390 void OnComplete(int result
) {
392 ASSERT_EQ(OK
, result
);
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();
400 base::MessageLoop::ScopedNestableTaskAllower
allow(
401 base::MessageLoop::current());
402 base::MessageLoop::current()->RunUntilIdle();
404 within_callback_
= true;
405 scoped_refptr
<TransportSocketParams
> dest(
406 new TransportSocketParams(
407 HostPortPair("www.google.com", 80),
410 OnHostResolutionCallback(),
411 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
413 handle_
->Init("a", dest
, LOWEST
, callback(), pool_
, BoundNetLog());
418 ClientSocketHandle
* const handle_
;
419 WebSocketTransportClientSocketPool
* const pool_
;
420 bool within_callback_
;
421 CompletionCallback callback_
;
423 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback
);
426 TEST_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),
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
);
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);
444 EXPECT_EQ(OK
, callback
.WaitForResult());
449 // Make sure that pending requests get serviced after active requests get
451 TEST_F(WebSocketTransportClientSocketPoolTest
,
452 CancelActiveRequestWithPendingRequests
) {
453 client_socket_factory_
.set_default_client_socket_type(
454 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
);
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
));
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();
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();
478 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup
, completion_count());
481 // Make sure that pending requests get serviced after active requests fail.
482 TEST_F(WebSocketTransportClientSocketPoolTest
,
483 FailingActiveRequestWithPendingRequests
) {
484 client_socket_factory_
.set_default_client_socket_type(
485 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
);
487 const int kNumRequests
= 2 * kMaxSocketsPerGroup
+ 1;
488 ASSERT_LE(kNumRequests
, kMaxSockets
); // Otherwise the test will hang.
490 // Queue up all the requests
491 for (int i
= 0; i
< kNumRequests
; i
++)
492 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
494 for (int i
= 0; i
< kNumRequests
; i
++)
495 EXPECT_EQ(ERR_CONNECTION_FAILED
, request(i
)->WaitForResult());
498 // The lock on the endpoint is released when a ClientSocketHandle is reset.
499 TEST_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());
509 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
510 TEST_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
);
517 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
518 EXPECT_EQ(OK
, callback
.WaitForResult());
519 EXPECT_FALSE(request(0)->handle()->is_initialized());
521 base::RunLoop().RunUntilIdle();
522 EXPECT_TRUE(request(0)->handle()->is_initialized());
525 // A new connection is performed when the lock on the previous connection is
526 // explicitly released.
527 TEST_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());
538 // A connection which is cancelled before completion does not block subsequent
540 TEST_F(WebSocketTransportClientSocketPoolTest
,
541 CancelDuringConnectionReleasesLock
) {
542 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
543 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
,
544 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
};
546 client_socket_factory_
.set_client_socket_types(case_types
,
547 arraysize(case_types
));
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());
556 // Test the case of the IPv6 address stalling, and falling back to the IPv4
557 // socket which finishes first.
558 TEST_F(WebSocketTransportClientSocketPoolTest
,
559 IPv6FallbackSocketIPv4FinishesFirst
) {
560 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
563 host_resolver_
.get(),
564 &client_socket_factory_
,
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
};
573 client_socket_factory_
.set_client_socket_types(case_types
, 2);
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());
579 TestCompletionCallback callback
;
580 ClientSocketHandle handle
;
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());
587 EXPECT_EQ(OK
, callback
.WaitForResult());
588 EXPECT_TRUE(handle
.is_initialized());
589 EXPECT_TRUE(handle
.socket());
591 handle
.socket()->GetLocalAddress(&endpoint
);
592 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
593 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
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
599 TEST_F(WebSocketTransportClientSocketPoolTest
,
600 IPv6FallbackSocketIPv6FinishesFirst
) {
601 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
604 host_resolver_
.get(),
605 &client_socket_factory_
,
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
};
614 client_socket_factory_
.set_client_socket_types(case_types
, 2);
615 client_socket_factory_
.set_delay(base::TimeDelta::FromMilliseconds(
616 TransportConnectJobHelper::kIPv6FallbackTimerInMs
+ 50));
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());
622 TestCompletionCallback callback
;
623 ClientSocketHandle handle
;
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());
630 EXPECT_EQ(OK
, callback
.WaitForResult());
631 EXPECT_TRUE(handle
.is_initialized());
632 EXPECT_TRUE(handle
.socket());
634 handle
.socket()->GetLocalAddress(&endpoint
);
635 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
636 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
639 TEST_F(WebSocketTransportClientSocketPoolTest
,
640 IPv6NoIPv4AddressesToFallbackTo
) {
641 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
644 host_resolver_
.get(),
645 &client_socket_factory_
,
648 client_socket_factory_
.set_default_client_socket_type(
649 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
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());
655 TestCompletionCallback callback
;
656 ClientSocketHandle handle
;
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());
663 EXPECT_EQ(OK
, callback
.WaitForResult());
664 EXPECT_TRUE(handle
.is_initialized());
665 EXPECT_TRUE(handle
.socket());
667 handle
.socket()->GetLocalAddress(&endpoint
);
668 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
669 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
672 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv4HasNoFallback
) {
673 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
676 host_resolver_
.get(),
677 &client_socket_factory_
,
680 client_socket_factory_
.set_default_client_socket_type(
681 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
683 // Resolve an AddressList with only IPv4 addresses.
684 host_resolver_
->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
686 TestCompletionCallback callback
;
687 ClientSocketHandle handle
;
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());
694 EXPECT_EQ(OK
, callback
.WaitForResult());
695 EXPECT_TRUE(handle
.is_initialized());
696 EXPECT_TRUE(handle
.socket());
698 handle
.socket()->GetLocalAddress(&endpoint
);
699 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
700 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
703 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
704 // proceeed immediately.
705 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6InstantFail
) {
706 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
709 host_resolver_
.get(),
710 &client_socket_factory_
,
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
};
721 client_socket_factory_
.set_client_socket_types(case_types
,
722 arraysize(case_types
));
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
;
731 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
733 ASSERT_TRUE(handle
.socket());
736 handle
.socket()->GetPeerAddress(&endpoint
);
737 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
740 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
741 // connections proceed immediately.
742 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6RapidFail
) {
743 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
746 host_resolver_
.get(),
747 &client_socket_factory_
,
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
};
758 client_socket_factory_
.set_client_socket_types(case_types
,
759 arraysize(case_types
));
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());
765 TestCompletionCallback callback
;
766 ClientSocketHandle handle
;
768 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
769 EXPECT_EQ(ERR_IO_PENDING
, rv
);
770 EXPECT_FALSE(handle
.socket());
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());
780 handle
.socket()->GetPeerAddress(&endpoint
);
781 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
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).
787 TEST_F(WebSocketTransportClientSocketPoolTest
, FirstSuccessWins
) {
788 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
791 host_resolver_
.get(),
792 &client_socket_factory_
,
795 client_socket_factory_
.set_default_client_socket_type(
796 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET
);
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());
802 TestCompletionCallback callback
;
803 ClientSocketHandle handle
;
805 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
806 EXPECT_EQ(ERR_IO_PENDING
, rv
);
807 ASSERT_FALSE(handle
.socket());
809 base::Closure ipv6_connect_trigger
=
810 client_socket_factory_
.WaitForTriggerableSocketCreation();
811 base::Closure ipv4_connect_trigger
=
812 client_socket_factory_
.WaitForTriggerableSocketCreation();
814 ipv4_connect_trigger
.Run();
815 ipv6_connect_trigger
.Run();
817 EXPECT_EQ(OK
, callback
.WaitForResult());
818 ASSERT_TRUE(handle
.socket());
821 handle
.socket()->GetPeerAddress(&endpoint
);
822 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
825 // We should not report failure until all connections have failed.
826 TEST_F(WebSocketTransportClientSocketPoolTest
, LastFailureWins
) {
827 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
830 host_resolver_
.get(),
831 &client_socket_factory_
,
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
);
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,"
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
854 TestCompletionCallback callback
;
855 ClientSocketHandle handle
;
856 base::Time
start(base::Time::NowFromSystemTime());
858 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
859 EXPECT_EQ(ERR_IO_PENDING
, rv
);
861 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
863 EXPECT_GE(base::Time::NowFromSystemTime() - start
, delay
* 5);
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
869 TEST_F(WebSocketTransportClientSocketPoolTest
, DISABLED_OverallTimeoutApplies
) {
870 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
873 host_resolver_
.get(),
874 &client_socket_factory_
,
876 const base::TimeDelta connect_job_timeout
= pool
.ConnectionTimeout();
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);
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",
892 TestCompletionCallback callback
;
893 ClientSocketHandle handle
;
896 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
897 EXPECT_EQ(ERR_IO_PENDING
, rv
);
899 EXPECT_EQ(ERR_TIMED_OUT
, callback
.WaitForResult());
902 TEST_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());
908 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
911 TEST_F(WebSocketTransportClientSocketPoolTest
, MaxSocketsEnforcedWhenPending
) {
912 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
913 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
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());
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());
928 TEST_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());
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());
941 TEST_F(WebSocketTransportClientSocketPoolTest
, IsStalledTrueWhenStalled
) {
942 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
943 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
945 EXPECT_EQ(OK
, request(0)->WaitForResult());
946 EXPECT_TRUE(pool_
.IsStalled());
949 TEST_F(WebSocketTransportClientSocketPoolTest
,
950 CancellingPendingSocketUnstallsStalledSocket
) {
951 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
952 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
954 EXPECT_EQ(OK
, request(0)->WaitForResult());
955 request(1)->handle()->Reset();
956 base::RunLoop().RunUntilIdle();
957 EXPECT_FALSE(pool_
.IsStalled());
960 TEST_F(WebSocketTransportClientSocketPoolTest
,
961 LoadStateOfStalledSocketIsWaitingForAvailableSocket
) {
962 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
963 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
965 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET
,
966 pool_
.GetLoadState("a", request(kMaxSockets
)->handle()));
969 TEST_F(WebSocketTransportClientSocketPoolTest
,
970 CancellingStalledSocketUnstallsPool
) {
971 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
972 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
974 request(kMaxSockets
)->handle()->Reset();
975 EXPECT_FALSE(pool_
.IsStalled());
978 TEST_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());
985 TEST_F(WebSocketTransportClientSocketPoolTest
,
986 FlushWithErrorFlushesStalledConnections
) {
987 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
988 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
990 pool_
.FlushWithError(ERR_FAILED
);
991 EXPECT_EQ(ERR_FAILED
, request(kMaxSockets
)->WaitForResult());
994 TEST_F(WebSocketTransportClientSocketPoolTest
,
995 AfterFlushWithErrorCanMakeNewConnections
) {
996 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
997 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
999 pool_
.FlushWithError(ERR_FAILED
);
1000 host_resolver_
->set_synchronous_mode(true);
1001 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
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.
1007 TEST_F(WebSocketTransportClientSocketPoolTest
,
1008 FlushWithErrorDoesNotCauseSuccessfulConnections
) {
1009 host_resolver_
->set_synchronous_mode(true);
1010 MockTransportClientSocketFactory::ClientSocketType first_type
[] = {
1012 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
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
));
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());
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.
1035 TEST_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
1040 std::vector
<MockTransportClientSocketFactory::ClientSocketType
> socket_types(
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
1053 host_resolver_
->rules()->AddIPLiteralRule("*",
1059 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1061 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
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());
1073 // Sockets that have had ownership transferred to a ClientSocketHandle should
1074 // not be affected by FlushWithError.
1075 TEST_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());
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();
1097 // Sockets should not be leaked if CancelRequest() is called in between
1098 // SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
1099 TEST_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
};
1105 client_socket_factory_
.set_client_socket_types(socket_types
,
1106 arraysize(socket_types
));
1108 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1110 base::Closure connect_trigger
=
1111 client_socket_factory_
.WaitForTriggerableSocketCreation();
1113 connect_trigger
.Run(); // Calls InvokeUserCallbackLater()
1115 request(0)->handle()->Reset(); // calls CancelRequest()
1117 // We should now be able to create a new connection without blocking on the
1119 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1122 // A handshake completing and then the WebSocket closing should only release one
1123 // Endpoint, not two.
1124 TEST_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());