1// Copyright (c) 2006-2008 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/tcp_client_socket_pool.h"
6
7#include "base/compiler_specific.h"
8#include "base/message_loop.h"
9#include "net/base/mock_host_resolver.h"
10#include "net/base/mock_network_change_notifier.h"
11#include "net/base/net_errors.h"
12#include "net/base/test_completion_callback.h"
13#include "net/socket/client_socket.h"
14#include "net/socket/client_socket_factory.h"
15#include "net/socket/client_socket_handle.h"
16#include "net/socket/socket_test_util.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19namespace net {
20
21namespace {
22
23const int kMaxSockets = 32;
24const int kMaxSocketsPerGroup = 6;
25const net::RequestPriority kDefaultPriority = LOW;
26
27class MockClientSocket : public ClientSocket {
28 public:
29  MockClientSocket() : connected_(false) {}
30
31  // ClientSocket methods:
32  virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
33    connected_ = true;
34    return OK;
35  }
36  virtual void Disconnect() {
37    connected_ = false;
38  }
39  virtual bool IsConnected() const {
40    return connected_;
41  }
42  virtual bool IsConnectedAndIdle() const {
43    return connected_;
44  }
45  virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen) {
46    return ERR_UNEXPECTED;
47  }
48
49  // Socket methods:
50  virtual int Read(IOBuffer* buf, int buf_len,
51                   CompletionCallback* callback) {
52    return ERR_FAILED;
53  }
54  virtual int Write(IOBuffer* buf, int buf_len,
55                    CompletionCallback* callback) {
56    return ERR_FAILED;
57  }
58  virtual bool SetReceiveBufferSize(int32 size) { return true; }
59  virtual bool SetSendBufferSize(int32 size) { return true; }
60
61 private:
62  bool connected_;
63};
64
65class MockFailingClientSocket : public ClientSocket {
66 public:
67  MockFailingClientSocket() {}
68
69  // ClientSocket methods:
70  virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
71    return ERR_CONNECTION_FAILED;
72  }
73
74  virtual void Disconnect() {}
75
76  virtual bool IsConnected() const {
77    return false;
78  }
79  virtual bool IsConnectedAndIdle() const {
80    return false;
81  }
82  virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen) {
83    return ERR_UNEXPECTED;
84  }
85
86  // Socket methods:
87  virtual int Read(IOBuffer* buf, int buf_len,
88                   CompletionCallback* callback) {
89    return ERR_FAILED;
90  }
91
92  virtual int Write(IOBuffer* buf, int buf_len,
93                    CompletionCallback* callback) {
94    return ERR_FAILED;
95  }
96  virtual bool SetReceiveBufferSize(int32 size) { return true; }
97  virtual bool SetSendBufferSize(int32 size) { return true; }
98};
99
100class MockPendingClientSocket : public ClientSocket {
101 public:
102  MockPendingClientSocket(bool should_connect)
103      : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
104        should_connect_(should_connect),
105        is_connected_(false) {}
106
107  // ClientSocket methods:
108  virtual int Connect(CompletionCallback* callback, LoadLog* /* load_log */) {
109    MessageLoop::current()->PostTask(
110        FROM_HERE,
111        method_factory_.NewRunnableMethod(
112           &MockPendingClientSocket::DoCallback, callback));
113    return ERR_IO_PENDING;
114  }
115
116  virtual void Disconnect() {}
117
118  virtual bool IsConnected() const {
119    return is_connected_;
120  }
121  virtual bool IsConnectedAndIdle() const {
122    return is_connected_;
123  }
124  virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen) {
125    return ERR_UNEXPECTED;
126  }
127
128  // Socket methods:
129  virtual int Read(IOBuffer* buf, int buf_len,
130                   CompletionCallback* callback) {
131    return ERR_FAILED;
132  }
133
134  virtual int Write(IOBuffer* buf, int buf_len,
135                    CompletionCallback* callback) {
136    return ERR_FAILED;
137  }
138  virtual bool SetReceiveBufferSize(int32 size) { return true; }
139  virtual bool SetSendBufferSize(int32 size) { return true; }
140
141 private:
142  void DoCallback(CompletionCallback* callback) {
143    if (should_connect_) {
144      is_connected_ = true;
145      callback->Run(OK);
146    } else {
147      is_connected_ = false;
148      callback->Run(ERR_CONNECTION_FAILED);
149    }
150  }
151
152  ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_;
153  bool should_connect_;
154  bool is_connected_;
155};
156
157class MockClientSocketFactory : public ClientSocketFactory {
158 public:
159  enum ClientSocketType {
160    MOCK_CLIENT_SOCKET,
161    MOCK_FAILING_CLIENT_SOCKET,
162    MOCK_PENDING_CLIENT_SOCKET,
163    MOCK_PENDING_FAILING_CLIENT_SOCKET,
164  };
165
166  MockClientSocketFactory()
167      : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET) {}
168
169  virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
170    allocation_count_++;
171    switch (client_socket_type_) {
172      case MOCK_CLIENT_SOCKET:
173        return new MockClientSocket();
174      case MOCK_FAILING_CLIENT_SOCKET:
175        return new MockFailingClientSocket();
176      case MOCK_PENDING_CLIENT_SOCKET:
177        return new MockPendingClientSocket(true);
178      case MOCK_PENDING_FAILING_CLIENT_SOCKET:
179        return new MockPendingClientSocket(false);
180      default:
181        NOTREACHED();
182        return new MockClientSocket();
183    }
184  }
185
186  virtual SSLClientSocket* CreateSSLClientSocket(
187      ClientSocket* transport_socket,
188      const std::string& hostname,
189      const SSLConfig& ssl_config) {
190    NOTIMPLEMENTED();
191    return NULL;
192  }
193
194  int allocation_count() const { return allocation_count_; }
195
196  void set_client_socket_type(ClientSocketType type) {
197    client_socket_type_ = type;
198  }
199
200 private:
201  int allocation_count_;
202  ClientSocketType client_socket_type_;
203};
204
205class TCPClientSocketPoolTest : public ClientSocketPoolTest {
206 protected:
207  TCPClientSocketPoolTest()
208      : ignored_request_info_("ignored", 80),
209        host_resolver_(new MockHostResolver),
210        pool_(new TCPClientSocketPool(kMaxSockets,
211                                      kMaxSocketsPerGroup,
212                                      host_resolver_,
213                                      &client_socket_factory_,
214                                      &notifier_)) {
215  }
216
217  int StartRequest(const std::string& group_name, RequestPriority priority) {
218    return StartRequestUsingPool(
219        pool_.get(), group_name, priority, ignored_request_info_);
220  }
221
222  HostResolver::RequestInfo ignored_request_info_;
223  scoped_refptr<MockHostResolver> host_resolver_;
224  MockClientSocketFactory client_socket_factory_;
225  MockNetworkChangeNotifier notifier_;
226  scoped_refptr<TCPClientSocketPool> pool_;
227};
228
229TEST_F(TCPClientSocketPoolTest, Basic) {
230  TestCompletionCallback callback;
231  ClientSocketHandle handle;
232  HostResolver::RequestInfo info("www.google.com", 80);
233  int rv = handle.Init("a", info, LOW, &callback, pool_.get(), NULL);
234  EXPECT_EQ(ERR_IO_PENDING, rv);
235  EXPECT_FALSE(handle.is_initialized());
236  EXPECT_FALSE(handle.socket());
237
238  EXPECT_EQ(OK, callback.WaitForResult());
239  EXPECT_TRUE(handle.is_initialized());
240  EXPECT_TRUE(handle.socket());
241
242  handle.Reset();
243}
244
245TEST_F(TCPClientSocketPoolTest, InitHostResolutionFailure) {
246  host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
247  TestSocketRequest req(&request_order_, &completion_count_);
248  HostResolver::RequestInfo info("unresolvable.host.name", 80);
249  EXPECT_EQ(ERR_IO_PENDING,
250            req.handle()->Init(
251                "a", info, kDefaultPriority, &req, pool_.get(), NULL));
252  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req.WaitForResult());
253}
254
255TEST_F(TCPClientSocketPoolTest, InitConnectionFailure) {
256  client_socket_factory_.set_client_socket_type(
257      MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
258  TestSocketRequest req(&request_order_, &completion_count_);
259  HostResolver::RequestInfo info("a", 80);
260  EXPECT_EQ(ERR_IO_PENDING,
261            req.handle()->Init(
262                "a", info, kDefaultPriority, &req, pool_.get(), NULL));
263  EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
264
265  // Make the host resolutions complete synchronously this time.
266  host_resolver_->set_synchronous_mode(true);
267  EXPECT_EQ(ERR_CONNECTION_FAILED,
268            req.handle()->Init(
269                "a", info, kDefaultPriority, &req, pool_.get(), NULL));
270}
271
272TEST_F(TCPClientSocketPoolTest, PendingRequests) {
273  // First request finishes asynchronously.
274  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
275  EXPECT_EQ(OK, requests_[0]->WaitForResult());
276
277  // Make all subsequent host resolutions complete synchronously.
278  host_resolver_->set_synchronous_mode(true);
279
280  // Rest of them finish synchronously, until we reach the per-group limit.
281  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
282  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
283  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
284  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
285  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
286
287  // The rest are pending since we've used all active sockets.
288  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
289  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
290  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
291  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
292  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
293  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
294  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
295  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
296  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
297  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
298
299  ReleaseAllConnections(KEEP_ALIVE);
300
301  EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
302
303  // One initial asynchronous request and then 10 pending requests.
304  EXPECT_EQ(11U, completion_count_);
305
306  // First part of requests, all with the same priority, finishes in FIFO order.
307  EXPECT_EQ(1, GetOrderOfRequest(1));
308  EXPECT_EQ(2, GetOrderOfRequest(2));
309  EXPECT_EQ(3, GetOrderOfRequest(3));
310  EXPECT_EQ(4, GetOrderOfRequest(4));
311  EXPECT_EQ(5, GetOrderOfRequest(5));
312  EXPECT_EQ(6, GetOrderOfRequest(6));
313
314  // Make sure that rest of the requests complete in the order of priority.
315  EXPECT_EQ(7, GetOrderOfRequest(7));
316  EXPECT_EQ(14, GetOrderOfRequest(8));
317  EXPECT_EQ(15, GetOrderOfRequest(9));
318  EXPECT_EQ(10, GetOrderOfRequest(10));
319  EXPECT_EQ(13, GetOrderOfRequest(11));
320  EXPECT_EQ(8, GetOrderOfRequest(12));
321  EXPECT_EQ(16, GetOrderOfRequest(13));
322  EXPECT_EQ(11, GetOrderOfRequest(14));
323  EXPECT_EQ(12, GetOrderOfRequest(15));
324  EXPECT_EQ(9, GetOrderOfRequest(16));
325
326  // Make sure we test order of all requests made.
327  EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(17));
328}
329
330TEST_F(TCPClientSocketPoolTest, PendingRequests_NoKeepAlive) {
331  // First request finishes asynchronously.
332  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
333  EXPECT_EQ(OK, requests_[0]->WaitForResult());
334
335  // Make all subsequent host resolutions complete synchronously.
336  host_resolver_->set_synchronous_mode(true);
337
338  // Rest of them finish synchronously, until we reach the per-group limit.
339  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
340  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
341  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
342  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
343  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
344
345  // The rest are pending since we've used all active sockets.
346  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
347  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
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
352  ReleaseAllConnections(NO_KEEP_ALIVE);
353
354  // The pending requests should finish successfully.
355  EXPECT_EQ(OK, requests_[6]->WaitForResult());
356  EXPECT_EQ(OK, requests_[7]->WaitForResult());
357  EXPECT_EQ(OK, requests_[8]->WaitForResult());
358  EXPECT_EQ(OK, requests_[9]->WaitForResult());
359  EXPECT_EQ(OK, requests_[10]->WaitForResult());
360
361  EXPECT_EQ(static_cast<int>(requests_.size()),
362            client_socket_factory_.allocation_count());
363
364  // First asynchronous request, and then last 5 pending requests.
365  EXPECT_EQ(6U, completion_count_);
366}
367
368// This test will start up a RequestSocket() and then immediately Cancel() it.
369// The pending host resolution will eventually complete, and destroy the
370// ClientSocketPool which will crash if the group was not cleared properly.
371TEST_F(TCPClientSocketPoolTest, CancelRequestClearGroup) {
372  TestSocketRequest req(&request_order_, &completion_count_);
373  HostResolver::RequestInfo info("www.google.com", 80);
374  EXPECT_EQ(ERR_IO_PENDING,
375            req.handle()->Init(
376                "a", info, kDefaultPriority, &req, pool_.get(), NULL));
377  req.handle()->Reset();
378
379  // There is a race condition here.  If the worker pool doesn't post the task
380  // before we get here, then this might not run ConnectingSocket::OnIOComplete
381  // and therefore leak the canceled ConnectingSocket.  However, other tests
382  // after this will call MessageLoop::RunAllPending() which should prevent a
383  // leak, unless the worker thread takes longer than all of them.
384  PlatformThread::Sleep(10);
385  MessageLoop::current()->RunAllPending();
386}
387
388TEST_F(TCPClientSocketPoolTest, TwoRequestsCancelOne) {
389  TestSocketRequest req(&request_order_, &completion_count_);
390  TestSocketRequest req2(&request_order_, &completion_count_);
391
392  HostResolver::RequestInfo info("www.google.com", 80);
393  EXPECT_EQ(ERR_IO_PENDING,
394            req.handle()->Init(
395                "a", info, kDefaultPriority, &req, pool_.get(), NULL));
396  EXPECT_EQ(ERR_IO_PENDING,
397            req2.handle()->Init(
398                "a", info, kDefaultPriority, &req2, pool_.get(), NULL));
399
400  req.handle()->Reset();
401
402  EXPECT_EQ(OK, req2.WaitForResult());
403  req2.handle()->Reset();
404}
405
406TEST_F(TCPClientSocketPoolTest, ConnectCancelConnect) {
407  client_socket_factory_.set_client_socket_type(
408      MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
409  ClientSocketHandle handle;
410  TestCompletionCallback callback;
411  TestSocketRequest req(&request_order_, &completion_count_);
412
413  HostResolver::RequestInfo info("www.google.com", 80);
414  EXPECT_EQ(ERR_IO_PENDING,
415            handle.Init(
416                "a", info, kDefaultPriority, &callback, pool_.get(), NULL));
417
418  handle.Reset();
419
420  TestCompletionCallback callback2;
421  EXPECT_EQ(ERR_IO_PENDING,
422            handle.Init(
423                "a", info, kDefaultPriority, &callback2, pool_.get(), NULL));
424
425  host_resolver_->set_synchronous_mode(true);
426  // At this point, handle has two ConnectingSockets out for it.  Due to the
427  // setting the mock resolver into synchronous mode, the host resolution for
428  // both will return in the same loop of the MessageLoop.  The client socket
429  // is a pending socket, so the Connect() will asynchronously complete on the
430  // next loop of the MessageLoop.  That means that the first
431  // ConnectingSocket will enter OnIOComplete, and then the second one will.
432  // If the first one is not cancelled, it will advance the load state, and
433  // then the second one will crash.
434
435  EXPECT_EQ(OK, callback2.WaitForResult());
436  EXPECT_FALSE(callback.have_result());
437
438  handle.Reset();
439}
440
441TEST_F(TCPClientSocketPoolTest, CancelRequest) {
442  // First request finishes asynchronously.
443  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
444  EXPECT_EQ(OK, requests_[0]->WaitForResult());
445
446  // Make all subsequent host resolutions complete synchronously.
447  host_resolver_->set_synchronous_mode(true);
448
449  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
450  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
451  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
452  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
453  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
454
455  // Reached per-group limit, queue up requests.
456  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
457  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
458  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
459  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
460  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
461  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
462  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
463  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
464  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
465  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
466
467  // Cancel a request.
468  size_t index_to_cancel = kMaxSocketsPerGroup + 2;
469  EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
470  requests_[index_to_cancel]->handle()->Reset();
471
472  ReleaseAllConnections(KEEP_ALIVE);
473
474  EXPECT_EQ(kMaxSocketsPerGroup,
475            client_socket_factory_.allocation_count());
476  EXPECT_EQ(requests_.size() - kMaxSocketsPerGroup, completion_count_);
477
478  EXPECT_EQ(1, GetOrderOfRequest(1));
479  EXPECT_EQ(2, GetOrderOfRequest(2));
480  EXPECT_EQ(3, GetOrderOfRequest(3));
481  EXPECT_EQ(4, GetOrderOfRequest(4));
482  EXPECT_EQ(5, GetOrderOfRequest(5));
483  EXPECT_EQ(6, GetOrderOfRequest(6));
484  EXPECT_EQ(14, GetOrderOfRequest(7));
485  EXPECT_EQ(7, GetOrderOfRequest(8));
486  EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(9));  // Canceled request.
487  EXPECT_EQ(9, GetOrderOfRequest(10));
488  EXPECT_EQ(10, GetOrderOfRequest(11));
489  EXPECT_EQ(11, GetOrderOfRequest(12));
490  EXPECT_EQ(8, GetOrderOfRequest(13));
491  EXPECT_EQ(12, GetOrderOfRequest(14));
492  EXPECT_EQ(13, GetOrderOfRequest(15));
493  EXPECT_EQ(15, GetOrderOfRequest(16));
494
495  // Make sure we test order of all requests made.
496  EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(17));
497}
498
499class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
500 public:
501  RequestSocketCallback(ClientSocketHandle* handle, TCPClientSocketPool* pool)
502      : handle_(handle),
503        pool_(pool),
504        within_callback_(false) {}
505
506  virtual void RunWithParams(const Tuple1<int>& params) {
507    callback_.RunWithParams(params);
508    ASSERT_EQ(OK, params.a);
509
510    if (!within_callback_) {
511      // Don't allow reuse of the socket.  Disconnect it and then release it and
512      // run through the MessageLoop once to get it completely released.
513      handle_->socket()->Disconnect();
514      handle_->Reset();
515      {
516        MessageLoop::ScopedNestableTaskAllower nestable(
517            MessageLoop::current());
518        MessageLoop::current()->RunAllPending();
519      }
520      within_callback_ = true;
521      int rv = handle_->Init(
522          "a", HostResolver::RequestInfo("www.google.com", 80), LOWEST,
523          this, pool_.get(), NULL);
524      EXPECT_EQ(OK, rv);
525    }
526  }
527
528  int WaitForResult() {
529    return callback_.WaitForResult();
530  }
531
532 private:
533  ClientSocketHandle* const handle_;
534  const scoped_refptr<TCPClientSocketPool> pool_;
535  bool within_callback_;
536  TestCompletionCallback callback_;
537};
538
539TEST_F(TCPClientSocketPoolTest, RequestTwice) {
540  ClientSocketHandle handle;
541  RequestSocketCallback callback(&handle, pool_.get());
542  int rv = handle.Init(
543      "a", HostResolver::RequestInfo("www.google.com", 80), LOWEST,
544      &callback, pool_.get(), NULL);
545  ASSERT_EQ(ERR_IO_PENDING, rv);
546
547  // The callback is going to request "www.google.com". We want it to complete
548  // synchronously this time.
549  host_resolver_->set_synchronous_mode(true);
550
551  EXPECT_EQ(OK, callback.WaitForResult());
552
553  handle.Reset();
554}
555
556// Make sure that pending requests get serviced after active requests get
557// cancelled.
558TEST_F(TCPClientSocketPoolTest, CancelActiveRequestWithPendingRequests) {
559  client_socket_factory_.set_client_socket_type(
560      MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
561
562  // Queue up all the requests
563  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
564  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
565  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
566  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
567  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
568  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
569  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
570  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
571  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
572
573  // Now, kMaxSocketsPerGroup requests should be active.  Let's cancel them.
574  ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests_.size()));
575  for (int i = 0; i < kMaxSocketsPerGroup; i++)
576    requests_[i]->handle()->Reset();
577
578  // Let's wait for the rest to complete now.
579  for (size_t i = kMaxSocketsPerGroup; i < requests_.size(); ++i) {
580    EXPECT_EQ(OK, requests_[i]->WaitForResult());
581    requests_[i]->handle()->Reset();
582  }
583
584  EXPECT_EQ(requests_.size() - kMaxSocketsPerGroup, completion_count_);
585}
586
587// Make sure that pending requests get serviced after active requests fail.
588TEST_F(TCPClientSocketPoolTest, FailingActiveRequestWithPendingRequests) {
589  client_socket_factory_.set_client_socket_type(
590      MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
591
592  const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
593  ASSERT_LE(kNumRequests, kMaxSockets);  // Otherwise the test will hang.
594
595  // Queue up all the requests
596  for (int i = 0; i < kNumRequests; i++)
597    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
598
599  for (int i = 0; i < kNumRequests; i++)
600    EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
601}
602
603TEST_F(TCPClientSocketPoolTest, ResetIdleSocketsOnIPAddressChange) {
604  TestCompletionCallback callback;
605  ClientSocketHandle handle;
606  HostResolver::RequestInfo info("www.google.com", 80);
607  int rv = handle.Init("a", info, LOW, &callback, pool_.get(), NULL);
608  EXPECT_EQ(ERR_IO_PENDING, rv);
609  EXPECT_FALSE(handle.is_initialized());
610  EXPECT_FALSE(handle.socket());
611
612  EXPECT_EQ(OK, callback.WaitForResult());
613  EXPECT_TRUE(handle.is_initialized());
614  EXPECT_TRUE(handle.socket());
615
616  handle.Reset();
617
618  // Need to run all pending to release the socket back to the pool.
619  MessageLoop::current()->RunAllPending();
620
621  // Now we should have 1 idle socket.
622  EXPECT_EQ(1, pool_->IdleSocketCount());
623
624  // After an IP address change, we should have 0 idle sockets.
625  notifier_.NotifyIPAddressChange();
626  EXPECT_EQ(0, pool_->IdleSocketCount());
627}
628
629}  // namespace
630
631}  // namespace net
632