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.
4
5#include "net/socket/websocket_transport_client_socket_pool.h"
6
7#include <queue>
8#include <vector>
9
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"
33
34namespace net {
35
36namespace {
37
38const int kMaxSockets = 32;
39const int kMaxSocketsPerGroup = 6;
40const RequestPriority kDefaultPriority = LOW;
41
42// RunLoop doesn't support this natively but it is easy to emulate.
43void 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();
49}
50
51class 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) {}
69
70  virtual ~WebSocketTransportClientSocketPoolTest() {
71    ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
72    EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
73  }
74
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);
85  }
86
87  int GetOrderOfRequest(size_t index) {
88    return test_base_.GetOrderOfRequest(index);
89  }
90
91  bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
92    return test_base_.ReleaseOneConnection(keep_alive);
93  }
94
95  void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
96    test_base_.ReleaseAllConnections(keep_alive);
97  }
98
99  TestSocketRequest* request(int i) { return test_base_.request(i); }
100
101  ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
102  size_t completion_count() const { return test_base_.completion_count(); }
103
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_;
111
112 private:
113  DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest);
114};
115
116TEST_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());
124
125  EXPECT_EQ(OK, callback.WaitForResult());
126  EXPECT_TRUE(handle.is_initialized());
127  EXPECT_TRUE(handle.socket());
128  TestLoadTimingInfoConnectedNotReused(handle);
129}
130
131// Make sure that WebSocketTransportConnectJob passes on its priority to its
132// HostResolver request on Init.
133TEST_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());
146  }
147}
148
149TEST_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());
165}
166
167TEST_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());
180
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()));
190}
191
192TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
193  // First request finishes asynchronously.
194  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
195  EXPECT_EQ(OK, request(0)->WaitForResult());
196
197  // Make all subsequent host resolutions complete synchronously.
198  host_resolver_->set_synchronous_mode(true);
199
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));
206
207  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
208
209  EXPECT_EQ(6, client_socket_factory_.allocation_count());
210
211  // One initial asynchronous request and then 5 pending requests.
212  EXPECT_EQ(6U, completion_count());
213
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));
221
222  // Make sure we test order of all requests made.
223  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
224}
225
226TEST_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());
230
231  // Make all subsequent host resolutions complete synchronously.
232  host_resolver_->set_synchronous_mode(true);
233
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));
240
241  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
242
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());
249
250  EXPECT_EQ(static_cast<int>(requests()->size()),
251            client_socket_factory_.allocation_count());
252
253  // First asynchronous request, and then last 5 pending requests.
254  EXPECT_EQ(6U, completion_count());
255}
256
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.
260TEST_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();
271}
272
273TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
274  ClientSocketHandle handle;
275  TestCompletionCallback callback;
276  ClientSocketHandle handle2;
277  TestCompletionCallback callback2;
278
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()));
293
294  handle.Reset();
295
296  EXPECT_EQ(OK, callback2.WaitForResult());
297  handle2.Reset();
298}
299
300TEST_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()));
312
313  handle.Reset();
314
315  TestCompletionCallback callback2;
316  EXPECT_EQ(ERR_IO_PENDING,
317            handle.Init("a",
318                        params_,
319                        kDefaultPriority,
320                        callback2.callback(),
321                        &pool_,
322                        BoundNetLog()));
323
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.
333
334  EXPECT_EQ(OK, callback2.WaitForResult());
335  EXPECT_FALSE(callback.have_result());
336
337  handle.Reset();
338}
339
340TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
341  // First request finishes asynchronously.
342  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
343  EXPECT_EQ(OK, request(0)->WaitForResult());
344
345  // Make all subsequent host resolutions complete synchronously.
346  host_resolver_->set_synchronous_mode(true);
347
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));
353
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();
358
359  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
360
361  EXPECT_EQ(5, client_socket_factory_.allocation_count());
362
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));
370
371  // Make sure we test order of all requests made.
372  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
373}
374
375class 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))) {}
384
385  virtual ~RequestSocketCallback() {}
386
387  const CompletionCallback& callback() const { return callback_; }
388
389 private:
390  void OnComplete(int result) {
391    SetResult(result);
392    ASSERT_EQ(OK, result);
393
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();
399      {
400        base::MessageLoop::ScopedNestableTaskAllower allow(
401            base::MessageLoop::current());
402        base::MessageLoop::current()->RunUntilIdle();
403      }
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);
415    }
416  }
417
418  ClientSocketHandle* const handle_;
419  WebSocketTransportClientSocketPool* const pool_;
420  bool within_callback_;
421  CompletionCallback callback_;
422
423  DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback);
424};
425
426TEST_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);
439
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);
443
444  EXPECT_EQ(OK, callback.WaitForResult());
445
446  handle.Reset();
447}
448
449// Make sure that pending requests get serviced after active requests get
450// cancelled.
451TEST_F(WebSocketTransportClientSocketPoolTest,
452       CancelActiveRequestWithPendingRequests) {
453  client_socket_factory_.set_default_client_socket_type(
454      MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
455
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));
466
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();
471
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();
476  }
477
478  EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
479}
480
481// Make sure that pending requests get serviced after active requests fail.
482TEST_F(WebSocketTransportClientSocketPoolTest,
483       FailingActiveRequestWithPendingRequests) {
484  client_socket_factory_.set_default_client_socket_type(
485      MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
486
487  const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
488  ASSERT_LE(kNumRequests, kMaxSockets);  // Otherwise the test will hang.
489
490  // Queue up all the requests
491  for (int i = 0; i < kNumRequests; i++)
492    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
493
494  for (int i = 0; i < kNumRequests; i++)
495    EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
496}
497
498// The lock on the endpoint is released when a ClientSocketHandle is reset.
499TEST_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());
507}
508
509// The lock on the endpoint is released when a ClientSocketHandle is deleted.
510TEST_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);
516
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());
523}
524
525// A new connection is performed when the lock on the previous connection is
526// explicitly released.
527TEST_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());
536}
537
538// A connection which is cancelled before completion does not block subsequent
539// connections.
540TEST_F(WebSocketTransportClientSocketPoolTest,
541       CancelDuringConnectionReleasesLock) {
542  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
543      MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
544      MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
545
546  client_socket_factory_.set_client_socket_types(case_types,
547                                                 arraysize(case_types));
548
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());
554}
555
556// Test the case of the IPv6 address stalling, and falling back to the IPv4
557// socket which finishes first.
558TEST_F(WebSocketTransportClientSocketPoolTest,
559       IPv6FallbackSocketIPv4FinishesFirst) {
560  WebSocketTransportClientSocketPool pool(kMaxSockets,
561                                          kMaxSocketsPerGroup,
562                                          histograms_.get(),
563                                          host_resolver_.get(),
564                                          &client_socket_factory_,
565                                          NULL);
566
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};
572
573  client_socket_factory_.set_client_socket_types(case_types, 2);
574
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());
578
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());
586
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());
594}
595
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.
599TEST_F(WebSocketTransportClientSocketPoolTest,
600       IPv6FallbackSocketIPv6FinishesFirst) {
601  WebSocketTransportClientSocketPool pool(kMaxSockets,
602                                          kMaxSocketsPerGroup,
603                                          histograms_.get(),
604                                          host_resolver_.get(),
605                                          &client_socket_factory_,
606                                          NULL);
607
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};
613
614  client_socket_factory_.set_client_socket_types(case_types, 2);
615  client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds(
616      TransportConnectJobHelper::kIPv6FallbackTimerInMs + 50));
617
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());
621
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());
629
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());
637}
638
639TEST_F(WebSocketTransportClientSocketPoolTest,
640       IPv6NoIPv4AddressesToFallbackTo) {
641  WebSocketTransportClientSocketPool pool(kMaxSockets,
642                                          kMaxSocketsPerGroup,
643                                          histograms_.get(),
644                                          host_resolver_.get(),
645                                          &client_socket_factory_,
646                                          NULL);
647
648  client_socket_factory_.set_default_client_socket_type(
649      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
650
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());
654
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());
662
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());
670}
671
672TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
673  WebSocketTransportClientSocketPool pool(kMaxSockets,
674                                          kMaxSocketsPerGroup,
675                                          histograms_.get(),
676                                          host_resolver_.get(),
677                                          &client_socket_factory_,
678                                          NULL);
679
680  client_socket_factory_.set_default_client_socket_type(
681      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
682
683  // Resolve an AddressList with only IPv4 addresses.
684  host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
685
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());
693
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());
701}
702
703// If all IPv6 addresses fail to connect synchronously, then IPv4 connections
704// proceeed immediately.
705TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
706  WebSocketTransportClientSocketPool pool(kMaxSockets,
707                                          kMaxSocketsPerGroup,
708                                          histograms_.get(),
709                                          host_resolver_.get(),
710                                          &client_socket_factory_,
711                                          NULL);
712
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};
720
721  client_socket_factory_.set_client_socket_types(case_types,
722                                                 arraysize(case_types));
723
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());
734
735  IPEndPoint endpoint;
736  handle.socket()->GetPeerAddress(&endpoint);
737  EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
738}
739
740// If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
741// connections proceed immediately.
742TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
743  WebSocketTransportClientSocketPool pool(kMaxSockets,
744                                          kMaxSocketsPerGroup,
745                                          histograms_.get(),
746                                          host_resolver_.get(),
747                                          &client_socket_factory_,
748                                          NULL);
749
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};
757
758  client_socket_factory_.set_client_socket_types(case_types,
759                                                 arraysize(case_types));
760
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());
764
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());
771
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());
778
779  IPEndPoint endpoint;
780  handle.socket()->GetPeerAddress(&endpoint);
781  EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
782}
783
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).
787TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
788  WebSocketTransportClientSocketPool pool(kMaxSockets,
789                                          kMaxSocketsPerGroup,
790                                          histograms_.get(),
791                                          host_resolver_.get(),
792                                          &client_socket_factory_,
793                                          NULL);
794
795  client_socket_factory_.set_default_client_socket_type(
796      MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
797
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());
801
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());
808
809  base::Closure ipv6_connect_trigger =
810      client_socket_factory_.WaitForTriggerableSocketCreation();
811  base::Closure ipv4_connect_trigger =
812      client_socket_factory_.WaitForTriggerableSocketCreation();
813
814  ipv4_connect_trigger.Run();
815  ipv6_connect_trigger.Run();
816
817  EXPECT_EQ(OK, callback.WaitForResult());
818  ASSERT_TRUE(handle.socket());
819
820  IPEndPoint endpoint;
821  handle.socket()->GetPeerAddress(&endpoint);
822  EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
823}
824
825// We should not report failure until all connections have failed.
826TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
827  WebSocketTransportClientSocketPool pool(kMaxSockets,
828                                          kMaxSocketsPerGroup,
829                                          histograms_.get(),
830                                          host_resolver_.get(),
831                                          &client_socket_factory_,
832                                          NULL);
833
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);
839
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());
846
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
853
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);
860
861  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
862
863  EXPECT_GE(base::Time::NowFromSystemTime() - start, delay * 5);
864}
865
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.
869TEST_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();
877
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);
882
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());
891
892  TestCompletionCallback callback;
893  ClientSocketHandle handle;
894
895  int rv =
896      handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
897  EXPECT_EQ(ERR_IO_PENDING, rv);
898
899  EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult());
900}
901
902TEST_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());
907  }
908  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
909}
910
911TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
912  for (int i = 0; i < kMaxSockets + 1; ++i) {
913    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
914  }
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());
921  }
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());
926}
927
928TEST_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());
933  }
934
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());
939}
940
941TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) {
942  for (int i = 0; i < kMaxSockets + 1; ++i) {
943    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
944  }
945  EXPECT_EQ(OK, request(0)->WaitForResult());
946  EXPECT_TRUE(pool_.IsStalled());
947}
948
949TEST_F(WebSocketTransportClientSocketPoolTest,
950       CancellingPendingSocketUnstallsStalledSocket) {
951  for (int i = 0; i < kMaxSockets + 1; ++i) {
952    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
953  }
954  EXPECT_EQ(OK, request(0)->WaitForResult());
955  request(1)->handle()->Reset();
956  base::RunLoop().RunUntilIdle();
957  EXPECT_FALSE(pool_.IsStalled());
958}
959
960TEST_F(WebSocketTransportClientSocketPoolTest,
961       LoadStateOfStalledSocketIsWaitingForAvailableSocket) {
962  for (int i = 0; i < kMaxSockets + 1; ++i) {
963    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
964  }
965  EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
966            pool_.GetLoadState("a", request(kMaxSockets)->handle()));
967}
968
969TEST_F(WebSocketTransportClientSocketPoolTest,
970       CancellingStalledSocketUnstallsPool) {
971  for (int i = 0; i < kMaxSockets + 1; ++i) {
972    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
973  }
974  request(kMaxSockets)->handle()->Reset();
975  EXPECT_FALSE(pool_.IsStalled());
976}
977
978TEST_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());
983}
984
985TEST_F(WebSocketTransportClientSocketPoolTest,
986       FlushWithErrorFlushesStalledConnections) {
987  for (int i = 0; i < kMaxSockets + 1; ++i) {
988    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
989  }
990  pool_.FlushWithError(ERR_FAILED);
991  EXPECT_EQ(ERR_FAILED, request(kMaxSockets)->WaitForResult());
992}
993
994TEST_F(WebSocketTransportClientSocketPoolTest,
995       AfterFlushWithErrorCanMakeNewConnections) {
996  for (int i = 0; i < kMaxSockets + 1; ++i) {
997    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
998  }
999  pool_.FlushWithError(ERR_FAILED);
1000  host_resolver_->set_synchronous_mode(true);
1001  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1002}
1003
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.
1007TEST_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
1013  };
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));
1021  }
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());
1028  }
1029}
1030
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.
1035TEST_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));
1060  }
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());
1070  }
1071}
1072
1073// Sockets that have had ownership transferred to a ClientSocketHandle should
1074// not be affected by FlushWithError.
1075TEST_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());
1086
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();
1095}
1096
1097// Sockets should not be leaked if CancelRequest() is called in between
1098// SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
1099TEST_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};
1104
1105  client_socket_factory_.set_client_socket_types(socket_types,
1106                                                 arraysize(socket_types));
1107
1108  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1109
1110  base::Closure connect_trigger =
1111      client_socket_factory_.WaitForTriggerableSocketCreation();
1112
1113  connect_trigger.Run();  // Calls InvokeUserCallbackLater()
1114
1115  request(0)->handle()->Reset();  // calls CancelRequest()
1116
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));
1120}
1121
1122// A handshake completing and then the WebSocket closing should only release one
1123// Endpoint, not two.
1124TEST_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());
1139}
1140
1141}  // namespace
1142
1143}  // namespace net
1144