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