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