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 ~WebSocketTransportClientSocketPoolTest() override
{
72 // ReleaseAllConnections() calls RunUntilIdle() after releasing each
74 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
75 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
78 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
80 int StartRequest(const std::string
& group_name
, RequestPriority priority
) {
81 scoped_refptr
<TransportSocketParams
> params(
82 new TransportSocketParams(
83 HostPortPair("www.google.com", 80),
86 OnHostResolutionCallback(),
87 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
88 return test_base_
.StartRequestUsingPool(
89 &pool_
, group_name
, priority
, params
);
92 int GetOrderOfRequest(size_t index
) {
93 return test_base_
.GetOrderOfRequest(index
);
96 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive
) {
97 return test_base_
.ReleaseOneConnection(keep_alive
);
100 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive
) {
101 test_base_
.ReleaseAllConnections(keep_alive
);
104 TestSocketRequest
* request(int i
) { return test_base_
.request(i
); }
106 ScopedVector
<TestSocketRequest
>* requests() { return test_base_
.requests(); }
107 size_t completion_count() const { return test_base_
.completion_count(); }
109 CapturingNetLog net_log_
;
110 scoped_refptr
<TransportSocketParams
> params_
;
111 scoped_ptr
<ClientSocketPoolHistograms
> histograms_
;
112 scoped_ptr
<MockHostResolver
> host_resolver_
;
113 MockTransportClientSocketFactory client_socket_factory_
;
114 WebSocketTransportClientSocketPool pool_
;
115 ClientSocketPoolTest test_base_
;
116 ScopedWebSocketEndpointZeroUnlockDelay zero_unlock_delay_
;
119 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest
);
122 TEST_F(WebSocketTransportClientSocketPoolTest
, Basic
) {
123 TestCompletionCallback callback
;
124 ClientSocketHandle handle
;
125 int rv
= handle
.Init(
126 "a", params_
, LOW
, callback
.callback(), &pool_
, BoundNetLog());
127 EXPECT_EQ(ERR_IO_PENDING
, rv
);
128 EXPECT_FALSE(handle
.is_initialized());
129 EXPECT_FALSE(handle
.socket());
131 EXPECT_EQ(OK
, callback
.WaitForResult());
132 EXPECT_TRUE(handle
.is_initialized());
133 EXPECT_TRUE(handle
.socket());
134 TestLoadTimingInfoConnectedNotReused(handle
);
137 // Make sure that WebSocketTransportConnectJob passes on its priority to its
138 // HostResolver request on Init.
139 TEST_F(WebSocketTransportClientSocketPoolTest
, SetResolvePriorityOnInit
) {
140 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; ++i
) {
141 RequestPriority priority
= static_cast<RequestPriority
>(i
);
142 TestCompletionCallback callback
;
143 ClientSocketHandle handle
;
144 EXPECT_EQ(ERR_IO_PENDING
,
151 EXPECT_EQ(priority
, host_resolver_
->last_request_priority());
155 TEST_F(WebSocketTransportClientSocketPoolTest
, InitHostResolutionFailure
) {
156 host_resolver_
->rules()->AddSimulatedFailure("unresolvable.host.name");
157 TestCompletionCallback callback
;
158 ClientSocketHandle handle
;
159 HostPortPair
host_port_pair("unresolvable.host.name", 80);
160 scoped_refptr
<TransportSocketParams
> dest(new TransportSocketParams(
161 host_port_pair
, false, false, OnHostResolutionCallback(),
162 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
163 EXPECT_EQ(ERR_IO_PENDING
,
170 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, callback
.WaitForResult());
173 TEST_F(WebSocketTransportClientSocketPoolTest
, InitConnectionFailure
) {
174 client_socket_factory_
.set_default_client_socket_type(
175 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
);
176 TestCompletionCallback callback
;
177 ClientSocketHandle handle
;
178 EXPECT_EQ(ERR_IO_PENDING
,
185 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
187 // Make the host resolutions complete synchronously this time.
188 host_resolver_
->set_synchronous_mode(true);
189 EXPECT_EQ(ERR_CONNECTION_FAILED
,
198 TEST_F(WebSocketTransportClientSocketPoolTest
, PendingRequestsFinishFifo
) {
199 // First request finishes asynchronously.
200 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
201 EXPECT_EQ(OK
, request(0)->WaitForResult());
203 // Make all subsequent host resolutions complete synchronously.
204 host_resolver_
->set_synchronous_mode(true);
206 // Rest of them wait for the first socket to be released.
207 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
208 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
209 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
210 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
211 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
213 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
215 EXPECT_EQ(6, client_socket_factory_
.allocation_count());
217 // One initial asynchronous request and then 5 pending requests.
218 EXPECT_EQ(6U, completion_count());
220 // The requests finish in FIFO order.
221 EXPECT_EQ(1, GetOrderOfRequest(1));
222 EXPECT_EQ(2, GetOrderOfRequest(2));
223 EXPECT_EQ(3, GetOrderOfRequest(3));
224 EXPECT_EQ(4, GetOrderOfRequest(4));
225 EXPECT_EQ(5, GetOrderOfRequest(5));
226 EXPECT_EQ(6, GetOrderOfRequest(6));
228 // Make sure we test order of all requests made.
229 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
232 TEST_F(WebSocketTransportClientSocketPoolTest
, PendingRequests_NoKeepAlive
) {
233 // First request finishes asynchronously.
234 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
235 EXPECT_EQ(OK
, request(0)->WaitForResult());
237 // Make all subsequent host resolutions complete synchronously.
238 host_resolver_
->set_synchronous_mode(true);
240 // Rest of them wait for the first socket to be released.
241 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
242 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
243 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
244 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
245 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
247 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
249 // The pending requests should finish successfully.
250 EXPECT_EQ(OK
, request(1)->WaitForResult());
251 EXPECT_EQ(OK
, request(2)->WaitForResult());
252 EXPECT_EQ(OK
, request(3)->WaitForResult());
253 EXPECT_EQ(OK
, request(4)->WaitForResult());
254 EXPECT_EQ(OK
, request(5)->WaitForResult());
256 EXPECT_EQ(static_cast<int>(requests()->size()),
257 client_socket_factory_
.allocation_count());
259 // First asynchronous request, and then last 5 pending requests.
260 EXPECT_EQ(6U, completion_count());
263 // This test will start up a RequestSocket() and then immediately Cancel() it.
264 // The pending host resolution will eventually complete, and destroy the
265 // ClientSocketPool which will crash if the group was not cleared properly.
266 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequestClearGroup
) {
267 TestCompletionCallback callback
;
268 ClientSocketHandle handle
;
269 EXPECT_EQ(ERR_IO_PENDING
,
279 TEST_F(WebSocketTransportClientSocketPoolTest
, TwoRequestsCancelOne
) {
280 ClientSocketHandle handle
;
281 TestCompletionCallback callback
;
282 ClientSocketHandle handle2
;
283 TestCompletionCallback callback2
;
285 EXPECT_EQ(ERR_IO_PENDING
,
292 EXPECT_EQ(ERR_IO_PENDING
,
296 callback2
.callback(),
302 EXPECT_EQ(OK
, callback2
.WaitForResult());
306 TEST_F(WebSocketTransportClientSocketPoolTest
, ConnectCancelConnect
) {
307 client_socket_factory_
.set_default_client_socket_type(
308 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
);
309 ClientSocketHandle handle
;
310 TestCompletionCallback callback
;
311 EXPECT_EQ(ERR_IO_PENDING
,
321 TestCompletionCallback callback2
;
322 EXPECT_EQ(ERR_IO_PENDING
,
326 callback2
.callback(),
330 host_resolver_
->set_synchronous_mode(true);
331 // At this point, handle has two ConnectingSockets out for it. Due to the
332 // setting the mock resolver into synchronous mode, the host resolution for
333 // both will return in the same loop of the MessageLoop. The client socket
334 // is a pending socket, so the Connect() will asynchronously complete on the
335 // next loop of the MessageLoop. That means that the first
336 // ConnectingSocket will enter OnIOComplete, and then the second one will.
337 // If the first one is not cancelled, it will advance the load state, and
338 // then the second one will crash.
340 EXPECT_EQ(OK
, callback2
.WaitForResult());
341 EXPECT_FALSE(callback
.have_result());
346 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequest
) {
347 // First request finishes asynchronously.
348 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
349 EXPECT_EQ(OK
, request(0)->WaitForResult());
351 // Make all subsequent host resolutions complete synchronously.
352 host_resolver_
->set_synchronous_mode(true);
354 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
355 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
356 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
357 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
358 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
361 const size_t index_to_cancel
= 2;
362 EXPECT_FALSE(request(index_to_cancel
)->handle()->is_initialized());
363 request(index_to_cancel
)->handle()->Reset();
365 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
367 EXPECT_EQ(5, client_socket_factory_
.allocation_count());
369 EXPECT_EQ(1, GetOrderOfRequest(1));
370 EXPECT_EQ(2, GetOrderOfRequest(2));
371 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound
,
372 GetOrderOfRequest(3)); // Canceled request.
373 EXPECT_EQ(3, GetOrderOfRequest(4));
374 EXPECT_EQ(4, GetOrderOfRequest(5));
375 EXPECT_EQ(5, GetOrderOfRequest(6));
377 // Make sure we test order of all requests made.
378 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
381 class RequestSocketCallback
: public TestCompletionCallbackBase
{
383 RequestSocketCallback(ClientSocketHandle
* handle
,
384 WebSocketTransportClientSocketPool
* pool
)
387 within_callback_(false),
388 callback_(base::Bind(&RequestSocketCallback::OnComplete
,
389 base::Unretained(this))) {}
391 ~RequestSocketCallback() override
{}
393 const CompletionCallback
& callback() const { return callback_
; }
396 void OnComplete(int result
) {
398 ASSERT_EQ(OK
, result
);
400 if (!within_callback_
) {
401 // Don't allow reuse of the socket. Disconnect it and then release it and
402 // run through the MessageLoop once to get it completely released.
403 handle_
->socket()->Disconnect();
406 base::MessageLoop::ScopedNestableTaskAllower
allow(
407 base::MessageLoop::current());
408 base::MessageLoop::current()->RunUntilIdle();
410 within_callback_
= true;
411 scoped_refptr
<TransportSocketParams
> dest(
412 new TransportSocketParams(
413 HostPortPair("www.google.com", 80),
416 OnHostResolutionCallback(),
417 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
419 handle_
->Init("a", dest
, LOWEST
, callback(), pool_
, BoundNetLog());
424 ClientSocketHandle
* const handle_
;
425 WebSocketTransportClientSocketPool
* const pool_
;
426 bool within_callback_
;
427 CompletionCallback callback_
;
429 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback
);
432 TEST_F(WebSocketTransportClientSocketPoolTest
, RequestTwice
) {
433 ClientSocketHandle handle
;
434 RequestSocketCallback
callback(&handle
, &pool_
);
435 scoped_refptr
<TransportSocketParams
> dest(
436 new TransportSocketParams(
437 HostPortPair("www.google.com", 80),
440 OnHostResolutionCallback(),
441 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT
));
442 int rv
= handle
.Init(
443 "a", dest
, LOWEST
, callback
.callback(), &pool_
, BoundNetLog());
444 ASSERT_EQ(ERR_IO_PENDING
, rv
);
446 // The callback is going to request "www.google.com". We want it to complete
447 // synchronously this time.
448 host_resolver_
->set_synchronous_mode(true);
450 EXPECT_EQ(OK
, callback
.WaitForResult());
455 // Make sure that pending requests get serviced after active requests get
457 TEST_F(WebSocketTransportClientSocketPoolTest
,
458 CancelActiveRequestWithPendingRequests
) {
459 client_socket_factory_
.set_default_client_socket_type(
460 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
);
462 // Queue up all the requests
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 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
467 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
468 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
469 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
470 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
471 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
473 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
474 ASSERT_LE(kMaxSocketsPerGroup
, static_cast<int>(requests()->size()));
475 for (int i
= 0; i
< kMaxSocketsPerGroup
; i
++)
476 request(i
)->handle()->Reset();
478 // Let's wait for the rest to complete now.
479 for (size_t i
= kMaxSocketsPerGroup
; i
< requests()->size(); ++i
) {
480 EXPECT_EQ(OK
, request(i
)->WaitForResult());
481 request(i
)->handle()->Reset();
484 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup
, completion_count());
487 // Make sure that pending requests get serviced after active requests fail.
488 TEST_F(WebSocketTransportClientSocketPoolTest
,
489 FailingActiveRequestWithPendingRequests
) {
490 client_socket_factory_
.set_default_client_socket_type(
491 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
);
493 const int kNumRequests
= 2 * kMaxSocketsPerGroup
+ 1;
494 ASSERT_LE(kNumRequests
, kMaxSockets
); // Otherwise the test will hang.
496 // Queue up all the requests
497 for (int i
= 0; i
< kNumRequests
; i
++)
498 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
500 for (int i
= 0; i
< kNumRequests
; i
++)
501 EXPECT_EQ(ERR_CONNECTION_FAILED
, request(i
)->WaitForResult());
504 // The lock on the endpoint is released when a ClientSocketHandle is reset.
505 TEST_F(WebSocketTransportClientSocketPoolTest
, LockReleasedOnHandleReset
) {
506 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
507 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
508 EXPECT_EQ(OK
, request(0)->WaitForResult());
509 EXPECT_FALSE(request(1)->handle()->is_initialized());
510 request(0)->handle()->Reset();
512 EXPECT_TRUE(request(1)->handle()->is_initialized());
515 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
516 TEST_F(WebSocketTransportClientSocketPoolTest
, LockReleasedOnHandleDelete
) {
517 TestCompletionCallback callback
;
518 scoped_ptr
<ClientSocketHandle
> handle(new ClientSocketHandle
);
519 int rv
= handle
->Init(
520 "a", params_
, LOW
, callback
.callback(), &pool_
, BoundNetLog());
521 EXPECT_EQ(ERR_IO_PENDING
, rv
);
523 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
524 EXPECT_EQ(OK
, callback
.WaitForResult());
525 EXPECT_FALSE(request(0)->handle()->is_initialized());
528 EXPECT_TRUE(request(0)->handle()->is_initialized());
531 // A new connection is performed when the lock on the previous connection is
532 // explicitly released.
533 TEST_F(WebSocketTransportClientSocketPoolTest
,
534 ConnectionProceedsOnExplicitRelease
) {
535 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
536 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
537 EXPECT_EQ(OK
, request(0)->WaitForResult());
538 EXPECT_FALSE(request(1)->handle()->is_initialized());
539 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
541 EXPECT_TRUE(request(1)->handle()->is_initialized());
544 // A connection which is cancelled before completion does not block subsequent
546 TEST_F(WebSocketTransportClientSocketPoolTest
,
547 CancelDuringConnectionReleasesLock
) {
548 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
549 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
,
550 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
};
552 client_socket_factory_
.set_client_socket_types(case_types
,
553 arraysize(case_types
));
555 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
556 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
558 pool_
.CancelRequest("a", request(0)->handle());
559 EXPECT_EQ(OK
, request(1)->WaitForResult());
562 // Test the case of the IPv6 address stalling, and falling back to the IPv4
563 // socket which finishes first.
564 TEST_F(WebSocketTransportClientSocketPoolTest
,
565 IPv6FallbackSocketIPv4FinishesFirst
) {
566 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
569 host_resolver_
.get(),
570 &client_socket_factory_
,
573 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
574 // This is the IPv6 socket.
575 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
,
576 // This is the IPv4 socket.
577 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
};
579 client_socket_factory_
.set_client_socket_types(case_types
, 2);
581 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
582 host_resolver_
->rules()->AddIPLiteralRule(
583 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
585 TestCompletionCallback callback
;
586 ClientSocketHandle handle
;
588 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
589 EXPECT_EQ(ERR_IO_PENDING
, rv
);
590 EXPECT_FALSE(handle
.is_initialized());
591 EXPECT_FALSE(handle
.socket());
593 EXPECT_EQ(OK
, callback
.WaitForResult());
594 EXPECT_TRUE(handle
.is_initialized());
595 EXPECT_TRUE(handle
.socket());
597 handle
.socket()->GetLocalAddress(&endpoint
);
598 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
599 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
602 // Test the case of the IPv6 address being slow, thus falling back to trying to
603 // connect to the IPv4 address, but having the connect to the IPv6 address
605 TEST_F(WebSocketTransportClientSocketPoolTest
,
606 IPv6FallbackSocketIPv6FinishesFirst
) {
607 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
610 host_resolver_
.get(),
611 &client_socket_factory_
,
614 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
615 // This is the IPv6 socket.
616 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
,
617 // This is the IPv4 socket.
618 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
};
620 client_socket_factory_
.set_client_socket_types(case_types
, 2);
621 client_socket_factory_
.set_delay(base::TimeDelta::FromMilliseconds(
622 TransportConnectJobHelper::kIPv6FallbackTimerInMs
+ 50));
624 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
625 host_resolver_
->rules()->AddIPLiteralRule(
626 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
628 TestCompletionCallback callback
;
629 ClientSocketHandle handle
;
631 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
632 EXPECT_EQ(ERR_IO_PENDING
, rv
);
633 EXPECT_FALSE(handle
.is_initialized());
634 EXPECT_FALSE(handle
.socket());
636 EXPECT_EQ(OK
, callback
.WaitForResult());
637 EXPECT_TRUE(handle
.is_initialized());
638 EXPECT_TRUE(handle
.socket());
640 handle
.socket()->GetLocalAddress(&endpoint
);
641 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
642 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
645 TEST_F(WebSocketTransportClientSocketPoolTest
,
646 IPv6NoIPv4AddressesToFallbackTo
) {
647 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
650 host_resolver_
.get(),
651 &client_socket_factory_
,
654 client_socket_factory_
.set_default_client_socket_type(
655 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
657 // Resolve an AddressList with only IPv6 addresses.
658 host_resolver_
->rules()->AddIPLiteralRule(
659 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
661 TestCompletionCallback callback
;
662 ClientSocketHandle handle
;
664 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
665 EXPECT_EQ(ERR_IO_PENDING
, rv
);
666 EXPECT_FALSE(handle
.is_initialized());
667 EXPECT_FALSE(handle
.socket());
669 EXPECT_EQ(OK
, callback
.WaitForResult());
670 EXPECT_TRUE(handle
.is_initialized());
671 EXPECT_TRUE(handle
.socket());
673 handle
.socket()->GetLocalAddress(&endpoint
);
674 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
675 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
678 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv4HasNoFallback
) {
679 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
682 host_resolver_
.get(),
683 &client_socket_factory_
,
686 client_socket_factory_
.set_default_client_socket_type(
687 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
689 // Resolve an AddressList with only IPv4 addresses.
690 host_resolver_
->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
692 TestCompletionCallback callback
;
693 ClientSocketHandle handle
;
695 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
696 EXPECT_EQ(ERR_IO_PENDING
, rv
);
697 EXPECT_FALSE(handle
.is_initialized());
698 EXPECT_FALSE(handle
.socket());
700 EXPECT_EQ(OK
, callback
.WaitForResult());
701 EXPECT_TRUE(handle
.is_initialized());
702 EXPECT_TRUE(handle
.socket());
704 handle
.socket()->GetLocalAddress(&endpoint
);
705 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
706 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
709 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
710 // proceeed immediately.
711 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6InstantFail
) {
712 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
715 host_resolver_
.get(),
716 &client_socket_factory_
,
719 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
720 // First IPv6 socket.
721 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
,
722 // Second IPv6 socket.
723 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
,
724 // This is the IPv4 socket.
725 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
727 client_socket_factory_
.set_client_socket_types(case_types
,
728 arraysize(case_types
));
730 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
731 host_resolver_
->rules()->AddIPLiteralRule(
732 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
733 host_resolver_
->set_synchronous_mode(true);
734 TestCompletionCallback callback
;
735 ClientSocketHandle handle
;
737 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
739 ASSERT_TRUE(handle
.socket());
742 handle
.socket()->GetPeerAddress(&endpoint
);
743 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
746 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
747 // connections proceed immediately.
748 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6RapidFail
) {
749 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
752 host_resolver_
.get(),
753 &client_socket_factory_
,
756 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
757 // First IPv6 socket.
758 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
,
759 // Second IPv6 socket.
760 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
,
761 // This is the IPv4 socket.
762 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
764 client_socket_factory_
.set_client_socket_types(case_types
,
765 arraysize(case_types
));
767 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
768 host_resolver_
->rules()->AddIPLiteralRule(
769 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
771 TestCompletionCallback callback
;
772 ClientSocketHandle handle
;
774 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
775 EXPECT_EQ(ERR_IO_PENDING
, rv
);
776 EXPECT_FALSE(handle
.socket());
778 base::TimeTicks
start(base::TimeTicks::Now());
779 EXPECT_EQ(OK
, callback
.WaitForResult());
780 EXPECT_LT(base::TimeTicks::Now() - start
,
781 base::TimeDelta::FromMilliseconds(
782 TransportConnectJobHelper::kIPv6FallbackTimerInMs
));
783 ASSERT_TRUE(handle
.socket());
786 handle
.socket()->GetPeerAddress(&endpoint
);
787 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
790 // If two sockets connect successfully, the one which connected first wins (this
791 // can only happen if the sockets are different types, since sockets of the same
792 // type do not race).
793 TEST_F(WebSocketTransportClientSocketPoolTest
, FirstSuccessWins
) {
794 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
797 host_resolver_
.get(),
798 &client_socket_factory_
,
801 client_socket_factory_
.set_default_client_socket_type(
802 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET
);
804 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
805 host_resolver_
->rules()->AddIPLiteralRule(
806 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
808 TestCompletionCallback callback
;
809 ClientSocketHandle handle
;
811 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
812 EXPECT_EQ(ERR_IO_PENDING
, rv
);
813 ASSERT_FALSE(handle
.socket());
815 base::Closure ipv6_connect_trigger
=
816 client_socket_factory_
.WaitForTriggerableSocketCreation();
817 base::Closure ipv4_connect_trigger
=
818 client_socket_factory_
.WaitForTriggerableSocketCreation();
820 ipv4_connect_trigger
.Run();
821 ipv6_connect_trigger
.Run();
823 EXPECT_EQ(OK
, callback
.WaitForResult());
824 ASSERT_TRUE(handle
.socket());
827 handle
.socket()->GetPeerAddress(&endpoint
);
828 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
831 // We should not report failure until all connections have failed.
832 TEST_F(WebSocketTransportClientSocketPoolTest
, LastFailureWins
) {
833 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
836 host_resolver_
.get(),
837 &client_socket_factory_
,
840 client_socket_factory_
.set_default_client_socket_type(
841 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET
);
842 base::TimeDelta delay
= base::TimeDelta::FromMilliseconds(
843 TransportConnectJobHelper::kIPv6FallbackTimerInMs
/ 3);
844 client_socket_factory_
.set_delay(delay
);
846 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
847 host_resolver_
->rules()->AddIPLiteralRule("*",
848 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
849 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
853 // Expected order of events:
854 // After 100ms: Connect to 1:abcd::3:4:ff times out
855 // After 200ms: Connect to 2:abcd::3:4:ff times out
856 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
857 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
858 // After 500ms: Connect to 2.2.2.2 times out
860 TestCompletionCallback callback
;
861 ClientSocketHandle handle
;
862 base::TimeTicks
start(base::TimeTicks::Now());
864 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
865 EXPECT_EQ(ERR_IO_PENDING
, rv
);
867 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
869 EXPECT_GE(base::TimeTicks::Now() - start
, delay
* 5);
872 // Global timeout for all connects applies. This test is disabled by default
873 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
875 TEST_F(WebSocketTransportClientSocketPoolTest
, DISABLED_OverallTimeoutApplies
) {
876 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
879 host_resolver_
.get(),
880 &client_socket_factory_
,
882 const base::TimeDelta connect_job_timeout
= pool
.ConnectionTimeout();
884 client_socket_factory_
.set_default_client_socket_type(
885 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET
);
886 client_socket_factory_
.set_delay(base::TimeDelta::FromSeconds(1) +
887 connect_job_timeout
/ 6);
889 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 addresses.
890 host_resolver_
->rules()->AddIPLiteralRule("*",
891 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
892 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
893 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
894 "1.1.1.1,2.2.2.2,3.3.3.3,"
895 "4.4.4.4,5.5.5.5,6.6.6.6",
898 TestCompletionCallback callback
;
899 ClientSocketHandle handle
;
902 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
903 EXPECT_EQ(ERR_IO_PENDING
, rv
);
905 EXPECT_EQ(ERR_TIMED_OUT
, callback
.WaitForResult());
908 TEST_F(WebSocketTransportClientSocketPoolTest
, MaxSocketsEnforced
) {
909 host_resolver_
->set_synchronous_mode(true);
910 for (int i
= 0; i
< kMaxSockets
; ++i
) {
911 ASSERT_EQ(OK
, StartRequest("a", kDefaultPriority
));
912 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
915 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
918 TEST_F(WebSocketTransportClientSocketPoolTest
, MaxSocketsEnforcedWhenPending
) {
919 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
920 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
922 // Now there are 32 sockets waiting to connect, and one stalled.
923 for (int i
= 0; i
< kMaxSockets
; ++i
) {
925 EXPECT_TRUE(request(i
)->handle()->is_initialized());
926 EXPECT_TRUE(request(i
)->handle()->socket());
927 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
929 // Now there are 32 sockets connected, and one stalled.
931 EXPECT_FALSE(request(kMaxSockets
)->handle()->is_initialized());
932 EXPECT_FALSE(request(kMaxSockets
)->handle()->socket());
935 TEST_F(WebSocketTransportClientSocketPoolTest
, StalledSocketReleased
) {
936 host_resolver_
->set_synchronous_mode(true);
937 for (int i
= 0; i
< kMaxSockets
; ++i
) {
938 ASSERT_EQ(OK
, StartRequest("a", kDefaultPriority
));
939 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
943 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
944 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE
);
945 EXPECT_TRUE(request(kMaxSockets
)->handle()->is_initialized());
946 EXPECT_TRUE(request(kMaxSockets
)->handle()->socket());
949 TEST_F(WebSocketTransportClientSocketPoolTest
, IsStalledTrueWhenStalled
) {
950 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
951 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
953 EXPECT_EQ(OK
, request(0)->WaitForResult());
954 EXPECT_TRUE(pool_
.IsStalled());
957 TEST_F(WebSocketTransportClientSocketPoolTest
,
958 CancellingPendingSocketUnstallsStalledSocket
) {
959 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
960 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
962 EXPECT_EQ(OK
, request(0)->WaitForResult());
963 request(1)->handle()->Reset();
965 EXPECT_FALSE(pool_
.IsStalled());
968 TEST_F(WebSocketTransportClientSocketPoolTest
,
969 LoadStateOfStalledSocketIsWaitingForAvailableSocket
) {
970 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
971 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
973 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET
,
974 pool_
.GetLoadState("a", request(kMaxSockets
)->handle()));
977 TEST_F(WebSocketTransportClientSocketPoolTest
,
978 CancellingStalledSocketUnstallsPool
) {
979 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
980 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
982 request(kMaxSockets
)->handle()->Reset();
984 EXPECT_FALSE(pool_
.IsStalled());
987 TEST_F(WebSocketTransportClientSocketPoolTest
,
988 FlushWithErrorFlushesPendingConnections
) {
989 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
990 pool_
.FlushWithError(ERR_FAILED
);
991 EXPECT_EQ(ERR_FAILED
, request(0)->WaitForResult());
994 TEST_F(WebSocketTransportClientSocketPoolTest
,
995 FlushWithErrorFlushesStalledConnections
) {
996 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
997 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
999 pool_
.FlushWithError(ERR_FAILED
);
1000 EXPECT_EQ(ERR_FAILED
, request(kMaxSockets
)->WaitForResult());
1003 TEST_F(WebSocketTransportClientSocketPoolTest
,
1004 AfterFlushWithErrorCanMakeNewConnections
) {
1005 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
1006 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1008 pool_
.FlushWithError(ERR_FAILED
);
1009 host_resolver_
->set_synchronous_mode(true);
1010 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1013 // Deleting pending connections can release the lock on the endpoint, which can
1014 // in principle lead to other pending connections succeeding. However, when we
1015 // call FlushWithError(), everything should fail.
1016 TEST_F(WebSocketTransportClientSocketPoolTest
,
1017 FlushWithErrorDoesNotCauseSuccessfulConnections
) {
1018 host_resolver_
->set_synchronous_mode(true);
1019 MockTransportClientSocketFactory::ClientSocketType first_type
[] = {
1021 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
1023 client_socket_factory_
.set_client_socket_types(first_type
,
1024 arraysize(first_type
));
1025 // The rest of the sockets will connect synchronously.
1026 client_socket_factory_
.set_default_client_socket_type(
1027 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
);
1028 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1029 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1031 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in
1032 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the
1033 // lock, they will synchronously connect.
1034 pool_
.FlushWithError(ERR_FAILED
);
1035 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1036 EXPECT_EQ(ERR_FAILED
, request(i
)->WaitForResult());
1040 // This is a regression test for the first attempted fix for
1041 // FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can
1042 // have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for
1043 // the lock at the same time.
1044 TEST_F(WebSocketTransportClientSocketPoolTest
,
1045 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes
) {
1046 host_resolver_
->set_synchronous_mode(true);
1047 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have
1049 std::vector
<MockTransportClientSocketFactory::ClientSocketType
> socket_types(
1051 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
);
1052 client_socket_factory_
.set_client_socket_types(&socket_types
[0],
1053 socket_types
.size());
1054 // The rest of the sockets will connect synchronously.
1055 client_socket_factory_
.set_default_client_socket_type(
1056 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
);
1057 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1058 host_resolver_
->rules()->ClearRules();
1059 // Each connect job has a different IPv6 address but the same IPv4 address.
1060 // So the IPv6 connections happen in parallel but the IPv4 ones are
1062 host_resolver_
->rules()->AddIPLiteralRule("*",
1068 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1070 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
1072 RunLoopForTimePeriod(base::TimeDelta::FromMilliseconds(
1073 TransportConnectJobHelper::kIPv6FallbackTimerInMs
));
1074 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
1075 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
1076 pool_
.FlushWithError(ERR_FAILED
);
1077 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1078 EXPECT_EQ(ERR_FAILED
, request(i
)->WaitForResult());
1082 // Sockets that have had ownership transferred to a ClientSocketHandle should
1083 // not be affected by FlushWithError.
1084 TEST_F(WebSocketTransportClientSocketPoolTest
,
1085 FlushWithErrorDoesNotAffectHandedOutSockets
) {
1086 host_resolver_
->set_synchronous_mode(true);
1087 MockTransportClientSocketFactory::ClientSocketType socket_types
[] = {
1088 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
,
1089 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
};
1090 client_socket_factory_
.set_client_socket_types(socket_types
,
1091 arraysize(socket_types
));
1092 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1093 // Socket has been "handed out".
1094 EXPECT_TRUE(request(0)->handle()->socket());
1096 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1097 // Now we have one socket handed out, and one pending.
1098 pool_
.FlushWithError(ERR_FAILED
);
1099 EXPECT_EQ(ERR_FAILED
, request(1)->WaitForResult());
1100 // Socket owned by ClientSocketHandle is unaffected:
1101 EXPECT_TRUE(request(0)->handle()->socket());
1102 // Return it to the pool (which deletes it).
1103 request(0)->handle()->Reset();
1106 // Sockets should not be leaked if CancelRequest() is called in between
1107 // SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
1108 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequestReclaimsSockets
) {
1109 host_resolver_
->set_synchronous_mode(true);
1110 MockTransportClientSocketFactory::ClientSocketType socket_types
[] = {
1111 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET
,
1112 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
1114 client_socket_factory_
.set_client_socket_types(socket_types
,
1115 arraysize(socket_types
));
1117 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1119 base::Closure connect_trigger
=
1120 client_socket_factory_
.WaitForTriggerableSocketCreation();
1122 connect_trigger
.Run(); // Calls InvokeUserCallbackLater()
1124 request(0)->handle()->Reset(); // calls CancelRequest()
1127 // We should now be able to create a new connection without blocking on the
1129 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1132 // A handshake completing and then the WebSocket closing should only release one
1133 // Endpoint, not two.
1134 TEST_F(WebSocketTransportClientSocketPoolTest
, EndpointLockIsOnlyReleasedOnce
) {
1135 host_resolver_
->set_synchronous_mode(true);
1136 ASSERT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1137 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1138 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1139 // First socket completes handshake.
1140 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
1142 // First socket is closed.
1143 request(0)->handle()->Reset();
1144 // Second socket should have been released.
1145 EXPECT_EQ(OK
, request(1)->WaitForResult());
1146 // Third socket should still be waiting for endpoint.
1147 ASSERT_FALSE(request(2)->handle()->is_initialized());
1148 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET
,
1149 request(2)->handle()->GetLoadState());