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(HostPortPair("www.google.com", 80),
57 OnHostResolutionCallback())),
58 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
59 host_resolver_(new MockHostResolver
),
60 client_socket_factory_(&net_log_
),
65 &client_socket_factory_
,
68 virtual ~WebSocketTransportClientSocketPoolTest() {
69 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
70 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
73 int StartRequest(const std::string
& group_name
, RequestPriority priority
) {
74 scoped_refptr
<TransportSocketParams
> params(
75 new TransportSocketParams(HostPortPair("www.google.com", 80),
78 OnHostResolutionCallback()));
79 return test_base_
.StartRequestUsingPool(
80 &pool_
, group_name
, priority
, params
);
83 int GetOrderOfRequest(size_t index
) {
84 return test_base_
.GetOrderOfRequest(index
);
87 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive
) {
88 return test_base_
.ReleaseOneConnection(keep_alive
);
91 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive
) {
92 test_base_
.ReleaseAllConnections(keep_alive
);
95 TestSocketRequest
* request(int i
) { return test_base_
.request(i
); }
97 ScopedVector
<TestSocketRequest
>* requests() { return test_base_
.requests(); }
98 size_t completion_count() const { return test_base_
.completion_count(); }
100 CapturingNetLog net_log_
;
101 scoped_refptr
<TransportSocketParams
> params_
;
102 scoped_ptr
<ClientSocketPoolHistograms
> histograms_
;
103 scoped_ptr
<MockHostResolver
> host_resolver_
;
104 MockTransportClientSocketFactory client_socket_factory_
;
105 WebSocketTransportClientSocketPool pool_
;
106 ClientSocketPoolTest test_base_
;
109 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest
);
112 TEST_F(WebSocketTransportClientSocketPoolTest
, Basic
) {
113 TestCompletionCallback callback
;
114 ClientSocketHandle handle
;
115 int rv
= handle
.Init(
116 "a", params_
, LOW
, callback
.callback(), &pool_
, BoundNetLog());
117 EXPECT_EQ(ERR_IO_PENDING
, rv
);
118 EXPECT_FALSE(handle
.is_initialized());
119 EXPECT_FALSE(handle
.socket());
121 EXPECT_EQ(OK
, callback
.WaitForResult());
122 EXPECT_TRUE(handle
.is_initialized());
123 EXPECT_TRUE(handle
.socket());
124 TestLoadTimingInfoConnectedNotReused(handle
);
127 // Make sure that WebSocketTransportConnectJob passes on its priority to its
128 // HostResolver request on Init.
129 TEST_F(WebSocketTransportClientSocketPoolTest
, SetResolvePriorityOnInit
) {
130 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; ++i
) {
131 RequestPriority priority
= static_cast<RequestPriority
>(i
);
132 TestCompletionCallback callback
;
133 ClientSocketHandle handle
;
134 EXPECT_EQ(ERR_IO_PENDING
,
141 EXPECT_EQ(priority
, host_resolver_
->last_request_priority());
145 TEST_F(WebSocketTransportClientSocketPoolTest
, InitHostResolutionFailure
) {
146 host_resolver_
->rules()->AddSimulatedFailure("unresolvable.host.name");
147 TestCompletionCallback callback
;
148 ClientSocketHandle handle
;
149 HostPortPair
host_port_pair("unresolvable.host.name", 80);
150 scoped_refptr
<TransportSocketParams
> dest(new TransportSocketParams(
151 host_port_pair
, false, false, OnHostResolutionCallback()));
152 EXPECT_EQ(ERR_IO_PENDING
,
159 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, callback
.WaitForResult());
162 TEST_F(WebSocketTransportClientSocketPoolTest
, InitConnectionFailure
) {
163 client_socket_factory_
.set_default_client_socket_type(
164 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
);
165 TestCompletionCallback callback
;
166 ClientSocketHandle handle
;
167 EXPECT_EQ(ERR_IO_PENDING
,
174 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
176 // Make the host resolutions complete synchronously this time.
177 host_resolver_
->set_synchronous_mode(true);
178 EXPECT_EQ(ERR_CONNECTION_FAILED
,
187 TEST_F(WebSocketTransportClientSocketPoolTest
, PendingRequestsFinishFifo
) {
188 // First request finishes asynchronously.
189 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
190 EXPECT_EQ(OK
, request(0)->WaitForResult());
192 // Make all subsequent host resolutions complete synchronously.
193 host_resolver_
->set_synchronous_mode(true);
195 // Rest of them wait for the first socket to be released.
196 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
197 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
198 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
199 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
200 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
202 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
204 EXPECT_EQ(6, client_socket_factory_
.allocation_count());
206 // One initial asynchronous request and then 5 pending requests.
207 EXPECT_EQ(6U, completion_count());
209 // The requests finish in FIFO order.
210 EXPECT_EQ(1, GetOrderOfRequest(1));
211 EXPECT_EQ(2, GetOrderOfRequest(2));
212 EXPECT_EQ(3, GetOrderOfRequest(3));
213 EXPECT_EQ(4, GetOrderOfRequest(4));
214 EXPECT_EQ(5, GetOrderOfRequest(5));
215 EXPECT_EQ(6, GetOrderOfRequest(6));
217 // Make sure we test order of all requests made.
218 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
221 TEST_F(WebSocketTransportClientSocketPoolTest
, PendingRequests_NoKeepAlive
) {
222 // First request finishes asynchronously.
223 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
224 EXPECT_EQ(OK
, request(0)->WaitForResult());
226 // Make all subsequent host resolutions complete synchronously.
227 host_resolver_
->set_synchronous_mode(true);
229 // Rest of them wait for the first socket to be released.
230 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
231 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
232 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
233 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
234 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
236 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE
);
238 // The pending requests should finish successfully.
239 EXPECT_EQ(OK
, request(1)->WaitForResult());
240 EXPECT_EQ(OK
, request(2)->WaitForResult());
241 EXPECT_EQ(OK
, request(3)->WaitForResult());
242 EXPECT_EQ(OK
, request(4)->WaitForResult());
243 EXPECT_EQ(OK
, request(5)->WaitForResult());
245 EXPECT_EQ(static_cast<int>(requests()->size()),
246 client_socket_factory_
.allocation_count());
248 // First asynchronous request, and then last 5 pending requests.
249 EXPECT_EQ(6U, completion_count());
252 // This test will start up a RequestSocket() and then immediately Cancel() it.
253 // The pending host resolution will eventually complete, and destroy the
254 // ClientSocketPool which will crash if the group was not cleared properly.
255 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequestClearGroup
) {
256 TestCompletionCallback callback
;
257 ClientSocketHandle handle
;
258 EXPECT_EQ(ERR_IO_PENDING
,
268 TEST_F(WebSocketTransportClientSocketPoolTest
, TwoRequestsCancelOne
) {
269 ClientSocketHandle handle
;
270 TestCompletionCallback callback
;
271 ClientSocketHandle handle2
;
272 TestCompletionCallback callback2
;
274 EXPECT_EQ(ERR_IO_PENDING
,
281 EXPECT_EQ(ERR_IO_PENDING
,
285 callback2
.callback(),
291 EXPECT_EQ(OK
, callback2
.WaitForResult());
295 TEST_F(WebSocketTransportClientSocketPoolTest
, ConnectCancelConnect
) {
296 client_socket_factory_
.set_default_client_socket_type(
297 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
);
298 ClientSocketHandle handle
;
299 TestCompletionCallback callback
;
300 EXPECT_EQ(ERR_IO_PENDING
,
310 TestCompletionCallback callback2
;
311 EXPECT_EQ(ERR_IO_PENDING
,
315 callback2
.callback(),
319 host_resolver_
->set_synchronous_mode(true);
320 // At this point, handle has two ConnectingSockets out for it. Due to the
321 // setting the mock resolver into synchronous mode, the host resolution for
322 // both will return in the same loop of the MessageLoop. The client socket
323 // is a pending socket, so the Connect() will asynchronously complete on the
324 // next loop of the MessageLoop. That means that the first
325 // ConnectingSocket will enter OnIOComplete, and then the second one will.
326 // If the first one is not cancelled, it will advance the load state, and
327 // then the second one will crash.
329 EXPECT_EQ(OK
, callback2
.WaitForResult());
330 EXPECT_FALSE(callback
.have_result());
335 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequest
) {
336 // First request finishes asynchronously.
337 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
338 EXPECT_EQ(OK
, request(0)->WaitForResult());
340 // Make all subsequent host resolutions complete synchronously.
341 host_resolver_
->set_synchronous_mode(true);
343 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
344 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
345 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
346 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
347 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
350 const size_t index_to_cancel
= 2;
351 EXPECT_FALSE(request(index_to_cancel
)->handle()->is_initialized());
352 request(index_to_cancel
)->handle()->Reset();
354 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE
);
356 EXPECT_EQ(5, client_socket_factory_
.allocation_count());
358 EXPECT_EQ(1, GetOrderOfRequest(1));
359 EXPECT_EQ(2, GetOrderOfRequest(2));
360 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound
,
361 GetOrderOfRequest(3)); // Canceled request.
362 EXPECT_EQ(3, GetOrderOfRequest(4));
363 EXPECT_EQ(4, GetOrderOfRequest(5));
364 EXPECT_EQ(5, GetOrderOfRequest(6));
366 // Make sure we test order of all requests made.
367 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds
, GetOrderOfRequest(7));
370 class RequestSocketCallback
: public TestCompletionCallbackBase
{
372 RequestSocketCallback(ClientSocketHandle
* handle
,
373 WebSocketTransportClientSocketPool
* pool
)
376 within_callback_(false),
377 callback_(base::Bind(&RequestSocketCallback::OnComplete
,
378 base::Unretained(this))) {}
380 virtual ~RequestSocketCallback() {}
382 const CompletionCallback
& callback() const { return callback_
; }
385 void OnComplete(int result
) {
387 ASSERT_EQ(OK
, result
);
389 if (!within_callback_
) {
390 // Don't allow reuse of the socket. Disconnect it and then release it and
391 // run through the MessageLoop once to get it completely released.
392 handle_
->socket()->Disconnect();
395 base::MessageLoop::ScopedNestableTaskAllower
allow(
396 base::MessageLoop::current());
397 base::MessageLoop::current()->RunUntilIdle();
399 within_callback_
= true;
400 scoped_refptr
<TransportSocketParams
> dest(
401 new TransportSocketParams(HostPortPair("www.google.com", 80),
404 OnHostResolutionCallback()));
406 handle_
->Init("a", dest
, LOWEST
, callback(), pool_
, BoundNetLog());
411 ClientSocketHandle
* const handle_
;
412 WebSocketTransportClientSocketPool
* const pool_
;
413 bool within_callback_
;
414 CompletionCallback callback_
;
416 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback
);
419 TEST_F(WebSocketTransportClientSocketPoolTest
, RequestTwice
) {
420 ClientSocketHandle handle
;
421 RequestSocketCallback
callback(&handle
, &pool_
);
422 scoped_refptr
<TransportSocketParams
> dest(
423 new TransportSocketParams(HostPortPair("www.google.com", 80),
426 OnHostResolutionCallback()));
427 int rv
= handle
.Init(
428 "a", dest
, LOWEST
, callback
.callback(), &pool_
, BoundNetLog());
429 ASSERT_EQ(ERR_IO_PENDING
, rv
);
431 // The callback is going to request "www.google.com". We want it to complete
432 // synchronously this time.
433 host_resolver_
->set_synchronous_mode(true);
435 EXPECT_EQ(OK
, callback
.WaitForResult());
440 // Make sure that pending requests get serviced after active requests get
442 TEST_F(WebSocketTransportClientSocketPoolTest
,
443 CancelActiveRequestWithPendingRequests
) {
444 client_socket_factory_
.set_default_client_socket_type(
445 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
);
447 // Queue up all the requests
448 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
449 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
450 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
451 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
452 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
453 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
454 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
455 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
456 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
458 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
459 ASSERT_LE(kMaxSocketsPerGroup
, static_cast<int>(requests()->size()));
460 for (int i
= 0; i
< kMaxSocketsPerGroup
; i
++)
461 request(i
)->handle()->Reset();
463 // Let's wait for the rest to complete now.
464 for (size_t i
= kMaxSocketsPerGroup
; i
< requests()->size(); ++i
) {
465 EXPECT_EQ(OK
, request(i
)->WaitForResult());
466 request(i
)->handle()->Reset();
469 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup
, completion_count());
472 // Make sure that pending requests get serviced after active requests fail.
473 TEST_F(WebSocketTransportClientSocketPoolTest
,
474 FailingActiveRequestWithPendingRequests
) {
475 client_socket_factory_
.set_default_client_socket_type(
476 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
);
478 const int kNumRequests
= 2 * kMaxSocketsPerGroup
+ 1;
479 ASSERT_LE(kNumRequests
, kMaxSockets
); // Otherwise the test will hang.
481 // Queue up all the requests
482 for (int i
= 0; i
< kNumRequests
; i
++)
483 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
485 for (int i
= 0; i
< kNumRequests
; i
++)
486 EXPECT_EQ(ERR_CONNECTION_FAILED
, request(i
)->WaitForResult());
489 // The lock on the endpoint is released when a ClientSocketHandle is reset.
490 TEST_F(WebSocketTransportClientSocketPoolTest
, LockReleasedOnHandleReset
) {
491 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
492 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
493 EXPECT_EQ(OK
, request(0)->WaitForResult());
494 EXPECT_FALSE(request(1)->handle()->is_initialized());
495 request(0)->handle()->Reset();
496 base::RunLoop().RunUntilIdle();
497 EXPECT_TRUE(request(1)->handle()->is_initialized());
500 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
501 TEST_F(WebSocketTransportClientSocketPoolTest
, LockReleasedOnHandleDelete
) {
502 TestCompletionCallback callback
;
503 scoped_ptr
<ClientSocketHandle
> handle(new ClientSocketHandle
);
504 int rv
= handle
->Init(
505 "a", params_
, LOW
, callback
.callback(), &pool_
, BoundNetLog());
506 EXPECT_EQ(ERR_IO_PENDING
, rv
);
508 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
509 EXPECT_EQ(OK
, callback
.WaitForResult());
510 EXPECT_FALSE(request(0)->handle()->is_initialized());
512 base::RunLoop().RunUntilIdle();
513 EXPECT_TRUE(request(0)->handle()->is_initialized());
516 // A new connection is performed when the lock on the previous connection is
517 // explicitly released.
518 TEST_F(WebSocketTransportClientSocketPoolTest
,
519 ConnectionProceedsOnExplicitRelease
) {
520 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
521 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
522 EXPECT_EQ(OK
, request(0)->WaitForResult());
523 EXPECT_FALSE(request(1)->handle()->is_initialized());
524 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
525 base::RunLoop().RunUntilIdle();
526 EXPECT_TRUE(request(1)->handle()->is_initialized());
529 // A connection which is cancelled before completion does not block subsequent
531 TEST_F(WebSocketTransportClientSocketPoolTest
,
532 CancelDuringConnectionReleasesLock
) {
533 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
534 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
,
535 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
};
537 client_socket_factory_
.set_client_socket_types(case_types
,
538 arraysize(case_types
));
540 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
541 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
542 base::RunLoop().RunUntilIdle();
543 pool_
.CancelRequest("a", request(0)->handle());
544 EXPECT_EQ(OK
, request(1)->WaitForResult());
547 // Test the case of the IPv6 address stalling, and falling back to the IPv4
548 // socket which finishes first.
549 TEST_F(WebSocketTransportClientSocketPoolTest
,
550 IPv6FallbackSocketIPv4FinishesFirst
) {
551 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
554 host_resolver_
.get(),
555 &client_socket_factory_
,
558 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
559 // This is the IPv6 socket.
560 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
,
561 // This is the IPv4 socket.
562 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
};
564 client_socket_factory_
.set_client_socket_types(case_types
, 2);
566 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
567 host_resolver_
->rules()->AddIPLiteralRule(
568 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
570 TestCompletionCallback callback
;
571 ClientSocketHandle handle
;
573 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
574 EXPECT_EQ(ERR_IO_PENDING
, rv
);
575 EXPECT_FALSE(handle
.is_initialized());
576 EXPECT_FALSE(handle
.socket());
578 EXPECT_EQ(OK
, callback
.WaitForResult());
579 EXPECT_TRUE(handle
.is_initialized());
580 EXPECT_TRUE(handle
.socket());
582 handle
.socket()->GetLocalAddress(&endpoint
);
583 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
584 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
587 // Test the case of the IPv6 address being slow, thus falling back to trying to
588 // connect to the IPv4 address, but having the connect to the IPv6 address
590 TEST_F(WebSocketTransportClientSocketPoolTest
,
591 IPv6FallbackSocketIPv6FinishesFirst
) {
592 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
595 host_resolver_
.get(),
596 &client_socket_factory_
,
599 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
600 // This is the IPv6 socket.
601 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
,
602 // This is the IPv4 socket.
603 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
};
605 client_socket_factory_
.set_client_socket_types(case_types
, 2);
606 client_socket_factory_
.set_delay(base::TimeDelta::FromMilliseconds(
607 TransportConnectJobHelper::kIPv6FallbackTimerInMs
+ 50));
609 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
610 host_resolver_
->rules()->AddIPLiteralRule(
611 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
613 TestCompletionCallback callback
;
614 ClientSocketHandle handle
;
616 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
617 EXPECT_EQ(ERR_IO_PENDING
, rv
);
618 EXPECT_FALSE(handle
.is_initialized());
619 EXPECT_FALSE(handle
.socket());
621 EXPECT_EQ(OK
, callback
.WaitForResult());
622 EXPECT_TRUE(handle
.is_initialized());
623 EXPECT_TRUE(handle
.socket());
625 handle
.socket()->GetLocalAddress(&endpoint
);
626 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
627 EXPECT_EQ(2, client_socket_factory_
.allocation_count());
630 TEST_F(WebSocketTransportClientSocketPoolTest
,
631 IPv6NoIPv4AddressesToFallbackTo
) {
632 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
635 host_resolver_
.get(),
636 &client_socket_factory_
,
639 client_socket_factory_
.set_default_client_socket_type(
640 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
642 // Resolve an AddressList with only IPv6 addresses.
643 host_resolver_
->rules()->AddIPLiteralRule(
644 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
646 TestCompletionCallback callback
;
647 ClientSocketHandle handle
;
649 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
650 EXPECT_EQ(ERR_IO_PENDING
, rv
);
651 EXPECT_FALSE(handle
.is_initialized());
652 EXPECT_FALSE(handle
.socket());
654 EXPECT_EQ(OK
, callback
.WaitForResult());
655 EXPECT_TRUE(handle
.is_initialized());
656 EXPECT_TRUE(handle
.socket());
658 handle
.socket()->GetLocalAddress(&endpoint
);
659 EXPECT_EQ(kIPv6AddressSize
, endpoint
.address().size());
660 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
663 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv4HasNoFallback
) {
664 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
667 host_resolver_
.get(),
668 &client_socket_factory_
,
671 client_socket_factory_
.set_default_client_socket_type(
672 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET
);
674 // Resolve an AddressList with only IPv4 addresses.
675 host_resolver_
->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
677 TestCompletionCallback callback
;
678 ClientSocketHandle handle
;
680 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
681 EXPECT_EQ(ERR_IO_PENDING
, rv
);
682 EXPECT_FALSE(handle
.is_initialized());
683 EXPECT_FALSE(handle
.socket());
685 EXPECT_EQ(OK
, callback
.WaitForResult());
686 EXPECT_TRUE(handle
.is_initialized());
687 EXPECT_TRUE(handle
.socket());
689 handle
.socket()->GetLocalAddress(&endpoint
);
690 EXPECT_EQ(kIPv4AddressSize
, endpoint
.address().size());
691 EXPECT_EQ(1, client_socket_factory_
.allocation_count());
694 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
695 // proceeed immediately.
696 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6InstantFail
) {
697 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
700 host_resolver_
.get(),
701 &client_socket_factory_
,
704 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
705 // First IPv6 socket.
706 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
,
707 // Second IPv6 socket.
708 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
,
709 // This is the IPv4 socket.
710 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
712 client_socket_factory_
.set_client_socket_types(case_types
,
713 arraysize(case_types
));
715 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
716 host_resolver_
->rules()->AddIPLiteralRule(
717 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
718 host_resolver_
->set_synchronous_mode(true);
719 TestCompletionCallback callback
;
720 ClientSocketHandle handle
;
722 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
724 ASSERT_TRUE(handle
.socket());
727 handle
.socket()->GetPeerAddress(&endpoint
);
728 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
731 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
732 // connections proceed immediately.
733 TEST_F(WebSocketTransportClientSocketPoolTest
, IPv6RapidFail
) {
734 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
737 host_resolver_
.get(),
738 &client_socket_factory_
,
741 MockTransportClientSocketFactory::ClientSocketType case_types
[] = {
742 // First IPv6 socket.
743 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
,
744 // Second IPv6 socket.
745 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET
,
746 // This is the IPv4 socket.
747 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
749 client_socket_factory_
.set_client_socket_types(case_types
,
750 arraysize(case_types
));
752 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
753 host_resolver_
->rules()->AddIPLiteralRule(
754 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
756 TestCompletionCallback callback
;
757 ClientSocketHandle handle
;
759 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
760 EXPECT_EQ(ERR_IO_PENDING
, rv
);
761 EXPECT_FALSE(handle
.socket());
763 base::Time
start(base::Time::NowFromSystemTime());
764 EXPECT_EQ(OK
, callback
.WaitForResult());
765 EXPECT_LT(base::Time::NowFromSystemTime() - start
,
766 base::TimeDelta::FromMilliseconds(
767 TransportConnectJobHelper::kIPv6FallbackTimerInMs
));
768 ASSERT_TRUE(handle
.socket());
771 handle
.socket()->GetPeerAddress(&endpoint
);
772 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
775 // If two sockets connect successfully, the one which connected first wins (this
776 // can only happen if the sockets are different types, since sockets of the same
777 // type do not race).
778 TEST_F(WebSocketTransportClientSocketPoolTest
, FirstSuccessWins
) {
779 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
782 host_resolver_
.get(),
783 &client_socket_factory_
,
786 client_socket_factory_
.set_default_client_socket_type(
787 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET
);
789 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
790 host_resolver_
->rules()->AddIPLiteralRule(
791 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
793 TestCompletionCallback callback
;
794 ClientSocketHandle handle
;
796 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
797 EXPECT_EQ(ERR_IO_PENDING
, rv
);
798 ASSERT_FALSE(handle
.socket());
800 base::Closure ipv6_connect_trigger
=
801 client_socket_factory_
.WaitForTriggerableSocketCreation();
802 base::Closure ipv4_connect_trigger
=
803 client_socket_factory_
.WaitForTriggerableSocketCreation();
805 ipv4_connect_trigger
.Run();
806 ipv6_connect_trigger
.Run();
808 EXPECT_EQ(OK
, callback
.WaitForResult());
809 ASSERT_TRUE(handle
.socket());
812 handle
.socket()->GetPeerAddress(&endpoint
);
813 EXPECT_EQ("2.2.2.2", endpoint
.ToStringWithoutPort());
816 // We should not report failure until all connections have failed.
817 TEST_F(WebSocketTransportClientSocketPoolTest
, LastFailureWins
) {
818 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
821 host_resolver_
.get(),
822 &client_socket_factory_
,
825 client_socket_factory_
.set_default_client_socket_type(
826 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET
);
827 base::TimeDelta delay
= base::TimeDelta::FromMilliseconds(
828 TransportConnectJobHelper::kIPv6FallbackTimerInMs
/ 3);
829 client_socket_factory_
.set_delay(delay
);
831 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
832 host_resolver_
->rules()->AddIPLiteralRule("*",
833 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
834 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
838 // Expected order of events:
839 // After 100ms: Connect to 1:abcd::3:4:ff times out
840 // After 200ms: Connect to 2:abcd::3:4:ff times out
841 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
842 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
843 // After 500ms: Connect to 2.2.2.2 times out
845 TestCompletionCallback callback
;
846 ClientSocketHandle handle
;
847 base::Time
start(base::Time::NowFromSystemTime());
849 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
850 EXPECT_EQ(ERR_IO_PENDING
, rv
);
852 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
854 EXPECT_GE(base::Time::NowFromSystemTime() - start
, delay
* 5);
857 // Global timeout for all connects applies. This test is disabled by default
858 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
860 TEST_F(WebSocketTransportClientSocketPoolTest
, DISABLED_OverallTimeoutApplies
) {
861 WebSocketTransportClientSocketPool
pool(kMaxSockets
,
864 host_resolver_
.get(),
865 &client_socket_factory_
,
867 const base::TimeDelta connect_job_timeout
= pool
.ConnectionTimeout();
869 client_socket_factory_
.set_default_client_socket_type(
870 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET
);
871 client_socket_factory_
.set_delay(base::TimeDelta::FromSeconds(1) +
872 connect_job_timeout
/ 6);
874 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 addresses.
875 host_resolver_
->rules()->AddIPLiteralRule("*",
876 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
877 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
878 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
879 "1.1.1.1,2.2.2.2,3.3.3.3,"
880 "4.4.4.4,5.5.5.5,6.6.6.6",
883 TestCompletionCallback callback
;
884 ClientSocketHandle handle
;
887 handle
.Init("a", params_
, LOW
, callback
.callback(), &pool
, BoundNetLog());
888 EXPECT_EQ(ERR_IO_PENDING
, rv
);
890 EXPECT_EQ(ERR_TIMED_OUT
, callback
.WaitForResult());
893 TEST_F(WebSocketTransportClientSocketPoolTest
, MaxSocketsEnforced
) {
894 host_resolver_
->set_synchronous_mode(true);
895 for (int i
= 0; i
< kMaxSockets
; ++i
) {
896 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
897 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
899 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
902 TEST_F(WebSocketTransportClientSocketPoolTest
, MaxSocketsEnforcedWhenPending
) {
903 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
904 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
906 // Now there are 32 sockets waiting to connect, and one stalled.
907 for (int i
= 0; i
< kMaxSockets
; ++i
) {
908 base::RunLoop().RunUntilIdle();
909 EXPECT_TRUE(request(i
)->handle()->is_initialized());
910 EXPECT_TRUE(request(i
)->handle()->socket());
911 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
913 // Now there are 32 sockets connected, and one stalled.
914 base::RunLoop().RunUntilIdle();
915 EXPECT_FALSE(request(kMaxSockets
)->handle()->is_initialized());
916 EXPECT_FALSE(request(kMaxSockets
)->handle()->socket());
919 TEST_F(WebSocketTransportClientSocketPoolTest
, StalledSocketReleased
) {
920 host_resolver_
->set_synchronous_mode(true);
921 for (int i
= 0; i
< kMaxSockets
; ++i
) {
922 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
923 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i
)->handle());
926 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
927 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE
);
928 EXPECT_TRUE(request(kMaxSockets
)->handle()->is_initialized());
929 EXPECT_TRUE(request(kMaxSockets
)->handle()->socket());
932 TEST_F(WebSocketTransportClientSocketPoolTest
, IsStalledTrueWhenStalled
) {
933 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
934 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
936 EXPECT_EQ(OK
, request(0)->WaitForResult());
937 EXPECT_TRUE(pool_
.IsStalled());
940 TEST_F(WebSocketTransportClientSocketPoolTest
,
941 CancellingPendingSocketUnstallsStalledSocket
) {
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 request(1)->handle()->Reset();
947 base::RunLoop().RunUntilIdle();
948 EXPECT_FALSE(pool_
.IsStalled());
951 TEST_F(WebSocketTransportClientSocketPoolTest
,
952 LoadStateOfStalledSocketIsWaitingForAvailableSocket
) {
953 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
954 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
956 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET
,
957 pool_
.GetLoadState("a", request(kMaxSockets
)->handle()));
960 TEST_F(WebSocketTransportClientSocketPoolTest
,
961 CancellingStalledSocketUnstallsPool
) {
962 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
963 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
965 request(kMaxSockets
)->handle()->Reset();
966 EXPECT_FALSE(pool_
.IsStalled());
969 TEST_F(WebSocketTransportClientSocketPoolTest
,
970 FlushWithErrorFlushesPendingConnections
) {
971 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
972 pool_
.FlushWithError(ERR_FAILED
);
973 EXPECT_EQ(ERR_FAILED
, request(0)->WaitForResult());
976 TEST_F(WebSocketTransportClientSocketPoolTest
,
977 FlushWithErrorFlushesStalledConnections
) {
978 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
979 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
981 pool_
.FlushWithError(ERR_FAILED
);
982 EXPECT_EQ(ERR_FAILED
, request(kMaxSockets
)->WaitForResult());
985 TEST_F(WebSocketTransportClientSocketPoolTest
,
986 AfterFlushWithErrorCanMakeNewConnections
) {
987 for (int i
= 0; i
< kMaxSockets
+ 1; ++i
) {
988 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
990 pool_
.FlushWithError(ERR_FAILED
);
991 host_resolver_
->set_synchronous_mode(true);
992 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
995 // Deleting pending connections can release the lock on the endpoint, which can
996 // in principle lead to other pending connections succeeding. However, when we
997 // call FlushWithError(), everything should fail.
998 TEST_F(WebSocketTransportClientSocketPoolTest
,
999 FlushWithErrorDoesNotCauseSuccessfulConnections
) {
1000 host_resolver_
->set_synchronous_mode(true);
1001 MockTransportClientSocketFactory::ClientSocketType first_type
[] = {
1003 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
1005 client_socket_factory_
.set_client_socket_types(first_type
,
1006 arraysize(first_type
));
1007 // The rest of the sockets will connect synchronously.
1008 client_socket_factory_
.set_default_client_socket_type(
1009 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
);
1010 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1011 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1013 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in
1014 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the
1015 // lock, they will synchronously connect.
1016 pool_
.FlushWithError(ERR_FAILED
);
1017 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1018 EXPECT_EQ(ERR_FAILED
, request(i
)->WaitForResult());
1022 // This is a regression test for the first attempted fix for
1023 // FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can
1024 // have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for
1025 // the lock at the same time.
1026 TEST_F(WebSocketTransportClientSocketPoolTest
,
1027 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes
) {
1028 host_resolver_
->set_synchronous_mode(true);
1029 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have
1031 std::vector
<MockTransportClientSocketFactory::ClientSocketType
> socket_types(
1033 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
);
1034 client_socket_factory_
.set_client_socket_types(&socket_types
[0],
1035 socket_types
.size());
1036 // The rest of the sockets will connect synchronously.
1037 client_socket_factory_
.set_default_client_socket_type(
1038 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
);
1039 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1040 host_resolver_
->rules()->ClearRules();
1041 // Each connect job has a different IPv6 address but the same IPv4 address.
1042 // So the IPv6 connections happen in parallel but the IPv4 ones are
1044 host_resolver_
->rules()->AddIPLiteralRule("*",
1050 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1052 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
1054 RunLoopForTimePeriod(base::TimeDelta::FromMilliseconds(
1055 TransportConnectJobHelper::kIPv6FallbackTimerInMs
));
1056 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
1057 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
1058 pool_
.FlushWithError(ERR_FAILED
);
1059 for (int i
= 0; i
< kMaxSockets
; ++i
) {
1060 EXPECT_EQ(ERR_FAILED
, request(i
)->WaitForResult());
1064 // Sockets that have had ownership transferred to a ClientSocketHandle should
1065 // not be affected by FlushWithError.
1066 TEST_F(WebSocketTransportClientSocketPoolTest
,
1067 FlushWithErrorDoesNotAffectHandedOutSockets
) {
1068 host_resolver_
->set_synchronous_mode(true);
1069 MockTransportClientSocketFactory::ClientSocketType socket_types
[] = {
1070 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
,
1071 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
};
1072 client_socket_factory_
.set_client_socket_types(socket_types
,
1073 arraysize(socket_types
));
1074 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1075 // Socket has been "handed out".
1076 EXPECT_TRUE(request(0)->handle()->socket());
1078 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1079 // Now we have one socket handed out, and one pending.
1080 pool_
.FlushWithError(ERR_FAILED
);
1081 EXPECT_EQ(ERR_FAILED
, request(1)->WaitForResult());
1082 // Socket owned by ClientSocketHandle is unaffected:
1083 EXPECT_TRUE(request(0)->handle()->socket());
1084 // Return it to the pool (which deletes it).
1085 request(0)->handle()->Reset();
1088 // Sockets should not be leaked if CancelRequest() is called in between
1089 // SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
1090 TEST_F(WebSocketTransportClientSocketPoolTest
, CancelRequestReclaimsSockets
) {
1091 host_resolver_
->set_synchronous_mode(true);
1092 MockTransportClientSocketFactory::ClientSocketType socket_types
[] = {
1093 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET
,
1094 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
};
1096 client_socket_factory_
.set_client_socket_types(socket_types
,
1097 arraysize(socket_types
));
1099 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1101 base::Closure connect_trigger
=
1102 client_socket_factory_
.WaitForTriggerableSocketCreation();
1104 connect_trigger
.Run(); // Calls InvokeUserCallbackLater()
1106 request(0)->handle()->Reset(); // calls CancelRequest()
1108 // We should now be able to create a new connection without blocking on the
1110 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1113 // A handshake completing and then the WebSocket closing should only release one
1114 // Endpoint, not two.
1115 TEST_F(WebSocketTransportClientSocketPoolTest
, EndpointLockIsOnlyReleasedOnce
) {
1116 host_resolver_
->set_synchronous_mode(true);
1117 EXPECT_EQ(OK
, StartRequest("a", kDefaultPriority
));
1118 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1119 EXPECT_EQ(ERR_IO_PENDING
, StartRequest("a", kDefaultPriority
));
1120 // First socket completes handshake.
1121 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
1122 // First socket is closed.
1123 request(0)->handle()->Reset();
1124 // Second socket should have been released.
1125 EXPECT_EQ(OK
, request(1)->WaitForResult());
1126 // Third socket should still be waiting for endpoint.
1127 ASSERT_FALSE(request(2)->handle()->is_initialized());
1128 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET
,
1129 request(2)->handle()->GetLoadState());