1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_pool_base.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/compiler_specific.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_vector.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/platform_thread.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/net_errors.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log_unittest.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/request_priority.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/test_completion_callback.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_response_headers.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_factory.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_handle.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_pool_histograms.h"
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/socket_test_util.h"
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/socket/ssl_host_info.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kDefaultMaxSockets = 4;
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kDefaultMaxSocketsPerGroup = 2;
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst net::RequestPriority kDefaultPriority = MEDIUM;
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestSocketParams : public base::RefCounted<TestSocketParams> {
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool ignore_limits() { return false; }
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCounted<TestSocketParams>;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~TestSocketParams() {}
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockClientSocket : public ClientSocket {
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Socket methods:
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int Read(
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ERR_UNEXPECTED;
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int Write(
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    was_used_to_convey_data_ = true;
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return len;
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool SetReceiveBufferSize(int32 size) { return true; }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool SetSendBufferSize(int32 size) { return true; }
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ClientSocket methods:
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int Connect(CompletionCallback* callback) {
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    connected_ = true;
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return OK;
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void Disconnect() { connected_ = false; }
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual bool IsConnected() const { return connected_; }
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual bool IsConnectedAndIdle() const { return connected_; }
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int GetPeerAddress(AddressList* /* address */) const {
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ERR_UNEXPECTED;
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual int GetLocalAddress(IPEndPoint* /* address */) const {
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ERR_UNEXPECTED;
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual const BoundNetLog& NetLog() const {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net_log_;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void SetSubresourceSpeculation() {}
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void SetOmniboxSpeculation() {}
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual bool UsingTCPFastOpen() const { return false; }
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool connected_;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BoundNetLog net_log_;
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool was_used_to_convey_data_;
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestConnectJob;
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockClientSocketFactory : public ClientSocketFactory {
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockClientSocketFactory() : allocation_count_(0) {}
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ClientSocket* CreateTransportClientSocket(
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const AddressList& addresses,
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NetLog* /* net_log */,
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const NetLog::Source& /*source*/) {
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    allocation_count_++;
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual SSLClientSocket* CreateSSLClientSocket(
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ClientSocketHandle* transport_socket,
1164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      const HostPortPair& host_and_port,
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const SSLConfig& ssl_config,
118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      SSLHostInfo* ssl_host_info,
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      CertVerifier* cert_verifier,
120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      DnsCertProvenanceChecker* dns_cert_checker) {
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTIMPLEMENTED();
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    delete ssl_host_info;
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void ClearSSLSessionCache() {
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    NOTIMPLEMENTED();
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void SignalJobs();
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int allocation_count() const { return allocation_count_; }
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int allocation_count_;
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<TestConnectJob*> waiting_jobs_;
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestConnectJob : public ConnectJob {
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum JobType {
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockJob,
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockFailingJob,
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockPendingJob,
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockPendingFailingJob,
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockWaitingJob,
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    kMockAdvancingLoadStateJob,
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kMockRecoverableJob,
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kMockPendingRecoverableJob,
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kMockAdditionalErrorStateJob,
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kMockPendingAdditionalErrorStateJob,
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The kMockPendingJob uses a slight delay before allowing the connect
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to complete.
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const int kPendingConnectDelay = 2;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJob(JobType job_type,
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 const std::string& group_name,
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 const TestClientSocketPoolBase::Request& request,
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 base::TimeDelta timeout_duration,
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 ConnectJob::Delegate* delegate,
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                 MockClientSocketFactory* client_socket_factory,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NetLog* net_log)
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : ConnectJob(group_name, timeout_duration, delegate,
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        job_type_(job_type),
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        client_socket_factory_(client_socket_factory),
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        load_state_(LOAD_STATE_IDLE),
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        store_additional_error_state_(false) {}
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void Signal() {
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DoConnect(waiting_success_, true /* async */, false /* recoverable */);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual LoadState GetLoadState() const { return load_state_; }
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (store_additional_error_state_) {
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Set all of the additional error state fields in some way.
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      handle->set_is_ssl_error(true);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HttpResponseInfo info;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      info.headers = new HttpResponseHeaders("");
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      handle->set_ssl_error_response_info(info);
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ConnectJob methods:
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int ConnectInternal() {
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AddressList ignored;
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    client_socket_factory_->CreateTransportClientSocket(
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        ignored, NULL, net::NetLog::Source());
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    set_socket(new MockClientSocket());
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    switch (job_type_) {
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockJob:
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return DoConnect(true /* successful */, false /* sync */,
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         false /* recoverable */);
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockFailingJob:
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return DoConnect(false /* error */, false /* sync */,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         false /* recoverable */);
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockPendingJob:
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        set_load_state(LOAD_STATE_CONNECTING);
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // Depending on execution timings, posting a delayed task can result
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // in the task getting executed the at the earliest possible
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // opportunity or only after returning once from the message loop and
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // then a second call into the message loop. In order to make behavior
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // more deterministic, we change the default delay to 2ms. This should
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // always require us to wait for the second call into the message loop.
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        //
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // N.B. The correct fix for this and similar timing problems is to
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // abstract time for the purpose of unittests. Unfortunately, we have
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // a lot of third-party components that directly call the various
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // time functions, so this change would be rather invasive.
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        MessageLoop::current()->PostDelayedTask(
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            FROM_HERE,
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            method_factory_.NewRunnableMethod(
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                &TestConnectJob::DoConnect,
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                true /* successful */,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true /* async */,
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                false /* recoverable */),
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            kPendingConnectDelay);
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return ERR_IO_PENDING;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockPendingFailingJob:
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        set_load_state(LOAD_STATE_CONNECTING);
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        MessageLoop::current()->PostDelayedTask(
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            FROM_HERE,
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            method_factory_.NewRunnableMethod(
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                &TestConnectJob::DoConnect,
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                false /* error */,
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true  /* async */,
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                false /* recoverable */),
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            2);
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return ERR_IO_PENDING;
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockWaitingJob:
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        client_socket_factory_->WaitForSignal(this);
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        waiting_success_ = true;
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return ERR_IO_PENDING;
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      case kMockAdvancingLoadStateJob:
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        MessageLoop::current()->PostTask(
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            FROM_HERE,
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            method_factory_.NewRunnableMethod(
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                &TestConnectJob::AdvanceLoadState, load_state_));
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return ERR_IO_PENDING;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kMockRecoverableJob:
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return DoConnect(false /* error */, false /* sync */,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         true /* recoverable */);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kMockPendingRecoverableJob:
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        set_load_state(LOAD_STATE_CONNECTING);
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        MessageLoop::current()->PostDelayedTask(
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            FROM_HERE,
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            method_factory_.NewRunnableMethod(
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                &TestConnectJob::DoConnect,
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                false /* error */,
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true  /* async */,
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true  /* recoverable */),
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            2);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return ERR_IO_PENDING;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kMockAdditionalErrorStateJob:
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        store_additional_error_state_ = true;
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return DoConnect(false /* error */, false /* sync */,
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         false /* recoverable */);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case kMockPendingAdditionalErrorStateJob:
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        set_load_state(LOAD_STATE_CONNECTING);
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        store_additional_error_state_ = true;
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        MessageLoop::current()->PostDelayedTask(
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            FROM_HERE,
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            method_factory_.NewRunnableMethod(
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                &TestConnectJob::DoConnect,
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                false /* error */,
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                true  /* async */,
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                false /* recoverable */),
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            2);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return ERR_IO_PENDING;
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      default:
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        NOTREACHED();
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        set_socket(NULL);
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return ERR_FAILED;
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_load_state(LoadState load_state) { load_state_ = load_state; }
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int DoConnect(bool succeed, bool was_async, bool recoverable) {
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int result = OK;
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (succeed) {
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      socket()->Connect(NULL);
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (recoverable) {
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result = ERR_PROXY_AUTH_REQUESTED;
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result = ERR_CONNECTION_FAILED;
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      set_socket(NULL);
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (was_async)
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      NotifyDelegateOfCompletion(result);
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This function helps simulate the progress of load states on a ConnectJob.
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Each time it is called it advances the load state and posts a task to be
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // called again.  It stops at the last connecting load state (the one
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // before LOAD_STATE_SENDING_REQUEST).
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AdvanceLoadState(LoadState state) {
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int tmp = state;
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    tmp++;
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (tmp < LOAD_STATE_SENDING_REQUEST) {
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      state = static_cast<LoadState>(tmp);
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      set_load_state(state);
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->PostTask(
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          FROM_HERE,
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            state));
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool waiting_success_;
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const JobType job_type_;
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockClientSocketFactory* const client_socket_factory_;
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LoadState load_state_;
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool store_additional_error_state_;
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestConnectJobFactory
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : public TestClientSocketPoolBase::ConnectJobFactory {
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : job_type_(TestConnectJob::kMockJob),
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        client_socket_factory_(client_socket_factory) {}
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~TestConnectJobFactory() {}
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void set_timeout_duration(base::TimeDelta timeout_duration) {
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    timeout_duration_ = timeout_duration;
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ConnectJobFactory methods:
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ConnectJob* NewConnectJob(
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const std::string& group_name,
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const TestClientSocketPoolBase::Request& request,
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ConnectJob::Delegate* delegate) const {
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return new TestConnectJob(job_type_,
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              group_name,
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              request,
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              timeout_duration_,
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              delegate,
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              client_socket_factory_,
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              NULL);
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual base::TimeDelta ConnectionTimeout() const {
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return timeout_duration_;
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJob::JobType job_type_;
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  base::TimeDelta timeout_duration_;
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockClientSocketFactory* const client_socket_factory_;
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestClientSocketPool : public ClientSocketPool {
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestClientSocketPool(
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int max_sockets,
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int max_sockets_per_group,
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ClientSocketPoolHistograms* histograms,
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta unused_idle_socket_timeout,
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta used_idle_socket_timeout,
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : base_(max_sockets, max_sockets_per_group, histograms,
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              unused_idle_socket_timeout, used_idle_socket_timeout,
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              connect_job_factory) {}
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~TestClientSocketPool() {}
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int RequestSocket(
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const std::string& group_name,
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const void* params,
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      net::RequestPriority priority,
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      ClientSocketHandle* handle,
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      CompletionCallback* callback,
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const BoundNetLog& net_log) {
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const scoped_refptr<TestSocketParams>* casted_socket_params =
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<const scoped_refptr<TestSocketParams>*>(params);
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return base_.RequestSocket(group_name, *casted_socket_params, priority,
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               handle, callback, net_log);
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  virtual void RequestSockets(const std::string& group_name,
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                              const void* params,
403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                              int num_sockets,
404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                              const BoundNetLog& net_log) {
405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const scoped_refptr<TestSocketParams>* casted_params =
406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        static_cast<const scoped_refptr<TestSocketParams>*>(params);
407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void CancelRequest(
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const std::string& group_name,
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ClientSocketHandle* handle) {
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    base_.CancelRequest(group_name, handle);
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void ReleaseSocket(
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      const std::string& group_name,
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ClientSocket* socket,
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int id) {
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base_.ReleaseSocket(group_name, socket, id);
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Flush() {
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base_.Flush();
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void CloseIdleSockets() {
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    base_.CloseIdleSockets();
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual int IdleSocketCountInGroup(const std::string& group_name) const {
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return base_.IdleSocketCountInGroup(group_name);
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual LoadState GetLoadState(const std::string& group_name,
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 const ClientSocketHandle* handle) const {
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return base_.GetLoadState(group_name, handle);
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual DictionaryValue* GetInfoAsValue(const std::string& name,
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                          const std::string& type,
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                          bool include_nested_pools) const {
4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return base_.GetInfoAsValue(name, type);
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual base::TimeDelta ConnectionTimeout() const {
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return base_.ConnectionTimeout();
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ClientSocketPoolHistograms* histograms() const {
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return base_.histograms();
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const TestClientSocketPoolBase* base() const { return &base_; }
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int NumConnectJobsInGroup(const std::string& group_name) const {
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return base_.NumConnectJobsInGroup(group_name);
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
463731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int NumActiveSocketsInGroup(const std::string& group_name) const {
464731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return base_.NumActiveSocketsInGroup(group_name);
465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
466731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool HasGroup(const std::string& group_name) const {
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return base_.HasGroup(group_name);
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestClientSocketPoolBase base_;
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochREGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MockClientSocketFactory::SignalJobs() {
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       it != waiting_jobs_.end(); ++it) {
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    (*it)->Signal();
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  waiting_jobs_.clear();
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TestConnectJobDelegate : public ConnectJob::Delegate {
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJobDelegate()
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : have_result_(false), waiting_for_result_(false), result_(OK) {}
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual ~TestConnectJobDelegate() {}
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void OnConnectJobComplete(int result, ConnectJob* job) {
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result_ = result;
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // socket.get() should be NULL iff result != OK
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(socket.get() == NULL, result != OK);
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete job;
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    have_result_ = true;
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (waiting_for_result_)
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      MessageLoop::current()->Quit();
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int WaitForResult() {
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(!waiting_for_result_);
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    while (!have_result_) {
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      waiting_for_result_ = true;
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      MessageLoop::current()->Run();
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      waiting_for_result_ = false;
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    have_result_ = false;  // auto-reset for next callback
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result_;
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool have_result_;
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool waiting_for_result_;
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result_;
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ClientSocketPoolBaseTest : public testing::Test {
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketPoolBaseTest()
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : params_(new TestSocketParams()),
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        histograms_("ClientSocketPoolTest") {
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    connect_backup_jobs_enabled_ =
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
537088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun    cleanup_timer_enabled_ =
538088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun        internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~ClientSocketPoolBaseTest() {
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        connect_backup_jobs_enabled_);
544088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun    internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
545088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun        cleanup_timer_enabled_);
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CreatePool(int max_sockets, int max_sockets_per_group) {
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    CreatePoolWithIdleTimeouts(
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        max_sockets,
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        max_sockets_per_group,
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        base::TimeDelta::FromSeconds(
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            ClientSocketPool::unused_idle_socket_timeout()),
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void CreatePoolWithIdleTimeouts(
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      int max_sockets, int max_sockets_per_group,
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta unused_idle_socket_timeout,
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta used_idle_socket_timeout) {
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK(!pool_.get());
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    pool_.reset(new TestClientSocketPool(max_sockets,
5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         max_sockets_per_group,
5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         &histograms_,
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         unused_idle_socket_timeout,
5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         used_idle_socket_timeout,
5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         connect_job_factory_));
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int StartRequest(const std::string& group_name,
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                   net::RequestPriority priority) {
5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return test_base_.StartRequestUsingPool<
5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        TestClientSocketPool, TestSocketParams>(
5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            pool_.get(), group_name, priority, params_);
5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int GetOrderOfRequest(size_t index) const {
5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return test_base_.GetOrderOfRequest(index);
5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return test_base_.ReleaseOneConnection(keep_alive);
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    test_base_.ReleaseAllConnections(keep_alive);
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest* request(int i) { return test_base_.request(i); }
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  size_t requests_size() const { return test_base_.requests_size(); }
5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  size_t completion_count() const { return test_base_.completion_count(); }
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool connect_backup_jobs_enabled_;
596088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  bool cleanup_timer_enabled_;
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MockClientSocketFactory client_socket_factory_;
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJobFactory* connect_job_factory_;
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<TestSocketParams> params_;
6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketPoolHistograms histograms_;
6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<TestClientSocketPool> pool_;
6023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketPoolTest test_base_;
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Even though a timeout is specified, it doesn't time out on a synchronous
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// completion.
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJobDelegate delegate;
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle ignored;
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestClientSocketPoolBase::Request request(
611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      &ignored, NULL, kDefaultPriority,
612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      internal::ClientSocketPoolBaseHelper::NORMAL,
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      false, params_, BoundNetLog());
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_ptr<TestConnectJob> job(
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new TestConnectJob(TestConnectJob::kMockJob,
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         "a",
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         request,
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         base::TimeDelta::FromMicroseconds(1),
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         &delegate,
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         &client_socket_factory_,
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         NULL));
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, job->Connect());
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJobDelegate delegate;
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle ignored;
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingNetLog log(CapturingNetLog::kUnbounded);
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestClientSocketPoolBase::Request request(
631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      &ignored, NULL, kDefaultPriority,
632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      internal::ClientSocketPoolBaseHelper::NORMAL,
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      false, params_, BoundNetLog());
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Deleted by TestConnectJobDelegate.
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJob* job =
636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      new TestConnectJob(TestConnectJob::kMockPendingJob,
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         "a",
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         request,
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         base::TimeDelta::FromMicroseconds(1),
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         &delegate,
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                         &client_socket_factory_,
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         &log);
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(ERR_IO_PENDING, job->Connect());
6443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(1);
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
64821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
64921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
65021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(6u, entries.size());
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsBeginEvent(
65221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
65421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
65621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEvent(
65921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
66221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEndEvent(
66421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle handle;
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK,
6753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
6763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
6793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
6803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        log.bound()));
681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(handle.is_initialized());
682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(handle.socket());
683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handle.Reset();
684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
68621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
68721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
68821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(4u, entries.size());
689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
69021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_SOCKET_POOL));
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
69221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
69521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
69821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, NetLog::TYPE_SOCKET_POOL));
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set the additional error state members to ensure that they get cleared.
7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.set_is_ssl_error(true);
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpResponseInfo info;
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info.headers = new HttpResponseHeaders("");
7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.set_ssl_error_response_info(info);
7143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED,
7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
7163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
7203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        log.bound()));
7213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.socket());
7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.is_ssl_error());
7233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
72621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
72721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
72821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(3u, entries.size());
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
73021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_SOCKET_POOL));
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
73221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
73521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_SOCKET_POOL));
736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TotalLimit) {
739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Check that the NetLog contains this event.
742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(3));
765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(4));
766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(5));
767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(6, GetOrderOfRequest(6));
768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(7, GetOrderOfRequest(7));
769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
7713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Check that the NetLog contains this event.
778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Reach all limits: max total sockets, and max sockets per group.
780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
7873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now create a new group and verify that we don't starve it.
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
7963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(3));
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(4));
802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(5));
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
8053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", LOWEST));
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", MEDIUM));
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", HIGHEST));
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", LOWEST));
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First 4 requests don't have to wait, and finish in order.
828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(3));
831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(4));
832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and then ("c", LOWEST).
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(7, GetOrderOfRequest(5));
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(6, GetOrderOfRequest(6));
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(7));
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
8403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", LOWEST));
847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", LOW));
848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", HIGHEST));
849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", MEDIUM));
850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First 4 requests don't have to wait, and finish in order.
865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(3));
868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(4));
869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Request ("b", 7) has the highest priority, but we can't make new socket for
871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // group "b", because it has reached the per-group limit. Then we make
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // socket for ("c", 6), because it has higher priority than ("a", 4),
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and we still can't make a socket for group "b".
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(5));
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(6, GetOrderOfRequest(6));
876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(7, GetOrderOfRequest(7));
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
8793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that we count connecting sockets against the total limit.
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Create one asynchronous request.
891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We post all of our delayed tasks with a 2ms delay. I.e. they don't
895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // actually become pending until 2ms after they have been created. In order
896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to flush all tasks, we need to wait so that we know there are no
897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // soon-to-be-pending tasks waiting.
8983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(10);
899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The next synchronous request should wait for its turn.
902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(3));
913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(4));
914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(5));
915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
9173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
9403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
9423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
9433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle;
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
9543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
9553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
9563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
9573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
9583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
9593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handles[4];
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(handles); ++i) {
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callback;
9643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
9653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              handles[i].Init("b",
9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              params_,
9673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              kDefaultPriority,
9683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              &callback,
9693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              pool_.get(),
9703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              BoundNetLog()));
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // One will be stalled, cancel all the handles now.
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This should hit the OnAvailableSocketSlot() code where we previously had
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // stalled groups, but no longer have any.
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(handles); ++i)
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handles[i].Reset();
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle handles[kDefaultMaxSockets];
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callbacks[kDefaultMaxSockets];
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < kDefaultMaxSockets; ++i) {
9883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    params_,
9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    kDefaultPriority,
9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    &callbacks[i],
9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    pool_.get(),
9933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    BoundNetLog()));
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Force a stalled group.
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle stalled_handle;
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callback;
9993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  params_,
10013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  kDefaultPriority,
10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  &callback,
10033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  pool_.get(),
10043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  BoundNetLog()));
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Cancel the stalled request.
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    stalled_handle.Reset();
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, pool_->IdleSocketCount());
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dropping out of scope will close all handles and return them to idle.
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle handles[kDefaultMaxSockets];
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < kDefaultMaxSockets; ++i) {
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestCompletionCallback callback;
10273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
10283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                params_,
10293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                kDefaultPriority,
10303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                &callback,
10313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                pool_.get(),
10323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                BoundNetLog()));
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Force a stalled group.
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle stalled_handle;
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callback;
10393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
10403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  params_,
10413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  kDefaultPriority,
10423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  &callback,
10433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  pool_.get(),
10443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  BoundNetLog()));
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Since it is stalled, it should have no connect jobs.
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Cancel the stalled request.
1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handles[0].Reset();
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now we should have a connect job.
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The stalled socket should connect.
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(OK, callback.WaitForResult());
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(kDefaultMaxSockets + 1,
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              client_socket_factory_.allocation_count());
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, pool_->IdleSocketCount());
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dropping out of scope will close all handles and return them to idle.
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->IdleSocketCount());
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle stalled_handle;
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle handles[kDefaultMaxSockets];
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < kDefaultMaxSockets; ++i) {
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestCompletionCallback callback;
10793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
10803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    params_,
10813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    kDefaultPriority,
10823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    &callback,
10833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    pool_.get(),
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    BoundNetLog()));
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, pool_->IdleSocketCount());
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now we will hit the socket limit.
10913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
10923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  params_,
10933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  kDefaultPriority,
10943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  &callback,
10953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  pool_.get(),
10963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  BoundNetLog()));
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Dropping out of scope will close all handles and return them to idle.
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // But if we wait for it, the released idle sockets will be closed in
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // preference of the waiting request.
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, pool_->IdleSocketCount());
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Regression test for http://crbug.com/40952.
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
11123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->EnableConnectBackupJobs();
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < kDefaultMaxSockets; ++i) {
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle handle;
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callback;
11183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, handle.Init(base::IntToString(i),
11193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              params_,
11203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              kDefaultPriority,
11213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              &callback,
11223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              pool_.get(),
11233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              BoundNetLog()));
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Flush all the DoReleaseSocket tasks.
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Stall a group.  Set a pending job so it'll trigger a backup job if we don't
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reuse a socket.
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle;
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // "0" is special here, since it should be the first entry in the sorted map,
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // which is the one which we would close an idle socket for.  We shouldn't
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // close an idle socket though, since we should reuse the idle socket.
11383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, handle.Init("0",
11393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            params_,
11403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            kDefaultPriority,
11413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            &callback,
11423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            pool_.get(),
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            BoundNetLog()));
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, PendingRequests) {
1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
11543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
11653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
11663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            completion_count());
1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
11703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(8, GetOrderOfRequest(3));
11713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(6, GetOrderOfRequest(4));
11723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(4, GetOrderOfRequest(5));
11733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(3, GetOrderOfRequest(6));
11743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(5, GetOrderOfRequest(7));
11753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(7, GetOrderOfRequest(8));
1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
11783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
1182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
11953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, request(i)->WaitForResult());
1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
1198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
11993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
12003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            completion_count());
1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This test will start up a RequestSocket() and then immediately Cancel() it.
1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The pending connect job will be cancelled and should not call back into
1205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ClientSocketPoolBase.
1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
12103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
12113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
12123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
12133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
12143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
12153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
12163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
12173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
12183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
1222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle handle;
1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback;
1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
12293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
12303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
12313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
12323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
12333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handle.Reset();
1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback2;
12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
12393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
12403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
12413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
12423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback2,
12433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
12443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback2.WaitForResult());
1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(callback.have_result());
1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  handle.Reset();
1250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CancelRequest) {
1253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel a request.
1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
12653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
12663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  (*requests())[index_to_cancel]->handle()->Reset();
1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            client_socket_factory_.allocation_count());
12723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
12733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            completion_count());
1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1, GetOrderOfRequest(1));
1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, GetOrderOfRequest(2));
1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(5, GetOrderOfRequest(3));
1278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(3, GetOrderOfRequest(4));
12793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
12803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            GetOrderOfRequest(5));  // Canceled request.
1281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(4, GetOrderOfRequest(6));
1282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(6, GetOrderOfRequest(7));
1283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Make sure we test order of all requests made.
12853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RequestSocketCallback(ClientSocketHandle* handle,
1291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        TestClientSocketPool* pool,
1292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        TestConnectJobFactory* test_connect_job_factory,
1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        TestConnectJob::JobType next_job_type)
1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      : handle_(handle),
1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        pool_(pool),
1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        within_callback_(false),
1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        test_connect_job_factory_(test_connect_job_factory),
1298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        next_job_type_(next_job_type) {}
1299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  virtual void RunWithParams(const Tuple1<int>& params) {
1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    callback_.RunWithParams(params);
1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ASSERT_EQ(OK, params.a);
1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!within_callback_) {
1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      test_connect_job_factory_->set_job_type(next_job_type_);
1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // Don't allow reuse of the socket.  Disconnect it and then release it and
1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // run through the MessageLoop once to get it completely released.
1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      handle_->socket()->Disconnect();
1310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      handle_->Reset();
1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      {
1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        MessageLoop::ScopedNestableTaskAllower nestable(
1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            MessageLoop::current());
1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        MessageLoop::current()->RunAllPending();
1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      within_callback_ = true;
1317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TestCompletionCallback next_job_callback;
1318513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      scoped_refptr<TestSocketParams> params(new TestSocketParams());
13193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      int rv = handle_->Init("a",
13203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             params,
13213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             kDefaultPriority,
13223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             &next_job_callback,
13233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             pool_,
13243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             BoundNetLog());
1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      switch (next_job_type_) {
1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        case TestConnectJob::kMockJob:
1327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          EXPECT_EQ(OK, rv);
1328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          break;
1329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        case TestConnectJob::kMockPendingJob:
1330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          EXPECT_EQ(ERR_IO_PENDING, rv);
1331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // For pending jobs, wait for new socket to be created. This makes
1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // sure there are no more pending operations nor any unclosed sockets
1334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // when the test finishes.
1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // We need to give it a little bit of time to run, so that all the
1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // operations that happen on timers (e.g. cleanup of idle
1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          // connections) can execute.
1338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          {
1339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            MessageLoop::ScopedNestableTaskAllower nestable(
1340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                MessageLoop::current());
13413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            base::PlatformThread::Sleep(10);
1342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            EXPECT_EQ(OK, next_job_callback.WaitForResult());
1343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          }
1344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          break;
1345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        default:
1346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          FAIL() << "Unexpected job type: " << next_job_type_;
1347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          break;
1348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
1349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int WaitForResult() {
1353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return callback_.WaitForResult();
1354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
1357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle* const handle_;
13583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestClientSocketPool* const pool_;
1359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool within_callback_;
1360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJobFactory* const test_connect_job_factory_;
1361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestConnectJob::JobType next_job_type_;
1362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestCompletionCallback callback_;
1363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
1364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
1366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle handle;
1370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RequestSocketCallback callback(
1371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      &handle, pool_.get(), connect_job_factory_,
1372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TestConnectJob::kMockPendingJob);
13733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
13743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
13753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       kDefaultPriority,
13763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
13773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       BoundNetLog());
1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(ERR_IO_PENDING, rv);
1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback.WaitForResult());
1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ClientSocketHandle handle;
1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  RequestSocketCallback callback(
1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
13913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
13923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
13933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       kDefaultPriority,
13943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
13953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       BoundNetLog());
1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(ERR_IO_PENDING, rv);
1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, callback.WaitForResult());
1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that pending requests get serviced after active requests get
1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// cancelled.
1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now, kDefaultMaxSocketsPerGroup requests should be active.
1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Let's cancel them.
1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
14203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_FALSE(request(i)->handle()->is_initialized());
14213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    request(i)->handle()->Reset();
1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Let's wait for the rest to complete now.
14253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
14263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, request(i)->WaitForResult());
14273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    request(i)->handle()->Reset();
1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
14313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            completion_count());
1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Make sure that pending requests get serviced after active requests fail.
1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const size_t kMaxSockets = 5;
1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_LE(kNumberOfRequests, kMaxSockets);  // Otherwise the test will hang.
1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Queue up all the requests
1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < kNumberOfRequests; ++i)
1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < kNumberOfRequests; ++i)
14493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
14583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
14593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
14603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
14613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       kDefaultPriority,
14623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
14633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
14643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       BoundNetLog());
1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel the active request.
14683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle.Init("a",
14713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   params_,
14723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   kDefaultPriority,
14733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   &callback,
14743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   pool_.get(),
14753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   BoundNetLog());
1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
14773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback.WaitForResult());
1478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.is_reused());
1480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(2, client_socket_factory_.allocation_count());
1481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Regression test for http://crbug.com/17985.
1484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kMaxSockets = 3;
1486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kMaxSocketsPerGroup = 2;
1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const RequestPriority kHighPriority = HIGHEST;
1490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This is going to be a pending request in an otherwise empty group.
1495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Reach the maximum socket limit.
1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Create a stalled group with high priorities.
1501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release the first two sockets from "a".  Because this is a keepalive,
1505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the first release will unblock the pending request for "a".  The
1506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // second release will unblock a request for "c", becaue it is the next
1507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // high priority socket.
15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
15093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Closing idle sockets should not get us into trouble, but in the bug
1512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // we were hitting a CHECK here.
1513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pool_->CloseIdleSockets();
1515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();  // Run the released socket wakeups
1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
1520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
15233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
15243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
15263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
15273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
15283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       LOWEST,
15293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
15303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
15313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       log.bound());
1532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
15333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
15343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback.WaitForResult());
15353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_initialized());
15363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.socket());
15373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
1538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
154021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
154121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
154221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(4u, entries.size());
1543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
154421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_SOCKET_POOL));
1545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
154621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
1548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
154921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
1551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
155221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 3, NetLog::TYPE_SOCKET_POOL));
1553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest,
1556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       InitConnectionAsynchronousFailure) {
1557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
15603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
15613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set the additional error state members to ensure that they get cleared.
15643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.set_is_ssl_error(true);
1565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpResponseInfo info;
1566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info.headers = new HttpResponseHeaders("");
15673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.set_ssl_error_response_info(info);
15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
15693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
15703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
15713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
15723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
15733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        log.bound()));
15743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
15753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
15763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.is_ssl_error());
15773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
1578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
157921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
158021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
158121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
158221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(3u, entries.size());
1583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsBeginEvent(
158421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 0, NetLog::TYPE_SOCKET_POOL));
1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEvent(
158621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NetLog::PHASE_NONE));
1588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(LogContainsEndEvent(
158921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 2, NetLog::TYPE_SOCKET_POOL));
1590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
1593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Add back the log expectations! Removed them because the
1594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //               ordering is difficult, and some may fire during destructor.
1595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
15993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
16003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
16013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
1602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
16043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
16053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
16063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
16073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
16083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
16093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
16113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
16123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle2.Init("a",
16133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
16143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
16153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback2,
16163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
16173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
1618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
1620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // At this point, request 2 is just waiting for the connect job to finish.
1623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
16253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle2.Reset();
1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Now request 2 has actually finished.
1628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Add back log expectations.
1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
1632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
16423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  (*requests())[2]->handle()->Reset();
16433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  (*requests())[3]->handle()->Reset();
1644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  (*requests())[1]->handle()->Reset();
1647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  (*requests())[0]->handle()->Reset();
1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When requests and ConnectJobs are not coupled, the request will get serviced
1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// by whatever comes first.
1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Start job 1 (async OK)
1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::vector<TestSocketRequest*> request_order;
16623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  size_t completion_count;  // unused
16633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req1(&request_order, &completion_count);
16643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = req1.handle()->Init("a",
16653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               params_,
16663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               kDefaultPriority,
16673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &req1, pool_.get(),
1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               BoundNetLog());
1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, req1.WaitForResult());
1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Job 1 finished OK.  Start job 2 (also async OK).  Request 3 is pending
1673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // without a job.
1674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req2(&request_order, &completion_count);
16773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = req2.handle()->Init("a",
16783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           params_,
16793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           kDefaultPriority,
16803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           &req2,
16813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           pool_.get(),
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           BoundNetLog());
1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
16843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req3(&request_order, &completion_count);
16853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = req3.handle()->Init("a",
16863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           params_,
16873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           kDefaultPriority,
16883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           &req3,
16893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           pool_.get(),
1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           BoundNetLog());
1691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Both Requests 2 and 3 are pending.  We release socket 1 which should
1694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // service request 2.  Request 3 should still be waiting.
1695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  req1.handle()->Reset();
1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();  // Run the released socket wakeups
1697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(req2.handle()->socket());
1698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, req2.WaitForResult());
1699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(req3.handle()->socket());
1700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Signal job 2, which should service request 3.
1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  client_socket_factory_.SignalJobs();
1704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, req3.WaitForResult());
1705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(3U, request_order.size());
17073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req1, request_order[0]);
17083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req2, request_order[1]);
17093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req3, request_order[2]);
1710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The requests are not coupled to the jobs.  So, the requests should finish in
1714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// their priority / insertion order.
1715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
1716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // First two jobs are async.
1718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::vector<TestSocketRequest*> request_order;
17213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  size_t completion_count;  // unused
17223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req1(&request_order, &completion_count);
17233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = req1.handle()->Init("a",
17243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               params_,
17253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               kDefaultPriority,
17263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &req1,
17273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               pool_.get(),
1728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               BoundNetLog());
1729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req2(&request_order, &completion_count);
17323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = req2.handle()->Init("a",
17333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           params_,
17343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           kDefaultPriority,
17353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           &req2,
17363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           pool_.get(),
1737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           BoundNetLog());
1738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The pending job is sync.
1741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestSocketRequest req3(&request_order, &completion_count);
17443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = req3.handle()->Init("a",
17453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           params_,
17463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           kDefaultPriority,
17473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           &req3,
17483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           pool_.get(),
1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           BoundNetLog());
1750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
1751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, req2.WaitForResult());
1754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(3U, request_order.size());
17573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req1, request_order[0]);
17583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req2, request_order[1]);
17593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(&req3, request_order[2]);
1760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1762c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, LoadState) {
1763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(
1765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      TestConnectJob::kMockAdvancingLoadStateJob);
1766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
17683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
17693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
17703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
17713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       kDefaultPriority,
17723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
17733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
17743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       BoundNetLog());
1775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
17763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
1777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
17813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
17823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle2.Init("a",
17833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    params_,
17843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    kDefaultPriority,
17853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &callback2, pool_.get(),
17863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    BoundNetLog());
1787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
17883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
17893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
1790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, Recoverable) {
1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
17973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
17983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
17993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  params_,
18003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  kDefaultPriority,
18013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  &callback, pool_.get(),
18023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                  BoundNetLog()));
18033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_initialized());
18043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.socket());
1805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(
1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestConnectJob::kMockPendingRecoverableJob);
18123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
18133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
18143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
18153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
18163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
18173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
18183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
18193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
18203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
18213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
18223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
18233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_initialized());
18243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.socket());
1825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1827c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(
1830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestConnectJob::kMockAdditionalErrorStateJob);
1831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
18333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
18343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED,
18353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
18363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
18373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
18383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
18393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
18403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
18413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.is_initialized());
18423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.socket());
18433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_ssl_error());
18443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1847c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(
1851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestConnectJob::kMockPendingAdditionalErrorStateJob);
18523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
18533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
18543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
18553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle.Init("a",
18563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        params_,
18573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        kDefaultPriority,
18583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        &callback,
18593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        pool_.get(),
18603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        BoundNetLog()));
18613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
18623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
18633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.is_initialized());
18643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.socket());
18653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_ssl_error());
18663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
1867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1869088da08b1e594e2e3cae7114394145e8268ab6c9Selim GurunTEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1870088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Disable cleanup timer.
1871088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1872088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1873088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  CreatePoolWithIdleTimeouts(
1874088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun      kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1875088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun      base::TimeDelta::FromMilliseconds(10),  // Time out unused sockets
1876088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun      base::TimeDelta::FromMilliseconds(10));  // Time out used sockets
1877088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1878088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1879088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1880088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1881088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1882088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  ClientSocketHandle handle;
1883088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  TestOldCompletionCallback callback;
1884088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  int rv = handle.Init("a",
1885088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                       params_,
1886088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                       LOWEST,
1887088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                       &callback,
1888088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                       pool_.get(),
1889088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                       BoundNetLog());
1890088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(ERR_IO_PENDING, rv);
1891088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1892088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1893088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  ClientSocketHandle handle2;
1894088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  TestOldCompletionCallback callback2;
1895088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  rv = handle2.Init("a",
1896088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                    params_,
1897088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                    LOWEST,
1898088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                    &callback2,
1899088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                    pool_.get(),
1900088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                    BoundNetLog());
1901088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(ERR_IO_PENDING, rv);
1902088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1903088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1904088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Cancel one of the requests.  Wait for the other, which will get the first
1905088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // job.  Release the socket.  Run the loop again to make sure the second
1906088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // socket is sitting idle and the first one is released (since ReleaseSocket()
1907088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // just posts a DoReleaseSocket() task).
1908088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1909088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  handle.Reset();
1910088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(OK, callback2.WaitForResult());
1911088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Use the socket.
1912088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1913088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  handle2.Reset();
1914088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1915088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // The idle socket timeout value was set to 10 milliseconds. Wait 20
1916088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // milliseconds so the sockets timeout.
1917088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  base::PlatformThread::Sleep(20);
1918088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  MessageLoop::current()->RunAllPending();
1919088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1920088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  ASSERT_EQ(2, pool_->IdleSocketCount());
1921088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1922088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Request a new socket. This should cleanup the unused and timed out ones.
1923088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // A new socket will be created rather than reusing the idle one.
1924088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
1925088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  rv = handle.Init("a",
1926088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                   params_,
1927088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                   LOWEST,
1928088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                   &callback,
1929088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                   pool_.get(),
1930088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun                   log.bound());
1931088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(ERR_IO_PENDING, rv);
1932088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(OK, callback.WaitForResult());
1933088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_FALSE(handle.is_reused());
1934088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1935088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  // Make sure the idle socket is closed
1936088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  ASSERT_TRUE(pool_->HasGroup("a"));
1937088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1938088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
1939088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1940088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  net::CapturingNetLog::EntryList entries;
1941088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  log.GetEntries(&entries);
1942088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun  EXPECT_FALSE(LogContainsEntryWithType(
1943088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun      entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
1944088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun}
1945088da08b1e594e2e3cae7114394145e8268ab6c9Selim Gurun
1946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
1947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePoolWithIdleTimeouts(
1948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta(),  // Time out unused sockets immediately.
1950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta::FromDays(1));  // Don't time out used sockets.
1951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
19573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
19583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
19593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
19603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       LOWEST,
19613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
19623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
19633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       BoundNetLog());
1964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
19653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
19683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
19693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle2.Init("a",
19703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    params_,
19713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    LOWEST,
19723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &callback2,
19733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    pool_.get(),
19743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    BoundNetLog());
1975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
19763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Cancel one of the requests.  Wait for the other, which will get the first
1979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // job.  Release the socket.  Run the loop again to make sure the second
1980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // socket is sitting idle and the first one is released (since ReleaseSocket()
1981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // just posts a DoReleaseSocket() task).
1982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
19843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
19853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Use the socket.
19863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
19873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle2.Reset();
1988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // actually become pending until 2ms after they have been created. In order
1991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to flush all tasks, we need to wait so that we know there are no
1992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // soon-to-be-pending tasks waiting.
19933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(10);
1994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
1995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(2, pool_->IdleSocketCount());
1997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Invoke the idle socket cleanup check.  Only one socket should be left, the
1999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // used socket.  Request it to make sure that it's used.
2000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pool_->CleanupTimedOutIdleSockets();
2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
20033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle.Init("a",
20043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   params_,
20053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   LOWEST,
20063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   &callback,
20073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   pool_.get(),
20083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   log.bound());
2009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
20103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(handle.is_reused());
201121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
201221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CapturingNetLog::EntryList entries;
201321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  log.GetEntries(&entries);
2014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(LogContainsEntryWithType(
201521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure that we process all pending requests even when we're stalling
2019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// because of multiple releasing disconnected sockets.
2020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CreatePoolWithIdleTimeouts(
2022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta(),  // Time out unused sockets immediately.
2024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      base::TimeDelta::FromDays(1));  // Don't time out used sockets.
2025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Startup 4 connect jobs.  Two of them will be pending.
2029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
20313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
20323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int rv = handle.Init("a",
20333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       params_,
20343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       LOWEST,
20353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       &callback,
20363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       pool_.get(),
20373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       BoundNetLog());
2038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
2039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
20413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
20423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle2.Init("a",
20433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    params_,
20443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    LOWEST,
20453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &callback2,
20463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    pool_.get(),
20473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    BoundNetLog());
2048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(OK, rv);
2049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle3;
20513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback3;
20523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle3.Init("a",
20533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    params_,
20543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    LOWEST,
20553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &callback3,
20563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    pool_.get(),
20573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    BoundNetLog());
2058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
2059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle4;
20613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback4;
20623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rv = handle4.Init("a",
20633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    params_,
20643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    LOWEST,
20653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    &callback4,
20663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    pool_.get(),
20673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    BoundNetLog());
2068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ERR_IO_PENDING, rv);
2069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Release two disconnected sockets.
2071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.socket()->Disconnect();
20733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
20743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle2.socket()->Disconnect();
20753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle2.Reset();
2076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback3.WaitForResult());
20783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle3.is_reused());
20793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback4.WaitForResult());
20803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(handle4.is_reused());
2081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
2082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Regression test for http://crbug.com/42267.
2084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// When DoReleaseSocket() is processed for one socket, it is blocked because the
2085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// other stalled groups all have releasing sockets, so no progress can be made.
2086c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePoolWithIdleTimeouts(
2088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      4 /* socket limit */, 4 /* socket limit per group */,
2089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::TimeDelta(),  // Time out unused sockets immediately.
2090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      base::TimeDelta::FromDays(1));  // Don't time out used sockets.
2091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Max out the socket limit with 2 per group.
2095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle_a[4];
20973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback_a[4];
20983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle_b[4];
20993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback_b[4];
2100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0; i < 2; ++i) {
21023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, handle_a[i].Init("a",
21033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   params_,
21043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   LOWEST,
21053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   &callback_a[i],
21063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   pool_.get(),
21073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   BoundNetLog()));
21083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, handle_b[i].Init("b",
21093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   params_,
21103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   LOWEST,
21113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   &callback_b[i],
21123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   pool_.get(),
21133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   BoundNetLog()));
2114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make 4 pending requests, 2 per group.
2117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 2; i < 4; ++i) {
21193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
21203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              handle_a[i].Init("a",
21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               params_,
21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               LOWEST,
21233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &callback_a[i],
21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               pool_.get(),
21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               BoundNetLog()));
21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              handle_b[i].Init("b",
21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               params_,
21293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               LOWEST,
21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &callback_b[i],
21313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               pool_.get(),
21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               BoundNetLog()));
2133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Release b's socket first.  The order is important, because in
2136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // DoReleaseSocket(), we'll process b's released socket, and since both b and
2137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // first, which has a releasing socket, so it refuses to start up another
2139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ConnectJob.  So, we used to infinite loop on this.
21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_b[0].socket()->Disconnect();
21413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_b[0].Reset();
21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_a[0].socket()->Disconnect();
21433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_a[0].Reset();
2144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to get stuck here.
2146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_b[1].socket()->Disconnect();
21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_b[1].Reset();
21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_a[1].socket()->Disconnect();
21513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle_a[1].Reset();
2152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 2; i < 4; ++i) {
21543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, callback_b[i].WaitForResult());
21553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, callback_a[i].WaitForResult());
2156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2159c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest,
2160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
21713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
21723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2u, completion_count());
2173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Releases one connection.
21753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
21763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
2177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
21793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
21803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(4u, completion_count());
2181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, GetOrderOfRequest(1));
2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, GetOrderOfRequest(2));
2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, GetOrderOfRequest(3));
2185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, GetOrderOfRequest(4));
2186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we test order of all requests made.
21883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
2189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
21933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestReleasingSocketRequest(TestClientSocketPool* pool,
21943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             int expected_result,
2195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool reset_releasing_handle)
2196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : pool_(pool),
2197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        expected_result_(expected_result),
2198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reset_releasing_handle_(reset_releasing_handle) {}
2199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle* handle() { return &handle_; }
2201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int WaitForResult() {
2203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return callback_.WaitForResult();
2204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RunWithParams(const Tuple1<int>& params) {
2207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback_.RunWithParams(params);
2208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (reset_releasing_handle_)
2209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      handle_.Reset();
2210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
22113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(expected_result_, handle2_.Init("a",
22123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              con_params,
22133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              kDefaultPriority,
22143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              &callback2_,
22153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              pool_,
2216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              BoundNetLog()));
2217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
22203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestClientSocketPool* const pool_;
2221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int expected_result_;
2222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool reset_releasing_handle_;
2223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle_;
2224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle2_;
2225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback_;
2226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback2_;
2227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
2228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2230c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(static_cast<int>(requests_size()),
2238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            client_socket_factory_.allocation_count());
2239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(
2241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TestConnectJob::kMockPendingAdditionalErrorStateJob);
2242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestReleasingSocketRequest req(pool_.get(), OK, false);
22433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
22443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            req.handle()->Init("a",
22453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               params_,
22463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               kDefaultPriority,
22473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               &req,
22483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               pool_.get(),
22493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               BoundNetLog()));
2250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The next job should complete synchronously
2251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(req.handle()->is_initialized());
2255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(req.handle()->socket());
2256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(req.handle()->is_ssl_error());
2257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
2258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// http://crbug.com/44724 regression test.
2261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We start releasing the pool when we flush on network change.  When that
2262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// happens, the only active references are in the ClientSocketHandles.  When a
2263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConnectJob completes and calls back into the last ClientSocketHandle, that
2264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callback can release the last reference and delete the pool.  After the
2265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// callback finishes, we go back to the stack frame within the now-deleted pool.
2266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Executing any code that refers to members of the now-deleted pool can cause
2267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// crashes.
2268c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle;
2273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
22743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
22753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
22763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
22773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
22783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
22793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
2280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->Flush();
2282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We'll call back into this now.
2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  callback.WaitForResult();
2285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle;
2292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
22933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
22943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
22953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
22963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
22973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
22983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
2299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pool_->Flush();
2303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handle.Reset();
2305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
23083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
23093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
23103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
23113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
23123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
2313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
23183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
23193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ConnectWithinCallback(
23203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const std::string& group_name,
23213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const scoped_refptr<TestSocketParams>& params,
23223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TestClientSocketPool* pool)
23233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : group_name_(group_name), params_(params), pool_(pool) {}
23243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ~ConnectWithinCallback() {}
23263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void RunWithParams(const Tuple1<int>& params) {
23283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    callback_.RunWithParams(params);
23293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(ERR_IO_PENDING,
23303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              handle_.Init(group_name_,
23313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           params_,
23323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           kDefaultPriority,
23333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           &nested_callback_,
23343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           pool_,
23353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           BoundNetLog()));
23363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
23373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int WaitForResult() {
23393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return callback_.WaitForResult();
23403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
23413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int WaitForNestedResult() {
23433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return nested_callback_.WaitForResult();
23443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
23453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
23473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string group_name_;
23483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const scoped_refptr<TestSocketParams> params_;
23493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestClientSocketPool* const pool_;
23503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle_;
23513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback_;
23523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback nested_callback_;
23533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
23543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23553345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
23563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
23573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // First job will be waiting until it gets aborted.
23593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
23603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
23623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ConnectWithinCallback callback("a", params_, pool_.get());
23633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
23643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
23653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
23663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
23673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
23683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
23693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
23703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Second job will be started during the first callback, and will
23713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // asynchronously complete with OK.
23723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
23733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->Flush();
23743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
23753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback.WaitForNestedResult());
23763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
23773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Cancel a pending socket request while we're at max sockets,
2379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and verify that the backup socket firing doesn't cause a crash.
2380c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Max 4 sockets globally, max 4 sockets per group.
2382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
23833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->EnableConnectBackupJobs();
2384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Create the first socket and set to ERR_IO_PENDING.  This starts the backup
23863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // timer.
2387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle;
2389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
23903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
23913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
23923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
23933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
23943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
23953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
2396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start (MaxSockets - 1) connected sockets to reach max sockets.
2398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handles[kDefaultMaxSockets];
2400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 1; i < kDefaultMaxSockets; ++i) {
2401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback callback;
24023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ(OK, handles[i].Init("bar",
24033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                  params_,
24043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                  kDefaultPriority,
24053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                  &callback,
24063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                  pool_.get(),
24073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                  BoundNetLog()));
2408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel the pending request.
2413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handle.Reset();
2414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the backup timer to fire (add some slop to ensure it fires)
24163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(
24173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24233345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
24243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
24253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->EnableConnectBackupJobs();
24263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Create the first socket and set to ERR_IO_PENDING.  This starts the backup
24283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // timer.
24293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
24303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
24313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
24323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
24333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
24343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
24353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
24363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
24373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
24383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(pool_->HasGroup("bar"));
24393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
24403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Cancel the socket request.  This should cancel the backup timer.  Wait for
24423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // the backup time to see if it indeed got canceled.
24433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
24443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Wait for the backup timer to fire (add some slop to ensure it fires)
24453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(
24463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
24473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->RunAllPending();
24483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(pool_->HasGroup("bar"));
24493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
24503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
24533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
24543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pool_->EnableConnectBackupJobs();
24553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Create the first socket and set to ERR_IO_PENDING.  This starts the backup
24573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // timer.
24583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
24593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle;
24603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback;
24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
24623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        params_,
24633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        kDefaultPriority,
24643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        &callback,
24653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        pool_.get(),
24663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        BoundNetLog()));
24673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
24683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
24693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
24703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
24713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         params_,
24723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         kDefaultPriority,
24733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         &callback2,
24743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         pool_.get(),
24753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         BoundNetLog()));
24763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(pool_->HasGroup("bar"));
24773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
24783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Cancel request 1 and then complete request 2.  With the requests finished,
24803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // the backup timer should be cancelled.
24813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  handle.Reset();
24823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
24833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Wait for the backup timer to fire (add some slop to ensure it fires)
24843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::PlatformThread::Sleep(
24853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
24863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->RunAllPending();
24873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test delayed socket binding for the case where we have two connects,
2490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and while one is waiting on a connect, the other frees up.
2491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The socket waiting on a connect should switch immediately to the freed
2492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// up socket.
2493c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle1;
2498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
24993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
25003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle1.Init("a",
25013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
25023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
25033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
25043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
25053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, no pending jobs.
2509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a second socket to the same host, but this one will wait.
2513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle2;
25153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
25163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle2.Init("a",
25173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
25183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
25193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
25203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
25213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, and one connecting job.
2523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return the first handle to the pool.  This will initiate the delayed
2527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // binding.
2528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handle1.Reset();
2529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Still no idle sockets, still one pending connect job.
2533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The second socket connected, even though it was a Waiting Job.
2537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And we can see there is still one job waiting.
2540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Finally, signal the waiting Connect.
2543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client_socket_factory_.SignalJobs();
2544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test delayed socket binding when a group is at capacity and one
2550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the group's sockets frees up.
2551c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle1;
2556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
25573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
25583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle1.Init("a",
25593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
25603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
25613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
25623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
25633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, no pending jobs.
2567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a second socket to the same host, but this one will wait.
2571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle2;
25733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
25743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle2.Init("a",
25753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
25763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
25773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
25783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
25793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, and one connecting job.
2581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return the first handle to the pool.  This will initiate the delayed
2585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // binding.
2586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handle1.Reset();
2587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Still no idle sockets, still one pending connect job.
2591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The second socket connected, even though it was a Waiting Job.
2595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And we can see there is still one job waiting.
2598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Finally, signal the waiting Connect.
2601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client_socket_factory_.SignalJobs();
2602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test out the case where we have one socket connected, one
2608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// connecting, when the first socket finishes and goes idle.
26093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Although the second connection is pending, the second request
2610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// should complete, by taking the first socket's idle socket.
2611c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle1;
2616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback callback;
26173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
26183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle1.Init("a",
26193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
26203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
26213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
26223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
26233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, no pending jobs.
2627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a second socket to the same host, but this one will wait.
2631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ClientSocketHandle handle2;
26333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
26343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle2.Init("a",
26353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
26363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
26373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback,
26383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
26393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
2640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No idle sockets, and one connecting job.
2641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return the first handle to the pool.  This will initiate the delayed
2645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // binding.
2646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handle1.Reset();
2647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Still no idle sockets, still one pending connect job.
2651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->IdleSocketCount());
2652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The second socket connected, even though it was a Waiting Job.
2655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(OK, callback.WaitForResult());
2656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And we can see there is still one job waiting.
2658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Finally, signal the waiting Connect.
2661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client_socket_factory_.SignalJobs();
2662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
2665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Cover the case where on an available socket slot, we have one pending
26683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// request that completes synchronously, thereby making the Group empty.
26693345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
26703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const int kUnlimitedSockets = 100;
26713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const int kOneSocketPerGroup = 1;
26723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
26733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
26743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Make the first request asynchronous fail.
26753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This will free up a socket slot later.
26763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
26773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
26783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle1;
26793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback1;
26803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
26813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle1.Init("a",
26823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
26833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
26843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback1,
26853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
26863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
26873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
26883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
26893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Make the second request synchronously fail.  This should make the Group
26903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // empty.
26913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
26923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ClientSocketHandle handle2;
26933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestCompletionCallback callback2;
26943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
26953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // when created.
26963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_IO_PENDING,
26973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            handle2.Init("a",
26983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         params_,
26993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         kDefaultPriority,
27003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         &callback2,
27013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         pool_.get(),
27023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         BoundNetLog()));
27033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
27043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
27053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
27063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
27073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
27083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(pool_->HasGroup("a"));
27093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
27103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2711731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2712731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2713731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2714731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2715731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2716731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2717731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2718731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2719731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2720731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2721731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2722731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2723731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2724731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2725731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle2;
2726731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback2;
2727731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2728731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2729731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2730731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback2,
2731731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2732731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2733731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle3;
2734731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback3;
2735731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2736731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2737731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2738731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback3,
2739731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2741731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2742731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback1.WaitForResult());
2743731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
2744731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback3.WaitForResult());
2745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2746731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Use the socket.
2747731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2748731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2749731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2750731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
2751731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle2.Reset();
2752731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle3.Reset();
2753731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2754731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, handle1.Init("a",
2755731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             params_,
2756731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             kDefaultPriority,
2757731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             &callback1,
2758731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             pool_.get(),
2759731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             BoundNetLog()));
2760731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, handle2.Init("a",
2761731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             params_,
2762731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             kDefaultPriority,
2763731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             &callback2,
2764731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             pool_.get(),
2765731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             BoundNetLog()));
2766731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, handle3.Init("a",
2767731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             params_,
2768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             kDefaultPriority,
2769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             &callback3,
2770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             pool_.get(),
2771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                             BoundNetLog()));
2772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2773731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(handle1.socket()->WasEverUsed());
2774731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(handle2.socket()->WasEverUsed());
2775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(handle3.socket()->WasEverUsed());
2776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2777731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2778731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2780731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2787731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2793731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2794731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2795731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2796731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2797731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle2;
2798731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback2;
2799731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2800731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2801731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2802731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback2,
2803731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2804731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2805731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2806731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2807731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2808731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2809731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback1.WaitForResult());
2810731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
2811731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
2812731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle2.Reset();
2813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2817731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2818731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2819731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2820731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2821731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2822731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2828731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2832731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2834731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2837731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2838731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle2;
2841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback2;
2842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2845731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback2,
2846731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2847731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2848731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2849731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2850731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2851731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2852731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback1.WaitForResult());
2853731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
2854731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
2855731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle2.Reset();
2856731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2857731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2858731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2859731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2860731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2861731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest,
2862731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick       RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2863731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(4, 4);
2864731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2865731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2868731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2869731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle2;
2876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback2;
2877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback2,
2881731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2882731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2884731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle3;
2885731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback3;
2886731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2887731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2888731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2889731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback3,
2890731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2891731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2892731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2893731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2894731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2895731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2896731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2897731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2898731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2899731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2900731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2901731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2902731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback1.WaitForResult());
2903731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback2.WaitForResult());
2904731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(OK, callback3.WaitForResult());
2905731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
2906731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle2.Reset();
2907731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle3.Reset();
2908731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2909731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2910731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2911731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2912731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2913731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2914731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2915731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2916731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2917731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(pool_->HasGroup("a"));
2918731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2919731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2920731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
2921731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2922731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2923731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2924731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2925731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(pool_->HasGroup("b"));
2926731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2927731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2928731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
2929731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2930731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(pool_->HasGroup("b"));
2931731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2932731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2933731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2934731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2935731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2936731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2937731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(pool_->HasGroup("a"));
2938731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2939731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2940731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
2941731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2942731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2943731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2944731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2945731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(pool_->HasGroup("b"));
2946731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2947731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2948731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
2949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2950731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("b"));
2951731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2952731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2953731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2954731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2955731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(4, 4);
2956731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2957731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2958731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2959731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2960731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2961731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2962731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2963731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2964731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2965731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2966731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(OK, callback1.WaitForResult());
2967731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
2968731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2969731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2970731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2971731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2972731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2973731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2974731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2975731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2976731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2977731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2978731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2979731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2980731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(4, 4);
2981731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2982731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2983731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
2984731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
2985731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2986731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
2987731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
2988731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
2989731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
2990731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
2991731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(OK, callback1.WaitForResult());
2992731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2993731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
2994731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2995731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2996731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2997731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2998731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2999731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3000731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3001731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3002731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3003731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3004731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3005731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3006731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3007731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3008731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3009731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3010731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
3011731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3012731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
3013731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3014731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3015731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3016731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3017731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
3018731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3019731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3020731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3021731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3022731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3023201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3024201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3025201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3026201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3027201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3028201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                        BoundNetLog());
3029201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3030201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(pool_->HasGroup("a"));
303172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
303272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  connect_job_factory_->set_job_type(
303372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      TestConnectJob::kMockAdditionalErrorStateJob);
303472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
303572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        BoundNetLog());
303672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
303772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_FALSE(pool_->HasGroup("a"));
3038201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
3039201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3040731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3041731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(4, 4);
3042731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3043731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3044731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3045731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3046731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
3047731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3048731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3049731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3050731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3051731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3052731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3053731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3054731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
3055731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
3056731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3057731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
3058731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
3059731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
3060731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
3061731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
3062731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(OK, callback1.WaitForResult());
3063731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3064731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle2;
3065731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback2;
3066731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int rv = handle2.Init("a",
3067731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        params_,
3068731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        kDefaultPriority,
3069731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        &callback2,
3070731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        pool_.get(),
3071731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        BoundNetLog());
3072731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (rv != OK) {
3073731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_EQ(ERR_IO_PENDING, rv);
3074731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_EQ(OK, callback2.WaitForResult());
3075731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
3076731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3077731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
3078731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle2.Reset();
3079731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3080731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3081731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3082731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3083731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3084731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3085731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3086731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3087731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3088731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(4, 4);
3089731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3090731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3091731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3092731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3093731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
3094731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3095731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3096731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3097731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3098731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3099731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3110731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(pool_->HasGroup("a"));
3117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ClientSocketHandle handle1;
3121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TestCompletionCallback callback1;
3122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         params_,
3124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         kDefaultPriority,
3125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         &callback1,
3126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         pool_.get(),
3127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         BoundNetLog()));
3128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_EQ(OK, callback1.WaitForResult());
3133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handle1.Reset();
3135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// http://crbug.com/64940 regression test.
3140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const int kMaxTotalSockets = 3;
3142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const int kMaxSocketsPerGroup = 2;
3143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Note that group name ordering matters here.  "a" comes before "b", so
3147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // CloseOneIdleSocket() will try to close "a"'s idle socket.
3148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Set up one idle socket in "a".
3150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ClientSocketHandle handle1;
3151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TestCompletionCallback callback1;
3152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         params_,
3154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         kDefaultPriority,
3155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         &callback1,
3156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         pool_.get(),
3157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         BoundNetLog()));
3158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(OK, callback1.WaitForResult());
3160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  handle1.Reset();
3161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Set up two active sockets in "b".
3164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ClientSocketHandle handle2;
3165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TestCompletionCallback callback2;
3166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         params_,
3168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         kDefaultPriority,
3169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         &callback1,
3170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         pool_.get(),
3171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         BoundNetLog()));
3172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         params_,
3174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         kDefaultPriority,
3175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         &callback2,
3176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         pool_.get(),
3177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                         BoundNetLog()));
3178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(OK, callback1.WaitForResult());
3180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(OK, callback2.WaitForResult());
3181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3182201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Now we have 1 idle socket in "a" and 2 active sockets in "b".  This means
3185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // sockets for "a", and "b" should still have 2 active sockets.
3188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3196201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Now release the 2 active sockets for "b".  This will give us 1 idle socket
3198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // in "a" and 2 idle sockets in "b".  Requesting 2 preconnected sockets for
3199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // "a" should result in closing 1 for "b".
3200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  handle1.Reset();
3201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  handle2.Reset();
3202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3211201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3212201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
3213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
3215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
3217