blob: 212438c9082880c7ecc3b3fd76ea974789b71286 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]51fdc7c2012-04-10 19:19:487#include <vector>
8
[email protected]6ecf2b92011-12-15 01:14:529#include "base/bind.h"
10#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:0912#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:1513#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1315#include "base/memory/weak_ptr.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4017#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2518#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0819#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0320#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0621#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5322#include "net/base/net_log.h"
23#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3124#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0925#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3526#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "net/socket/client_socket_factory.h"
28#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0029#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1730#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1931#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1032#include "net/socket/stream_socket.h"
[email protected]51fdc7c2012-04-10 19:19:4833#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0934#include "testing/gtest/include/gtest/gtest.h"
35
[email protected]51fdc7c2012-04-10 19:19:4836using ::testing::Invoke;
37using ::testing::Return;
38
[email protected]f6d1d6eb2009-06-24 20:16:0939namespace net {
40
41namespace {
42
[email protected]211d21722009-07-22 15:48:5343const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2044const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5245const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0146
[email protected]df4b4ef2010-07-12 18:25:2147class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2048 public:
[email protected]51fdc7c2012-04-10 19:19:4849 TestSocketParams() : ignore_limits_(false) {}
50
51 void set_ignore_limits(bool ignore_limits) {
52 ignore_limits_ = ignore_limits;
53 }
54 bool ignore_limits() { return ignore_limits_; }
55
[email protected]df4b4ef2010-07-12 18:25:2156 private:
57 friend class base::RefCounted<TestSocketParams>;
58 ~TestSocketParams() {}
[email protected]51fdc7c2012-04-10 19:19:4859
60 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:2161};
[email protected]7fc5b09a2010-02-27 00:07:3862typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4963
[email protected]3268023f2011-05-05 00:08:1064class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0965 public:
[email protected]5e6efa52011-06-27 17:26:4166 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
67 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]3f55aa12011-12-07 02:03:3369 // Socket implementation.
[email protected]ab838892009-06-30 18:49:0570 virtual int Read(
[email protected]83039bb2011-12-09 18:43:5571 IOBuffer* /* buf */, int len,
72 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]3f55aa12011-12-07 02:03:3373 num_bytes_read_ += len;
74 return len;
75 }
[email protected]ab838892009-06-30 18:49:0576
77 virtual int Write(
[email protected]83039bb2011-12-09 18:43:5578 IOBuffer* /* buf */, int len,
79 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:0180 was_used_to_convey_data_ = true;
81 return len;
[email protected]ab838892009-06-30 18:49:0582 }
[email protected]06650c52010-06-03 00:49:1783 virtual bool SetReceiveBufferSize(int32 size) { return true; }
84 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0585
[email protected]dbf036f2011-12-06 23:33:2486 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:5587 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:2488 connected_ = true;
89 return OK;
90 }
[email protected]f6d1d6eb2009-06-24 20:16:0991
[email protected]ab838892009-06-30 18:49:0592 virtual void Disconnect() { connected_ = false; }
93 virtual bool IsConnected() const { return connected_; }
94 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0195
[email protected]ac9eec62010-02-20 18:50:3896 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1697 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0998 }
[email protected]f6d1d6eb2009-06-24 20:16:0999
[email protected]e7f74da2011-04-19 23:49:35100 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
101 return ERR_UNEXPECTED;
102 }
103
[email protected]a2006ece2010-04-23 16:44:02104 virtual const BoundNetLog& NetLog() const {
105 return net_log_;
106 }
107
[email protected]9b5614a2010-08-25 20:29:45108 virtual void SetSubresourceSpeculation() {}
109 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:41110 virtual bool WasEverUsed() const {
111 return was_used_to_convey_data_ || num_bytes_read_ > 0;
112 }
[email protected]7f7e92392010-10-26 18:29:29113 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:41114 virtual int64 NumBytesRead() const { return num_bytes_read_; }
115 virtual base::TimeDelta GetConnectTimeMicros() const {
116 static const base::TimeDelta kDummyConnectTimeMicros =
117 base::TimeDelta::FromMicroseconds(10);
118 return kDummyConnectTimeMicros; // Dummy value.
119 }
[email protected]33661e482012-04-03 16:16:26120 virtual NextProto GetNegotiatedProtocol() const {
121 return kProtoUnknown;
122 }
[email protected]9b5614a2010-08-25 20:29:45123
[email protected]f6d1d6eb2009-06-24 20:16:09124 private:
125 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02126 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01127 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41128 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09129
[email protected]ab838892009-06-30 18:49:05130 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09131};
132
[email protected]5fc08e32009-07-15 17:09:57133class TestConnectJob;
134
[email protected]f6d1d6eb2009-06-24 20:16:09135class MockClientSocketFactory : public ClientSocketFactory {
136 public:
[email protected]ab838892009-06-30 18:49:05137 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09138
[email protected]98b0e582011-06-22 14:31:41139 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04140 DatagramSocket::BindType bind_type,
141 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41142 NetLog* net_log,
143 const NetLog::Source& source) {
144 NOTREACHED();
145 return NULL;
146 }
147
[email protected]3268023f2011-05-05 00:08:10148 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07149 const AddressList& addresses,
150 NetLog* /* net_log */,
151 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09152 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05153 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09154 }
155
156 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18157 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27158 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21159 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12160 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17161 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09162 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21163 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09164 return NULL;
165 }
166
[email protected]25f47352011-02-25 16:31:59167 virtual void ClearSSLSessionCache() {
168 NOTIMPLEMENTED();
169 }
170
[email protected]5fc08e32009-07-15 17:09:57171 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
172 void SignalJobs();
173
[email protected]f6d1d6eb2009-06-24 20:16:09174 int allocation_count() const { return allocation_count_; }
175
[email protected]f6d1d6eb2009-06-24 20:16:09176 private:
177 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57178 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09179};
180
[email protected]ab838892009-06-30 18:49:05181class TestConnectJob : public ConnectJob {
182 public:
183 enum JobType {
184 kMockJob,
185 kMockFailingJob,
186 kMockPendingJob,
187 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57188 kMockWaitingJob,
189 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13190 kMockRecoverableJob,
191 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18192 kMockAdditionalErrorStateJob,
193 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05194 };
195
[email protected]994d4932010-07-12 17:55:13196 // The kMockPendingJob uses a slight delay before allowing the connect
197 // to complete.
198 static const int kPendingConnectDelay = 2;
199
[email protected]ab838892009-06-30 18:49:05200 TestConnectJob(JobType job_type,
201 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49202 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34203 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05204 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30205 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17206 NetLog* net_log)
207 : ConnectJob(group_name, timeout_duration, delegate,
208 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58209 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05210 client_socket_factory_(client_socket_factory),
[email protected]6ea7b152011-12-21 21:21:13211 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
[email protected]e60e47a2010-07-14 03:37:18212 load_state_(LOAD_STATE_IDLE),
213 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05214
[email protected]974ebd62009-08-03 23:14:34215 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13216 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34217 }
218
[email protected]46451352009-09-01 14:54:21219 virtual LoadState GetLoadState() const { return load_state_; }
220
[email protected]e60e47a2010-07-14 03:37:18221 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
222 if (store_additional_error_state_) {
223 // Set all of the additional error state fields in some way.
224 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43225 HttpResponseInfo info;
226 info.headers = new HttpResponseHeaders("");
227 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18228 }
229 }
230
[email protected]974ebd62009-08-03 23:14:34231 private:
[email protected]3f55aa12011-12-07 02:03:33232 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05233
[email protected]974ebd62009-08-03 23:14:34234 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05235 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28236 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07237 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40238 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05239 switch (job_type_) {
240 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13241 return DoConnect(true /* successful */, false /* sync */,
242 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05243 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13244 return DoConnect(false /* error */, false /* sync */,
245 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05246 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57247 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47248
249 // Depending on execution timings, posting a delayed task can result
250 // in the task getting executed the at the earliest possible
251 // opportunity or only after returning once from the message loop and
252 // then a second call into the message loop. In order to make behavior
253 // more deterministic, we change the default delay to 2ms. This should
254 // always require us to wait for the second call into the message loop.
255 //
256 // N.B. The correct fix for this and similar timing problems is to
257 // abstract time for the purpose of unittests. Unfortunately, we have
258 // a lot of third-party components that directly call the various
259 // time functions, so this change would be rather invasive.
260 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05261 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13262 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
263 weak_factory_.GetWeakPtr(),
264 true /* successful */,
265 true /* async */,
266 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53267 base::TimeDelta::FromMilliseconds(kPendingConnectDelay));
[email protected]ab838892009-06-30 18:49:05268 return ERR_IO_PENDING;
269 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57270 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47271 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05272 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13273 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
274 weak_factory_.GetWeakPtr(),
275 false /* error */,
276 true /* async */,
277 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53278 base::TimeDelta::FromMilliseconds(2));
[email protected]ab838892009-06-30 18:49:05279 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57280 case kMockWaitingJob:
281 client_socket_factory_->WaitForSignal(this);
282 waiting_success_ = true;
283 return ERR_IO_PENDING;
284 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46285 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13286 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
287 weak_factory_.GetWeakPtr(), load_state_));
[email protected]5fc08e32009-07-15 17:09:57288 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13289 case kMockRecoverableJob:
290 return DoConnect(false /* error */, false /* sync */,
291 true /* recoverable */);
292 case kMockPendingRecoverableJob:
293 set_load_state(LOAD_STATE_CONNECTING);
294 MessageLoop::current()->PostDelayedTask(
295 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13296 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
297 weak_factory_.GetWeakPtr(),
298 false /* error */,
299 true /* async */,
300 true /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53301 base::TimeDelta::FromMilliseconds(2));
[email protected]e772db3f2010-07-12 18:11:13302 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18303 case kMockAdditionalErrorStateJob:
304 store_additional_error_state_ = true;
305 return DoConnect(false /* error */, false /* sync */,
306 false /* recoverable */);
307 case kMockPendingAdditionalErrorStateJob:
308 set_load_state(LOAD_STATE_CONNECTING);
309 store_additional_error_state_ = true;
310 MessageLoop::current()->PostDelayedTask(
311 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13312 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
313 weak_factory_.GetWeakPtr(),
314 false /* error */,
315 true /* async */,
316 false /* recoverable */),
[email protected]5761ab9c2012-02-04 16:44:53317 base::TimeDelta::FromMilliseconds(2));
[email protected]e60e47a2010-07-14 03:37:18318 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05319 default:
320 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40321 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05322 return ERR_FAILED;
323 }
324 }
325
[email protected]46451352009-09-01 14:54:21326 void set_load_state(LoadState load_state) { load_state_ = load_state; }
327
[email protected]e772db3f2010-07-12 18:11:13328 int DoConnect(bool succeed, bool was_async, bool recoverable) {
329 int result = OK;
[email protected]ab838892009-06-30 18:49:05330 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55331 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13332 } else if (recoverable) {
333 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40334 } else {
[email protected]e772db3f2010-07-12 18:11:13335 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40336 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05337 }
[email protected]2ab05b52009-07-01 23:57:58338
339 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30340 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05341 return result;
342 }
343
[email protected]cfa8228c2010-06-17 01:07:56344 // This function helps simulate the progress of load states on a ConnectJob.
345 // Each time it is called it advances the load state and posts a task to be
346 // called again. It stops at the last connecting load state (the one
347 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57348 void AdvanceLoadState(LoadState state) {
349 int tmp = state;
350 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56351 if (tmp < LOAD_STATE_SENDING_REQUEST) {
352 state = static_cast<LoadState>(tmp);
353 set_load_state(state);
354 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13355 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
356 weak_factory_.GetWeakPtr(), state));
[email protected]cfa8228c2010-06-17 01:07:56357 }
[email protected]5fc08e32009-07-15 17:09:57358 }
359
360 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05361 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57362 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13363 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21364 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18365 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05366
367 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
368};
369
[email protected]d80a4322009-08-14 07:07:49370class TestConnectJobFactory
371 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05372 public:
[email protected]5fc08e32009-07-15 17:09:57373 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05374 : job_type_(TestConnectJob::kMockJob),
[email protected]51fdc7c2012-04-10 19:19:48375 job_types_(NULL),
[email protected]ab838892009-06-30 18:49:05376 client_socket_factory_(client_socket_factory) {}
377
378 virtual ~TestConnectJobFactory() {}
379
380 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
381
[email protected]51fdc7c2012-04-10 19:19:48382 void set_job_types(std::list<TestConnectJob::JobType>* job_types) {
383 job_types_ = job_types;
384 CHECK(!job_types_->empty());
385 }
386
[email protected]974ebd62009-08-03 23:14:34387 void set_timeout_duration(base::TimeDelta timeout_duration) {
388 timeout_duration_ = timeout_duration;
389 }
390
[email protected]3f55aa12011-12-07 02:03:33391 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55392
[email protected]ab838892009-06-30 18:49:05393 virtual ConnectJob* NewConnectJob(
394 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49395 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17396 ConnectJob::Delegate* delegate) const {
[email protected]51fdc7c2012-04-10 19:19:48397 EXPECT_TRUE(!job_types_ || !job_types_->empty());
398 TestConnectJob::JobType job_type = job_type_;
399 if (job_types_ && !job_types_->empty()) {
400 job_type = job_types_->front();
401 job_types_->pop_front();
402 }
403 return new TestConnectJob(job_type,
[email protected]ab838892009-06-30 18:49:05404 group_name,
405 request,
[email protected]974ebd62009-08-03 23:14:34406 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05407 delegate,
[email protected]fd7b7c92009-08-20 19:38:30408 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17409 NULL);
[email protected]ab838892009-06-30 18:49:05410 }
411
[email protected]a796bcec2010-03-22 17:17:26412 virtual base::TimeDelta ConnectionTimeout() const {
413 return timeout_duration_;
414 }
415
[email protected]ab838892009-06-30 18:49:05416 private:
417 TestConnectJob::JobType job_type_;
[email protected]51fdc7c2012-04-10 19:19:48418 std::list<TestConnectJob::JobType>* job_types_;
[email protected]974ebd62009-08-03 23:14:34419 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57420 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05421
422 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
423};
424
425class TestClientSocketPool : public ClientSocketPool {
426 public:
427 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53428 int max_sockets,
[email protected]ab838892009-06-30 18:49:05429 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13430 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16431 base::TimeDelta unused_idle_socket_timeout,
432 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49433 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00434 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16435 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38436 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05437
[email protected]2431756e2010-09-29 20:26:13438 virtual ~TestClientSocketPool() {}
439
[email protected]ab838892009-06-30 18:49:05440 virtual int RequestSocket(
441 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49442 const void* params,
[email protected]ac790b42009-12-02 04:31:31443 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05444 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41445 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59446 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21447 const scoped_refptr<TestSocketParams>* casted_socket_params =
448 static_cast<const scoped_refptr<TestSocketParams>*>(params);
449 return base_.RequestSocket(group_name, *casted_socket_params, priority,
450 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05451 }
452
[email protected]2c2bef152010-10-13 00:55:03453 virtual void RequestSockets(const std::string& group_name,
454 const void* params,
455 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59456 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03457 const scoped_refptr<TestSocketParams>* casted_params =
458 static_cast<const scoped_refptr<TestSocketParams>*>(params);
459
460 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
461 }
462
[email protected]ab838892009-06-30 18:49:05463 virtual void CancelRequest(
464 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59465 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49466 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05467 }
468
469 virtual void ReleaseSocket(
470 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10471 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59472 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24473 base_.ReleaseSocket(group_name, socket, id);
474 }
475
[email protected]d4dfdab2011-12-07 16:56:59476 virtual void Flush() OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24477 base_.Flush();
[email protected]ab838892009-06-30 18:49:05478 }
479
[email protected]51fdc7c2012-04-10 19:19:48480 virtual bool IsStalled() const OVERRIDE {
481 return base_.IsStalled();
482 }
483
[email protected]d4dfdab2011-12-07 16:56:59484 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49485 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05486 }
487
[email protected]d4dfdab2011-12-07 16:56:59488 virtual int IdleSocketCount() const OVERRIDE {
489 return base_.idle_socket_count();
490 }
[email protected]ab838892009-06-30 18:49:05491
[email protected]d4dfdab2011-12-07 16:56:59492 virtual int IdleSocketCountInGroup(
493 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49494 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05495 }
496
[email protected]d4dfdab2011-12-07 16:56:59497 virtual LoadState GetLoadState(
498 const std::string& group_name,
499 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49500 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05501 }
502
[email protected]51fdc7c2012-04-10 19:19:48503 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
504 base_.AddLayeredPool(pool);
505 }
506
507 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
508 base_.RemoveLayeredPool(pool);
509 }
510
[email protected]d4dfdab2011-12-07 16:56:59511 virtual DictionaryValue* GetInfoAsValue(
512 const std::string& name,
513 const std::string& type,
514 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27515 return base_.GetInfoAsValue(name, type);
516 }
517
[email protected]d4dfdab2011-12-07 16:56:59518 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26519 return base_.ConnectionTimeout();
520 }
521
[email protected]d4dfdab2011-12-07 16:56:59522 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00523 return base_.histograms();
524 }
[email protected]a796bcec2010-03-22 17:17:26525
[email protected]d80a4322009-08-14 07:07:49526 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20527
[email protected]8159a1c2012-06-07 00:00:10528 int NumUnassignedConnectJobsInGroup(const std::string& group_name) const {
529 return base_.NumUnassignedConnectJobsInGroup(group_name);
530 }
531
[email protected]974ebd62009-08-03 23:14:34532 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49533 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34534 }
535
[email protected]2c2bef152010-10-13 00:55:03536 int NumActiveSocketsInGroup(const std::string& group_name) const {
537 return base_.NumActiveSocketsInGroup(group_name);
538 }
539
[email protected]2abfe90a2010-08-25 17:49:51540 bool HasGroup(const std::string& group_name) const {
541 return base_.HasGroup(group_name);
542 }
543
[email protected]9bf28db2009-08-29 01:35:16544 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
545
[email protected]06d94042010-08-25 01:45:22546 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54547
[email protected]51fdc7c2012-04-10 19:19:48548 bool CloseOneIdleConnectionInLayeredPool() {
549 return base_.CloseOneIdleConnectionInLayeredPool();
550 }
551
[email protected]ab838892009-06-30 18:49:05552 private:
[email protected]d80a4322009-08-14 07:07:49553 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05554
555 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
556};
557
[email protected]a937a06d2009-08-19 21:19:24558} // namespace
559
[email protected]7fc5b09a2010-02-27 00:07:38560REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24561
562namespace {
563
[email protected]5fc08e32009-07-15 17:09:57564void MockClientSocketFactory::SignalJobs() {
565 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
566 it != waiting_jobs_.end(); ++it) {
567 (*it)->Signal();
568 }
569 waiting_jobs_.clear();
570}
571
[email protected]974ebd62009-08-03 23:14:34572class TestConnectJobDelegate : public ConnectJob::Delegate {
573 public:
574 TestConnectJobDelegate()
575 : have_result_(false), waiting_for_result_(false), result_(OK) {}
576 virtual ~TestConnectJobDelegate() {}
577
578 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
579 result_ = result;
[email protected]3268023f2011-05-05 00:08:10580 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07581 // socket.get() should be NULL iff result != OK
582 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34583 delete job;
584 have_result_ = true;
585 if (waiting_for_result_)
586 MessageLoop::current()->Quit();
587 }
588
589 int WaitForResult() {
590 DCHECK(!waiting_for_result_);
591 while (!have_result_) {
592 waiting_for_result_ = true;
593 MessageLoop::current()->Run();
594 waiting_for_result_ = false;
595 }
596 have_result_ = false; // auto-reset for next callback
597 return result_;
598 }
599
600 private:
601 bool have_result_;
602 bool waiting_for_result_;
603 int result_;
604};
605
[email protected]2431756e2010-09-29 20:26:13606class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09607 protected:
[email protected]b89f7e42010-05-20 20:37:00608 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21609 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54610 histograms_("ClientSocketPoolTest") {
611 connect_backup_jobs_enabled_ =
612 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
613 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41614 cleanup_timer_enabled_ =
615 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54616 }
[email protected]2431756e2010-09-29 20:26:13617
[email protected]636b8252011-04-08 19:56:54618 virtual ~ClientSocketPoolBaseTest() {
619 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
620 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41621 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
622 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54623 }
[email protected]c9d6a1d2009-07-14 16:15:20624
[email protected]211d21722009-07-22 15:48:53625 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16626 CreatePoolWithIdleTimeouts(
627 max_sockets,
628 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30629 ClientSocketPool::unused_idle_socket_timeout(),
630 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16631 }
632
633 void CreatePoolWithIdleTimeouts(
634 int max_sockets, int max_sockets_per_group,
635 base::TimeDelta unused_idle_socket_timeout,
636 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20637 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04638 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13639 pool_.reset(new TestClientSocketPool(max_sockets,
640 max_sockets_per_group,
641 &histograms_,
642 unused_idle_socket_timeout,
643 used_idle_socket_timeout,
644 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20645 }
[email protected]f6d1d6eb2009-06-24 20:16:09646
[email protected]ac790b42009-12-02 04:31:31647 int StartRequest(const std::string& group_name,
648 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13649 return test_base_.StartRequestUsingPool<
650 TestClientSocketPool, TestSocketParams>(
651 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09652 }
653
[email protected]2431756e2010-09-29 20:26:13654 int GetOrderOfRequest(size_t index) const {
655 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09656 }
657
[email protected]2431756e2010-09-29 20:26:13658 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
659 return test_base_.ReleaseOneConnection(keep_alive);
660 }
661
662 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
663 test_base_.ReleaseAllConnections(keep_alive);
664 }
665
666 TestSocketRequest* request(int i) { return test_base_.request(i); }
667 size_t requests_size() const { return test_base_.requests_size(); }
668 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
669 size_t completion_count() const { return test_base_.completion_count(); }
670
[email protected]636b8252011-04-08 19:56:54671 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41672 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09673 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04674 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21675 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13676 ClientSocketPoolHistograms histograms_;
677 scoped_ptr<TestClientSocketPool> pool_;
678 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09679};
680
[email protected]5e6efa52011-06-27 17:26:41681TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
682 CreatePool(4, 4);
683 net::SetSocketReusePolicy(0);
684
685 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
686 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
687 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689
690 std::map<int, StreamSocket*> sockets_;
691 for (size_t i = 0; i < test_base_.requests_size(); i++) {
692 TestSocketRequest* req = test_base_.request(i);
693 StreamSocket* s = req->handle()->socket();
694 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
695 CHECK(sock);
696 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55697 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41698 }
699
700 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
701
702 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
703 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
704
705 // First socket is warmest.
706 EXPECT_EQ(sockets_[0], req->handle()->socket());
707
708 // Test that NumBytes are as expected.
709 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
710 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
711 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
712 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
713
714 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
715}
716
717TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
718 CreatePool(4, 4);
719 net::SetSocketReusePolicy(2);
720
721 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
722 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
723 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
724 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
725
726 std::map<int, StreamSocket*> sockets_;
727 for (size_t i = 0; i < test_base_.requests_size(); i++) {
728 TestSocketRequest* req = test_base_.request(i);
729 StreamSocket* s = req->handle()->socket();
730 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
731 CHECK(sock);
732 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55733 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41734 }
735
736 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
737
738 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
739 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
740
741 // Last socket is most recently accessed.
742 EXPECT_EQ(sockets_[3], req->handle()->socket());
743 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
744}
745
[email protected]974ebd62009-08-03 23:14:34746// Even though a timeout is specified, it doesn't time out on a synchronous
747// completion.
748TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
749 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06750 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49751 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41752 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03753 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20754 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34755 scoped_ptr<TestConnectJob> job(
756 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12757 "a",
[email protected]974ebd62009-08-03 23:14:34758 request,
759 base::TimeDelta::FromMicroseconds(1),
760 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30761 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17762 NULL));
[email protected]974ebd62009-08-03 23:14:34763 EXPECT_EQ(OK, job->Connect());
764}
765
766TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
767 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06768 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17769 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53770
[email protected]d80a4322009-08-14 07:07:49771 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41772 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03773 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20774 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34775 // Deleted by TestConnectJobDelegate.
776 TestConnectJob* job =
777 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12778 "a",
[email protected]974ebd62009-08-03 23:14:34779 request,
780 base::TimeDelta::FromMicroseconds(1),
781 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30782 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17783 &log);
[email protected]974ebd62009-08-03 23:14:34784 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]26b9973962012-01-28 00:57:00785 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
[email protected]974ebd62009-08-03 23:14:34786 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30787
[email protected]f3da152d2012-06-02 01:00:57788 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40789 log.GetEntries(&entries);
790
791 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46792 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40793 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17794 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40795 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46796 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40797 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17798 NetLog::PHASE_NONE));
799 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40800 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53801 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46802 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40803 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17804 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40805 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34806}
807
[email protected]5fc08e32009-07-15 17:09:57808TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20810
[email protected]6ecf2b92011-12-15 01:14:52811 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06812 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53813 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
814
[email protected]2431756e2010-09-29 20:26:13815 EXPECT_EQ(OK,
816 handle.Init("a",
817 params_,
818 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52819 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13820 pool_.get(),
821 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09822 EXPECT_TRUE(handle.is_initialized());
823 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09824 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30825
[email protected]f3da152d2012-06-02 01:00:57826 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40827 log.GetEntries(&entries);
828
829 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46830 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40831 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53832 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40833 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17834 NetLog::PHASE_NONE));
835 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40836 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53837 NetLog::PHASE_NONE));
838 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40839 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09840}
841
[email protected]ab838892009-06-30 18:49:05842TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20844
[email protected]ab838892009-06-30 18:49:05845 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53846 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
847
[email protected]2431756e2010-09-29 20:26:13848 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52849 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18850 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13851 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43852 HttpResponseInfo info;
853 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13854 handle.set_ssl_error_response_info(info);
855 EXPECT_EQ(ERR_CONNECTION_FAILED,
856 handle.Init("a",
857 params_,
858 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52859 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13860 pool_.get(),
861 log.bound()));
862 EXPECT_FALSE(handle.socket());
863 EXPECT_FALSE(handle.is_ssl_error());
864 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30865
[email protected]f3da152d2012-06-02 01:00:57866 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:40867 log.GetEntries(&entries);
868
869 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27870 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40871 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17872 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40873 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17874 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02875 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40876 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09877}
878
[email protected]211d21722009-07-22 15:48:53879TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
880 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
881
[email protected]9e743cd2010-03-16 07:03:53882 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30883
[email protected]211d21722009-07-22 15:48:53884 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
885 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
886 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
887 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
888
[email protected]2431756e2010-09-29 20:26:13889 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53890 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13891 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53892
893 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
894 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
895 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
896
[email protected]2431756e2010-09-29 20:26:13897 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53898
[email protected]2431756e2010-09-29 20:26:13899 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53900 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13901 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53902
903 EXPECT_EQ(1, GetOrderOfRequest(1));
904 EXPECT_EQ(2, GetOrderOfRequest(2));
905 EXPECT_EQ(3, GetOrderOfRequest(3));
906 EXPECT_EQ(4, GetOrderOfRequest(4));
907 EXPECT_EQ(5, GetOrderOfRequest(5));
908 EXPECT_EQ(6, GetOrderOfRequest(6));
909 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17910
911 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13912 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53913}
914
915TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
916 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
917
[email protected]9e743cd2010-03-16 07:03:53918 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30919
[email protected]211d21722009-07-22 15:48:53920 // Reach all limits: max total sockets, and max sockets per group.
921 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
922 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
923 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
924 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
925
[email protected]2431756e2010-09-29 20:26:13926 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53927 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13928 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53929
930 // Now create a new group and verify that we don't starve it.
931 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
932
[email protected]2431756e2010-09-29 20:26:13933 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53934
[email protected]2431756e2010-09-29 20:26:13935 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53936 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13937 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53938
939 EXPECT_EQ(1, GetOrderOfRequest(1));
940 EXPECT_EQ(2, GetOrderOfRequest(2));
941 EXPECT_EQ(3, GetOrderOfRequest(3));
942 EXPECT_EQ(4, GetOrderOfRequest(4));
943 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17944
945 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13946 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53947}
948
949TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
951
[email protected]ac790b42009-12-02 04:31:31952 EXPECT_EQ(OK, StartRequest("b", LOWEST));
953 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
954 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
955 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53956
[email protected]2431756e2010-09-29 20:26:13957 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53958 client_socket_factory_.allocation_count());
959
[email protected]ac790b42009-12-02 04:31:31960 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
961 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
962 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53963
[email protected]2431756e2010-09-29 20:26:13964 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53965
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53967
968 // First 4 requests don't have to wait, and finish in order.
969 EXPECT_EQ(1, GetOrderOfRequest(1));
970 EXPECT_EQ(2, GetOrderOfRequest(2));
971 EXPECT_EQ(3, GetOrderOfRequest(3));
972 EXPECT_EQ(4, GetOrderOfRequest(4));
973
[email protected]ac790b42009-12-02 04:31:31974 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
975 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53976 EXPECT_EQ(7, GetOrderOfRequest(5));
977 EXPECT_EQ(6, GetOrderOfRequest(6));
978 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17979
980 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13981 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53982}
983
984TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
985 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
986
[email protected]ac790b42009-12-02 04:31:31987 EXPECT_EQ(OK, StartRequest("a", LOWEST));
988 EXPECT_EQ(OK, StartRequest("a", LOW));
989 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
990 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53991
[email protected]2431756e2010-09-29 20:26:13992 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53993 client_socket_factory_.allocation_count());
994
[email protected]ac790b42009-12-02 04:31:31995 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
996 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
997 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53998
[email protected]2431756e2010-09-29 20:26:13999 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531000
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531002 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131003 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:531004
1005 // First 4 requests don't have to wait, and finish in order.
1006 EXPECT_EQ(1, GetOrderOfRequest(1));
1007 EXPECT_EQ(2, GetOrderOfRequest(2));
1008 EXPECT_EQ(3, GetOrderOfRequest(3));
1009 EXPECT_EQ(4, GetOrderOfRequest(4));
1010
1011 // Request ("b", 7) has the highest priority, but we can't make new socket for
1012 // group "b", because it has reached the per-group limit. Then we make
1013 // socket for ("c", 6), because it has higher priority than ("a", 4),
1014 // and we still can't make a socket for group "b".
1015 EXPECT_EQ(5, GetOrderOfRequest(5));
1016 EXPECT_EQ(6, GetOrderOfRequest(6));
1017 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171018
1019 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131020 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:531021}
1022
1023// Make sure that we count connecting sockets against the total limit.
1024TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1025 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1026
1027 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1028 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1029 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1030
1031 // Create one asynchronous request.
1032 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1033 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1034
[email protected]6b175382009-10-13 06:47:471035 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1036 // actually become pending until 2ms after they have been created. In order
1037 // to flush all tasks, we need to wait so that we know there are no
1038 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:001039 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]6b175382009-10-13 06:47:471040 MessageLoop::current()->RunAllPending();
1041
[email protected]211d21722009-07-22 15:48:531042 // The next synchronous request should wait for its turn.
1043 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1044 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1045
[email protected]2431756e2010-09-29 20:26:131046 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531047
[email protected]2431756e2010-09-29 20:26:131048 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531049 client_socket_factory_.allocation_count());
1050
1051 EXPECT_EQ(1, GetOrderOfRequest(1));
1052 EXPECT_EQ(2, GetOrderOfRequest(2));
1053 EXPECT_EQ(3, GetOrderOfRequest(3));
1054 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171055 EXPECT_EQ(5, GetOrderOfRequest(5));
1056
1057 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131058 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531059}
1060
[email protected]6427fe22010-04-16 22:27:411061TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1062 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1063 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1064
1065 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1066 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1067 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1068 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1069
1070 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1071
1072 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1073
1074 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1075 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1076
1077 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1078
[email protected]2431756e2010-09-29 20:26:131079 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411080 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131081 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411082 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1084 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411085 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1086}
1087
[email protected]d7027bb2010-05-10 18:58:541088TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1089 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1090 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1091
1092 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521093 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131094 EXPECT_EQ(ERR_IO_PENDING,
1095 handle.Init("a",
1096 params_,
1097 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521098 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131099 pool_.get(),
1100 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541101
1102 ClientSocketHandle handles[4];
1103 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521104 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131105 EXPECT_EQ(ERR_IO_PENDING,
1106 handles[i].Init("b",
1107 params_,
1108 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521109 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131110 pool_.get(),
1111 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541112 }
1113
1114 // One will be stalled, cancel all the handles now.
1115 // This should hit the OnAvailableSocketSlot() code where we previously had
1116 // stalled groups, but no longer have any.
1117 for (size_t i = 0; i < arraysize(handles); ++i)
1118 handles[i].Reset();
1119}
1120
[email protected]eb5a99382010-07-11 03:18:261121TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541122 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1123 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1124
[email protected]eb5a99382010-07-11 03:18:261125 {
1126 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521127 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261128 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131129 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1130 params_,
[email protected]e83326f2010-07-31 17:29:251131 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521132 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131133 pool_.get(),
1134 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261135 }
1136
1137 // Force a stalled group.
1138 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521139 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131140 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1141 params_,
1142 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521143 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131144 pool_.get(),
1145 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261146
1147 // Cancel the stalled request.
1148 stalled_handle.Reset();
1149
1150 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1151 EXPECT_EQ(0, pool_->IdleSocketCount());
1152
1153 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541154 }
1155
[email protected]43a21b82010-06-10 21:30:541156 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1157 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261158}
[email protected]43a21b82010-06-10 21:30:541159
[email protected]eb5a99382010-07-11 03:18:261160TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1162 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1163
1164 {
1165 ClientSocketHandle handles[kDefaultMaxSockets];
1166 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521167 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131168 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1169 params_,
1170 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521171 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131172 pool_.get(),
1173 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261174 }
1175
1176 // Force a stalled group.
1177 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1178 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521179 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131180 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1181 params_,
1182 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521183 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131184 pool_.get(),
1185 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261186
1187 // Since it is stalled, it should have no connect jobs.
1188 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101189 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261190
1191 // Cancel the stalled request.
1192 handles[0].Reset();
1193
[email protected]eb5a99382010-07-11 03:18:261194 // Now we should have a connect job.
1195 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101196 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261197
1198 // The stalled socket should connect.
1199 EXPECT_EQ(OK, callback.WaitForResult());
1200
1201 EXPECT_EQ(kDefaultMaxSockets + 1,
1202 client_socket_factory_.allocation_count());
1203 EXPECT_EQ(0, pool_->IdleSocketCount());
1204 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
[email protected]8159a1c2012-06-07 00:00:101205 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("foo"));
[email protected]eb5a99382010-07-11 03:18:261206
1207 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541208 }
1209
[email protected]eb5a99382010-07-11 03:18:261210 EXPECT_EQ(1, pool_->IdleSocketCount());
1211}
[email protected]43a21b82010-06-10 21:30:541212
[email protected]eb5a99382010-07-11 03:18:261213TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1214 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1215 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541216
[email protected]eb5a99382010-07-11 03:18:261217 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521218 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261219 {
[email protected]51fdc7c2012-04-10 19:19:481220 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261221 ClientSocketHandle handles[kDefaultMaxSockets];
1222 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521223 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401224 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1225 "Take 2: %d", i),
1226 params_,
1227 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521228 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401229 pool_.get(),
1230 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261231 }
1232
1233 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1234 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]51fdc7c2012-04-10 19:19:481235 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261236
1237 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131238 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1239 params_,
1240 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521241 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131242 pool_.get(),
1243 BoundNetLog()));
[email protected]51fdc7c2012-04-10 19:19:481244 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261245
1246 // Dropping out of scope will close all handles and return them to idle.
1247 }
[email protected]43a21b82010-06-10 21:30:541248
1249 // But if we wait for it, the released idle sockets will be closed in
1250 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101251 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261252
1253 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1254 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541255}
1256
1257// Regression test for http://crbug.com/40952.
1258TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1259 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221260 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541261 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1262
1263 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1264 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521265 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131266 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1267 params_,
1268 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521269 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131270 pool_.get(),
1271 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541272 }
1273
1274 // Flush all the DoReleaseSocket tasks.
1275 MessageLoop::current()->RunAllPending();
1276
1277 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1278 // reuse a socket.
1279 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1280 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521281 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541282
1283 // "0" is special here, since it should be the first entry in the sorted map,
1284 // which is the one which we would close an idle socket for. We shouldn't
1285 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131286 EXPECT_EQ(OK, handle.Init("0",
1287 params_,
1288 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521289 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131290 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211291 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541292
1293 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1294 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1295}
1296
[email protected]ab838892009-06-30 18:49:051297TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531298 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091299
[email protected]c9d6a1d2009-07-14 16:15:201300 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1301 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031302 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1304 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1305 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1306 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1307 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091308
[email protected]2431756e2010-09-29 20:26:131309 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091310
[email protected]c9d6a1d2009-07-14 16:15:201311 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1312 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131313 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1314 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091315
[email protected]c9d6a1d2009-07-14 16:15:201316 EXPECT_EQ(1, GetOrderOfRequest(1));
1317 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031318 EXPECT_EQ(8, GetOrderOfRequest(3));
1319 EXPECT_EQ(6, GetOrderOfRequest(4));
1320 EXPECT_EQ(4, GetOrderOfRequest(5));
1321 EXPECT_EQ(3, GetOrderOfRequest(6));
1322 EXPECT_EQ(5, GetOrderOfRequest(7));
1323 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171324
1325 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131326 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091327}
1328
[email protected]ab838892009-06-30 18:49:051329TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091331
[email protected]c9d6a1d2009-07-14 16:15:201332 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1333 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311334 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1335 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1336 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091339
[email protected]2431756e2010-09-29 20:26:131340 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091341
[email protected]2431756e2010-09-29 20:26:131342 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1343 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201344
[email protected]2431756e2010-09-29 20:26:131345 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201346 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131347 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1348 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091349}
1350
1351// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051352// The pending connect job will be cancelled and should not call back into
1353// ClientSocketPoolBase.
1354TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531355 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201356
[email protected]ab838892009-06-30 18:49:051357 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131358 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521359 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131360 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1361 params_,
1362 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521363 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131364 pool_.get(),
1365 BoundNetLog()));
1366 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091367}
1368
[email protected]ab838892009-06-30 18:49:051369TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531370 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201371
[email protected]ab838892009-06-30 18:49:051372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061373 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521374 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091375
[email protected]2431756e2010-09-29 20:26:131376 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1377 params_,
1378 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521379 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131380 pool_.get(),
1381 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091382
1383 handle.Reset();
1384
[email protected]6ecf2b92011-12-15 01:14:521385 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131386 EXPECT_EQ(ERR_IO_PENDING,
1387 handle.Init("a",
1388 params_,
1389 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521390 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131391 pool_.get(),
1392 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091393
1394 EXPECT_EQ(OK, callback2.WaitForResult());
1395 EXPECT_FALSE(callback.have_result());
1396
1397 handle.Reset();
1398}
1399
[email protected]ab838892009-06-30 18:49:051400TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531401 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091402
[email protected]c9d6a1d2009-07-14 16:15:201403 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1404 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1406 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1407 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1408 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1409 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091410
1411 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201412 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131413 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1414 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091415
[email protected]2431756e2010-09-29 20:26:131416 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091417
[email protected]c9d6a1d2009-07-14 16:15:201418 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1419 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131420 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1421 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091422
[email protected]c9d6a1d2009-07-14 16:15:201423 EXPECT_EQ(1, GetOrderOfRequest(1));
1424 EXPECT_EQ(2, GetOrderOfRequest(2));
1425 EXPECT_EQ(5, GetOrderOfRequest(3));
1426 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131427 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1428 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201429 EXPECT_EQ(4, GetOrderOfRequest(6));
1430 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171431
1432 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131433 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091434}
1435
[email protected]6ecf2b92011-12-15 01:14:521436class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091437 public:
[email protected]2ab05b52009-07-01 23:57:581438 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241439 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581440 TestConnectJobFactory* test_connect_job_factory,
1441 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091442 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061443 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581444 within_callback_(false),
1445 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521446 next_job_type_(next_job_type),
1447 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1448 base::Bind(&RequestSocketCallback::OnComplete,
1449 base::Unretained(this)))) {
1450 }
[email protected]f6d1d6eb2009-06-24 20:16:091451
[email protected]6ecf2b92011-12-15 01:14:521452 virtual ~RequestSocketCallback() {}
1453
1454 const CompletionCallback& callback() const { return callback_; }
1455
1456 private:
1457 void OnComplete(int result) {
1458 SetResult(result);
1459 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091460
1461 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581462 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111463
1464 // Don't allow reuse of the socket. Disconnect it and then release it and
1465 // run through the MessageLoop once to get it completely released.
1466 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091467 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111468 {
[email protected]b5717a42012-02-14 19:33:521469 // TODO: Resolve conflicting intentions of stopping recursion with the
1470 // |!within_callback_| test (above) and the call to |RunAllPending()|
1471 // below. http://crbug.com/114130.
1472 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]5edbf8d2010-01-13 18:44:111473 MessageLoop::current()->RunAllPending();
1474 }
[email protected]f6d1d6eb2009-06-24 20:16:091475 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521476 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271477 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131478 int rv = handle_->Init("a",
1479 params,
1480 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521481 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131482 pool_,
1483 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581484 switch (next_job_type_) {
1485 case TestConnectJob::kMockJob:
1486 EXPECT_EQ(OK, rv);
1487 break;
1488 case TestConnectJob::kMockPendingJob:
1489 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471490
1491 // For pending jobs, wait for new socket to be created. This makes
1492 // sure there are no more pending operations nor any unclosed sockets
1493 // when the test finishes.
1494 // We need to give it a little bit of time to run, so that all the
1495 // operations that happen on timers (e.g. cleanup of idle
1496 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111497 {
[email protected]b5717a42012-02-14 19:33:521498 MessageLoop::ScopedNestableTaskAllower allow(
[email protected]5edbf8d2010-01-13 18:44:111499 MessageLoop::current());
[email protected]26b9973962012-01-28 00:57:001500 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]5edbf8d2010-01-13 18:44:111501 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1502 }
[email protected]2ab05b52009-07-01 23:57:581503 break;
1504 default:
1505 FAIL() << "Unexpected job type: " << next_job_type_;
1506 break;
1507 }
[email protected]f6d1d6eb2009-06-24 20:16:091508 }
1509 }
1510
[email protected]f6d1d6eb2009-06-24 20:16:091511 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131512 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091513 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581514 TestConnectJobFactory* const test_connect_job_factory_;
1515 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521516 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091517};
1518
[email protected]2ab05b52009-07-01 23:57:581519TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201521
[email protected]0b7648c2009-07-06 20:14:011522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061523 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581524 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061525 &handle, pool_.get(), connect_job_factory_,
1526 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131527 int rv = handle.Init("a",
1528 params_,
1529 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521530 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131531 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211532 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091533 ASSERT_EQ(ERR_IO_PENDING, rv);
1534
1535 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581536}
[email protected]f6d1d6eb2009-06-24 20:16:091537
[email protected]2ab05b52009-07-01 23:57:581538TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531539 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201540
[email protected]0b7648c2009-07-06 20:14:011541 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061542 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581543 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061544 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131545 int rv = handle.Init("a",
1546 params_,
1547 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521548 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131549 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211550 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581551 ASSERT_EQ(ERR_IO_PENDING, rv);
1552
1553 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091554}
1555
1556// Make sure that pending requests get serviced after active requests get
1557// cancelled.
[email protected]ab838892009-06-30 18:49:051558TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531559 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201560
[email protected]0b7648c2009-07-06 20:14:011561 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091562
[email protected]c9d6a1d2009-07-14 16:15:201563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1564 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1565 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1566 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091570
[email protected]c9d6a1d2009-07-14 16:15:201571 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1572 // Let's cancel them.
1573 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131574 ASSERT_FALSE(request(i)->handle()->is_initialized());
1575 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091576 }
1577
[email protected]f6d1d6eb2009-06-24 20:16:091578 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131579 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1580 EXPECT_EQ(OK, request(i)->WaitForResult());
1581 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091582 }
1583
[email protected]2431756e2010-09-29 20:26:131584 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1585 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091586}
1587
1588// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051589TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531590 const size_t kMaxSockets = 5;
1591 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201592
[email protected]0b7648c2009-07-06 20:14:011593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091594
[email protected]211d21722009-07-22 15:48:531595 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1596 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091597
1598 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531599 for (size_t i = 0; i < kNumberOfRequests; ++i)
1600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091601
[email protected]211d21722009-07-22 15:48:531602 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131603 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091604}
1605
[email protected]5fc08e32009-07-15 17:09:571606TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531607 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571608
1609 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1610
[email protected]2431756e2010-09-29 20:26:131611 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521612 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131613 int rv = handle.Init("a",
1614 params_,
1615 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521616 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131617 pool_.get(),
1618 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571619 EXPECT_EQ(ERR_IO_PENDING, rv);
1620
1621 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131622 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571623
[email protected]2431756e2010-09-29 20:26:131624 rv = handle.Init("a",
1625 params_,
1626 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521627 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131628 pool_.get(),
1629 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571630 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131631 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571632
[email protected]2431756e2010-09-29 20:26:131633 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571634 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1635}
1636
[email protected]2b7523d2009-07-29 20:29:231637// Regression test for http://crbug.com/17985.
1638TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1639 const int kMaxSockets = 3;
1640 const int kMaxSocketsPerGroup = 2;
1641 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1642
[email protected]ac790b42009-12-02 04:31:311643 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231644
1645 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1646 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1647
1648 // This is going to be a pending request in an otherwise empty group.
1649 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1650
1651 // Reach the maximum socket limit.
1652 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1653
1654 // Create a stalled group with high priorities.
1655 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1656 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231657
[email protected]eb5a99382010-07-11 03:18:261658 // Release the first two sockets from "a". Because this is a keepalive,
1659 // the first release will unblock the pending request for "a". The
1660 // second release will unblock a request for "c", becaue it is the next
1661 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131662 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1663 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231664
1665 // Closing idle sockets should not get us into trouble, but in the bug
1666 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411667 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541668 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261669
1670 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231671}
1672
[email protected]4d3b05d2010-01-27 21:27:291673TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531674 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571675
1676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131677 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521678 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531679 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131680 int rv = handle.Init("a",
1681 params_,
1682 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521683 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131684 pool_.get(),
1685 log.bound());
[email protected]5fc08e32009-07-15 17:09:571686 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131687 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1688 EXPECT_EQ(OK, callback.WaitForResult());
1689 EXPECT_TRUE(handle.is_initialized());
1690 EXPECT_TRUE(handle.socket());
1691 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301692
[email protected]f3da152d2012-06-02 01:00:571693 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401694 log.GetEntries(&entries);
1695
1696 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461697 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401698 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171699 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401700 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171701 NetLog::PHASE_NONE));
1702 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401703 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171704 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461705 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401706 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571707}
1708
[email protected]4d3b05d2010-01-27 21:27:291709TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571710 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571712
1713 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131714 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521715 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531716 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181717 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131718 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431719 HttpResponseInfo info;
1720 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131721 handle.set_ssl_error_response_info(info);
1722 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1723 params_,
1724 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521725 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131726 pool_.get(),
1727 log.bound()));
1728 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1729 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1730 EXPECT_FALSE(handle.is_ssl_error());
1731 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301732
[email protected]f3da152d2012-06-02 01:00:571733 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:401734 log.GetEntries(&entries);
1735
1736 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461737 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401738 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171739 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401740 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171741 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321742 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401743 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571744}
1745
[email protected]4d3b05d2010-01-27 21:27:291746TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101747 // TODO(eroman): Add back the log expectations! Removed them because the
1748 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531749 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571750
1751 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131752 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521753 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131754 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521755 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571756
[email protected]2431756e2010-09-29 20:26:131757 EXPECT_EQ(ERR_IO_PENDING,
1758 handle.Init("a",
1759 params_,
1760 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521761 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131762 pool_.get(),
1763 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531764 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131765 EXPECT_EQ(ERR_IO_PENDING,
1766 handle2.Init("a",
1767 params_,
1768 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521769 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131770 pool_.get(),
1771 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571772
[email protected]2431756e2010-09-29 20:26:131773 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571774
[email protected]fd7b7c92009-08-20 19:38:301775
1776 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301777
[email protected]2431756e2010-09-29 20:26:131778 EXPECT_EQ(OK, callback2.WaitForResult());
1779 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301780
1781 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531782 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571783}
1784
[email protected]4d3b05d2010-01-27 21:27:291785TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1787
[email protected]17a0c6c2009-08-04 00:07:041788 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1789
[email protected]ac790b42009-12-02 04:31:311790 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1791 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1792 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1793 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341794
1795 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131796 (*requests())[2]->handle()->Reset();
1797 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341798 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1799
[email protected]2431756e2010-09-29 20:26:131800 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341801 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1802
[email protected]2431756e2010-09-29 20:26:131803 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261804 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341805}
1806
[email protected]5fc08e32009-07-15 17:09:571807// When requests and ConnectJobs are not coupled, the request will get serviced
1808// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291809TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531810 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571811
1812 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321813 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571814
[email protected]2431756e2010-09-29 20:26:131815 std::vector<TestSocketRequest*> request_order;
1816 size_t completion_count; // unused
1817 TestSocketRequest req1(&request_order, &completion_count);
1818 int rv = req1.handle()->Init("a",
1819 params_,
1820 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521821 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211822 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571823 EXPECT_EQ(ERR_IO_PENDING, rv);
1824 EXPECT_EQ(OK, req1.WaitForResult());
1825
1826 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1827 // without a job.
1828 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1829
[email protected]2431756e2010-09-29 20:26:131830 TestSocketRequest req2(&request_order, &completion_count);
1831 rv = req2.handle()->Init("a",
1832 params_,
1833 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521834 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131835 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211836 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571837 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131838 TestSocketRequest req3(&request_order, &completion_count);
1839 rv = req3.handle()->Init("a",
1840 params_,
1841 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521842 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131843 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211844 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571845 EXPECT_EQ(ERR_IO_PENDING, rv);
1846
1847 // Both Requests 2 and 3 are pending. We release socket 1 which should
1848 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331849 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261850 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331851 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571852 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331853 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571854
1855 // Signal job 2, which should service request 3.
1856
1857 client_socket_factory_.SignalJobs();
1858 EXPECT_EQ(OK, req3.WaitForResult());
1859
[email protected]2431756e2010-09-29 20:26:131860 ASSERT_EQ(3U, request_order.size());
1861 EXPECT_EQ(&req1, request_order[0]);
1862 EXPECT_EQ(&req2, request_order[1]);
1863 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571864 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1865}
1866
1867// The requests are not coupled to the jobs. So, the requests should finish in
1868// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291869TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531870 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571871 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321872 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571873
[email protected]2431756e2010-09-29 20:26:131874 std::vector<TestSocketRequest*> request_order;
1875 size_t completion_count; // unused
1876 TestSocketRequest req1(&request_order, &completion_count);
1877 int rv = req1.handle()->Init("a",
1878 params_,
1879 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521880 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131881 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211882 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571883 EXPECT_EQ(ERR_IO_PENDING, rv);
1884
[email protected]2431756e2010-09-29 20:26:131885 TestSocketRequest req2(&request_order, &completion_count);
1886 rv = req2.handle()->Init("a",
1887 params_,
1888 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521889 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131890 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211891 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571892 EXPECT_EQ(ERR_IO_PENDING, rv);
1893
1894 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321895 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571896
[email protected]2431756e2010-09-29 20:26:131897 TestSocketRequest req3(&request_order, &completion_count);
1898 rv = req3.handle()->Init("a",
1899 params_,
1900 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521901 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131902 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211903 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571904 EXPECT_EQ(ERR_IO_PENDING, rv);
1905
1906 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1907 EXPECT_EQ(OK, req2.WaitForResult());
1908 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1909
[email protected]2431756e2010-09-29 20:26:131910 ASSERT_EQ(3U, request_order.size());
1911 EXPECT_EQ(&req1, request_order[0]);
1912 EXPECT_EQ(&req2, request_order[1]);
1913 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571914}
1915
[email protected]e6ec67b2010-06-16 00:12:461916TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531917 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571918 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321919 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571920
[email protected]2431756e2010-09-29 20:26:131921 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521922 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131923 int rv = handle.Init("a",
1924 params_,
1925 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521926 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131927 pool_.get(),
1928 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571929 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131930 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571931
1932 MessageLoop::current()->RunAllPending();
1933
[email protected]2431756e2010-09-29 20:26:131934 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521935 TestCompletionCallback callback2;
1936 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1937 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571938 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131939 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1940 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571941}
1942
[email protected]e772db3f2010-07-12 18:11:131943TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1944 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1945 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1946
[email protected]2431756e2010-09-29 20:26:131947 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521948 TestCompletionCallback callback;
1949 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1950 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1951 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131952 EXPECT_TRUE(handle.is_initialized());
1953 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131954}
1955
1956TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1957 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1958
1959 connect_job_factory_->set_job_type(
1960 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131961 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521962 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131963 EXPECT_EQ(ERR_IO_PENDING,
1964 handle.Init("a",
1965 params_,
1966 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521967 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131968 pool_.get(),
1969 BoundNetLog()));
1970 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1971 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1972 EXPECT_TRUE(handle.is_initialized());
1973 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131974}
1975
[email protected]e60e47a2010-07-14 03:37:181976TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1977 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1978 connect_job_factory_->set_job_type(
1979 TestConnectJob::kMockAdditionalErrorStateJob);
1980
[email protected]2431756e2010-09-29 20:26:131981 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521982 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131983 EXPECT_EQ(ERR_CONNECTION_FAILED,
1984 handle.Init("a",
1985 params_,
1986 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521987 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131988 pool_.get(),
1989 BoundNetLog()));
1990 EXPECT_FALSE(handle.is_initialized());
1991 EXPECT_FALSE(handle.socket());
1992 EXPECT_TRUE(handle.is_ssl_error());
1993 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181994}
1995
1996TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1997 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1998
1999 connect_job_factory_->set_job_type(
2000 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:132001 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522002 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132003 EXPECT_EQ(ERR_IO_PENDING,
2004 handle.Init("a",
2005 params_,
2006 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522007 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132008 pool_.get(),
2009 BoundNetLog()));
2010 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2011 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2012 EXPECT_FALSE(handle.is_initialized());
2013 EXPECT_FALSE(handle.socket());
2014 EXPECT_TRUE(handle.is_ssl_error());
2015 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182016}
2017
[email protected]e7b1c6d2c2012-05-05 00:54:032018// Make sure we can reuse sockets when the cleanup timer is disabled.
2019TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerReuse) {
[email protected]64770b7d2011-11-16 04:30:412020 // Disable cleanup timer.
2021 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2022
2023 CreatePoolWithIdleTimeouts(
2024 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
[email protected]e7b1c6d2c2012-05-05 00:54:032025 base::TimeDelta(), // Time out unused sockets immediately.
2026 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2027
2028 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2029
2030 ClientSocketHandle handle;
2031 TestCompletionCallback callback;
2032 int rv = handle.Init("a",
2033 params_,
2034 LOWEST,
2035 callback.callback(),
2036 pool_.get(),
2037 BoundNetLog());
2038 ASSERT_EQ(ERR_IO_PENDING, rv);
2039 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2040 ASSERT_EQ(OK, callback.WaitForResult());
2041
2042 // Use and release the socket.
2043 EXPECT_EQ(1, handle.socket()->Write(NULL, 1, CompletionCallback()));
2044 handle.Reset();
2045
2046 // Should now have one idle socket.
2047 ASSERT_EQ(1, pool_->IdleSocketCount());
2048
2049 // Request a new socket. This should reuse the old socket and complete
2050 // synchronously.
2051 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2052 rv = handle.Init("a",
2053 params_,
2054 LOWEST,
2055 CompletionCallback(),
2056 pool_.get(),
2057 log.bound());
2058 ASSERT_EQ(OK, rv);
2059 EXPECT_TRUE(handle.is_reused());
2060
2061 ASSERT_TRUE(pool_->HasGroup("a"));
2062 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2063 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2064
[email protected]f3da152d2012-06-02 01:00:572065 net::CapturingNetLog::CapturedEntryList entries;
[email protected]e7b1c6d2c2012-05-05 00:54:032066 log.GetEntries(&entries);
2067 EXPECT_TRUE(LogContainsEntryWithType(
2068 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2069}
2070
2071// Make sure we cleanup old unused sockets when the cleanup timer is disabled.
2072TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimerNoReuse) {
2073 // Disable cleanup timer.
2074 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
2075
2076 CreatePoolWithIdleTimeouts(
2077 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2078 base::TimeDelta(), // Time out unused sockets immediately
2079 base::TimeDelta()); // Time out used sockets immediately
[email protected]64770b7d2011-11-16 04:30:412080
2081 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2082
2083 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2084
2085 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522086 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412087 int rv = handle.Init("a",
2088 params_,
2089 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522090 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412091 pool_.get(),
2092 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032093 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412094 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2095
2096 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522097 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412098 rv = handle2.Init("a",
2099 params_,
2100 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522101 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412102 pool_.get(),
2103 BoundNetLog());
[email protected]e7b1c6d2c2012-05-05 00:54:032104 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]64770b7d2011-11-16 04:30:412105 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2106
2107 // Cancel one of the requests. Wait for the other, which will get the first
2108 // job. Release the socket. Run the loop again to make sure the second
2109 // socket is sitting idle and the first one is released (since ReleaseSocket()
2110 // just posts a DoReleaseSocket() task).
2111
2112 handle.Reset();
[email protected]e7b1c6d2c2012-05-05 00:54:032113 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412114 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552115 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412116 handle2.Reset();
2117
[email protected]e7b1c6d2c2012-05-05 00:54:032118 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2119 // actually become pending until 2ms after they have been created. In order
2120 // to flush all tasks, we need to wait so that we know there are no
2121 // soon-to-be-pending tasks waiting.
2122 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]64770b7d2011-11-16 04:30:412123 MessageLoop::current()->RunAllPending();
2124
[email protected]e7b1c6d2c2012-05-05 00:54:032125 // Both sockets should now be idle.
[email protected]64770b7d2011-11-16 04:30:412126 ASSERT_EQ(2, pool_->IdleSocketCount());
2127
2128 // Request a new socket. This should cleanup the unused and timed out ones.
2129 // A new socket will be created rather than reusing the idle one.
2130 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]6ecf2b92011-12-15 01:14:522131 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412132 rv = handle.Init("a",
2133 params_,
2134 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522135 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412136 pool_.get(),
2137 log.bound());
[email protected]e7b1c6d2c2012-05-05 00:54:032138 ASSERT_EQ(ERR_IO_PENDING, rv);
2139 ASSERT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412140 EXPECT_FALSE(handle.is_reused());
2141
[email protected]e7b1c6d2c2012-05-05 00:54:032142 // Make sure the idle socket is closed.
[email protected]64770b7d2011-11-16 04:30:412143 ASSERT_TRUE(pool_->HasGroup("a"));
2144 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2145 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2146
[email protected]f3da152d2012-06-02 01:00:572147 net::CapturingNetLog::CapturedEntryList entries;
[email protected]64770b7d2011-11-16 04:30:412148 log.GetEntries(&entries);
2149 EXPECT_FALSE(LogContainsEntryWithType(
2150 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2151}
2152
[email protected]4d3b05d2010-01-27 21:27:292153TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162154 CreatePoolWithIdleTimeouts(
2155 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2156 base::TimeDelta(), // Time out unused sockets immediately.
2157 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2158
2159 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2160
2161 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2162
[email protected]2431756e2010-09-29 20:26:132163 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522164 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132165 int rv = handle.Init("a",
2166 params_,
2167 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522168 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132169 pool_.get(),
2170 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162171 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132172 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162173
[email protected]2431756e2010-09-29 20:26:132174 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522175 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132176 rv = handle2.Init("a",
2177 params_,
2178 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522179 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132180 pool_.get(),
2181 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162182 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132183 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162184
2185 // Cancel one of the requests. Wait for the other, which will get the first
2186 // job. Release the socket. Run the loop again to make sure the second
2187 // socket is sitting idle and the first one is released (since ReleaseSocket()
2188 // just posts a DoReleaseSocket() task).
2189
[email protected]2431756e2010-09-29 20:26:132190 handle.Reset();
2191 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012192 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552193 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132194 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472195
2196 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2197 // actually become pending until 2ms after they have been created. In order
2198 // to flush all tasks, we need to wait so that we know there are no
2199 // soon-to-be-pending tasks waiting.
[email protected]26b9973962012-01-28 00:57:002200 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
[email protected]9bf28db2009-08-29 01:35:162201 MessageLoop::current()->RunAllPending();
2202
2203 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042204
[email protected]9bf28db2009-08-29 01:35:162205 // Invoke the idle socket cleanup check. Only one socket should be left, the
2206 // used socket. Request it to make sure that it's used.
2207
2208 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532209 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132210 rv = handle.Init("a",
2211 params_,
2212 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522213 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132214 pool_.get(),
2215 log.bound());
[email protected]9bf28db2009-08-29 01:35:162216 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132217 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402218
[email protected]f3da152d2012-06-02 01:00:572219 net::CapturingNetLog::CapturedEntryList entries;
[email protected]b2fcd0e2010-12-01 15:19:402220 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152221 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402222 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162223}
2224
[email protected]2041cf342010-02-19 03:15:592225// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162226// because of multiple releasing disconnected sockets.
2227TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2228 CreatePoolWithIdleTimeouts(
2229 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2230 base::TimeDelta(), // Time out unused sockets immediately.
2231 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2232
2233 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2234
2235 // Startup 4 connect jobs. Two of them will be pending.
2236
[email protected]2431756e2010-09-29 20:26:132237 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522238 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132239 int rv = handle.Init("a",
2240 params_,
2241 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522242 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132243 pool_.get(),
2244 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162245 EXPECT_EQ(OK, rv);
2246
[email protected]2431756e2010-09-29 20:26:132247 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522248 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132249 rv = handle2.Init("a",
2250 params_,
2251 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522252 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132253 pool_.get(),
2254 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162255 EXPECT_EQ(OK, rv);
2256
[email protected]2431756e2010-09-29 20:26:132257 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522258 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132259 rv = handle3.Init("a",
2260 params_,
2261 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522262 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132263 pool_.get(),
2264 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162265 EXPECT_EQ(ERR_IO_PENDING, rv);
2266
[email protected]2431756e2010-09-29 20:26:132267 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522268 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132269 rv = handle4.Init("a",
2270 params_,
2271 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522272 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132273 pool_.get(),
2274 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162275 EXPECT_EQ(ERR_IO_PENDING, rv);
2276
2277 // Release two disconnected sockets.
2278
[email protected]2431756e2010-09-29 20:26:132279 handle.socket()->Disconnect();
2280 handle.Reset();
2281 handle2.socket()->Disconnect();
2282 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162283
[email protected]2431756e2010-09-29 20:26:132284 EXPECT_EQ(OK, callback3.WaitForResult());
2285 EXPECT_FALSE(handle3.is_reused());
2286 EXPECT_EQ(OK, callback4.WaitForResult());
2287 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162288}
2289
[email protected]d7027bb2010-05-10 18:58:542290// Regression test for http://crbug.com/42267.
2291// When DoReleaseSocket() is processed for one socket, it is blocked because the
2292// other stalled groups all have releasing sockets, so no progress can be made.
2293TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2294 CreatePoolWithIdleTimeouts(
2295 4 /* socket limit */, 4 /* socket limit per group */,
2296 base::TimeDelta(), // Time out unused sockets immediately.
2297 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2298
2299 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2300
2301 // Max out the socket limit with 2 per group.
2302
[email protected]2431756e2010-09-29 20:26:132303 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522304 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132305 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522306 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542307
2308 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132309 EXPECT_EQ(OK, handle_a[i].Init("a",
2310 params_,
2311 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522312 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132313 pool_.get(),
2314 BoundNetLog()));
2315 EXPECT_EQ(OK, handle_b[i].Init("b",
2316 params_,
2317 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522318 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132319 pool_.get(),
2320 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542321 }
[email protected]b89f7e42010-05-20 20:37:002322
[email protected]d7027bb2010-05-10 18:58:542323 // Make 4 pending requests, 2 per group.
2324
2325 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132326 EXPECT_EQ(ERR_IO_PENDING,
2327 handle_a[i].Init("a",
2328 params_,
2329 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522330 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132331 pool_.get(),
2332 BoundNetLog()));
2333 EXPECT_EQ(ERR_IO_PENDING,
2334 handle_b[i].Init("b",
2335 params_,
2336 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522337 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132338 pool_.get(),
2339 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542340 }
2341
2342 // Release b's socket first. The order is important, because in
2343 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2344 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2345 // first, which has a releasing socket, so it refuses to start up another
2346 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132347 handle_b[0].socket()->Disconnect();
2348 handle_b[0].Reset();
2349 handle_a[0].socket()->Disconnect();
2350 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542351
2352 // Used to get stuck here.
2353 MessageLoop::current()->RunAllPending();
2354
[email protected]2431756e2010-09-29 20:26:132355 handle_b[1].socket()->Disconnect();
2356 handle_b[1].Reset();
2357 handle_a[1].socket()->Disconnect();
2358 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542359
2360 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132361 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2362 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542363 }
2364}
2365
[email protected]fd4fe0b2010-02-08 23:02:152366TEST_F(ClientSocketPoolBaseTest,
2367 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2368 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2369
2370 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2371
2372 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2373 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2374 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2375 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2376
[email protected]2431756e2010-09-29 20:26:132377 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2378 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2379 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152380
2381 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132382 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2383 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152384
[email protected]2431756e2010-09-29 20:26:132385 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2386 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2387 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152388
2389 EXPECT_EQ(1, GetOrderOfRequest(1));
2390 EXPECT_EQ(2, GetOrderOfRequest(2));
2391 EXPECT_EQ(3, GetOrderOfRequest(3));
2392 EXPECT_EQ(4, GetOrderOfRequest(4));
2393
2394 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132395 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152396}
2397
[email protected]6ecf2b92011-12-15 01:14:522398class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042399 public:
[email protected]2431756e2010-09-29 20:26:132400 TestReleasingSocketRequest(TestClientSocketPool* pool,
2401 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182402 bool reset_releasing_handle)
2403 : pool_(pool),
2404 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522405 reset_releasing_handle_(reset_releasing_handle),
2406 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2407 base::Bind(&TestReleasingSocketRequest::OnComplete,
2408 base::Unretained(this)))) {
2409 }
2410
2411 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042412
2413 ClientSocketHandle* handle() { return &handle_; }
2414
[email protected]6ecf2b92011-12-15 01:14:522415 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042416
2417 private:
[email protected]6ecf2b92011-12-15 01:14:522418 void OnComplete(int result) {
2419 SetResult(result);
2420 if (reset_releasing_handle_)
2421 handle_.Reset();
2422
2423 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2424 EXPECT_EQ(expected_result_,
2425 handle2_.Init("a", con_params, kDefaultPriority,
2426 callback2_.callback(), pool_, BoundNetLog()));
2427 }
2428
[email protected]2431756e2010-09-29 20:26:132429 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182430 int expected_result_;
2431 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042432 ClientSocketHandle handle_;
2433 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522434 CompletionCallback callback_;
2435 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042436};
2437
[email protected]e60e47a2010-07-14 03:37:182438
2439TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2440 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2441
2442 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2443 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2444 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2445
[email protected]2431756e2010-09-29 20:26:132446 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182447 client_socket_factory_.allocation_count());
2448
2449 connect_job_factory_->set_job_type(
2450 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2451 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132452 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522453 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2454 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182455 // The next job should complete synchronously
2456 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2457
2458 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2459 EXPECT_FALSE(req.handle()->is_initialized());
2460 EXPECT_FALSE(req.handle()->socket());
2461 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432462 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182463}
2464
[email protected]b6501d3d2010-06-03 23:53:342465// http://crbug.com/44724 regression test.
2466// We start releasing the pool when we flush on network change. When that
2467// happens, the only active references are in the ClientSocketHandles. When a
2468// ConnectJob completes and calls back into the last ClientSocketHandle, that
2469// callback can release the last reference and delete the pool. After the
2470// callback finishes, we go back to the stack frame within the now-deleted pool.
2471// Executing any code that refers to members of the now-deleted pool can cause
2472// crashes.
2473TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2474 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2475 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2476
2477 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522478 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132479 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2480 params_,
2481 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522482 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132483 pool_.get(),
2484 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342485
[email protected]2431756e2010-09-29 20:26:132486 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342487
2488 // We'll call back into this now.
2489 callback.WaitForResult();
2490}
2491
[email protected]a7e38572010-06-07 18:22:242492TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2493 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2494 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2495
2496 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522497 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132498 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2499 params_,
2500 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522501 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132502 pool_.get(),
2503 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242504 EXPECT_EQ(OK, callback.WaitForResult());
2505 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2506
2507 pool_->Flush();
2508
2509 handle.Reset();
2510 MessageLoop::current()->RunAllPending();
2511
[email protected]2431756e2010-09-29 20:26:132512 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2513 params_,
2514 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522515 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132516 pool_.get(),
2517 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242518 EXPECT_EQ(OK, callback.WaitForResult());
2519 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2520}
2521
[email protected]6ecf2b92011-12-15 01:14:522522class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142523 public:
2524 ConnectWithinCallback(
2525 const std::string& group_name,
2526 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132527 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522528 : group_name_(group_name),
2529 params_(params),
2530 pool_(pool),
2531 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2532 base::Bind(&ConnectWithinCallback::OnComplete,
2533 base::Unretained(this)))) {
[email protected]06f92462010-08-31 19:24:142534 }
2535
[email protected]6ecf2b92011-12-15 01:14:522536 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142537
2538 int WaitForNestedResult() {
2539 return nested_callback_.WaitForResult();
2540 }
2541
[email protected]6ecf2b92011-12-15 01:14:522542 const CompletionCallback& callback() const { return callback_; }
2543
[email protected]06f92462010-08-31 19:24:142544 private:
[email protected]6ecf2b92011-12-15 01:14:522545 void OnComplete(int result) {
2546 SetResult(result);
2547 EXPECT_EQ(ERR_IO_PENDING,
2548 handle_.Init(group_name_,
2549 params_,
2550 kDefaultPriority,
2551 nested_callback_.callback(),
2552 pool_,
2553 BoundNetLog()));
2554 }
2555
[email protected]06f92462010-08-31 19:24:142556 const std::string group_name_;
2557 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132558 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142559 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522560 CompletionCallback callback_;
2561 TestCompletionCallback nested_callback_;
2562
2563 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142564};
2565
2566TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2567 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2568
2569 // First job will be waiting until it gets aborted.
2570 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2571
2572 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132573 ConnectWithinCallback callback("a", params_, pool_.get());
2574 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2575 params_,
2576 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522577 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132578 pool_.get(),
2579 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142580
2581 // Second job will be started during the first callback, and will
2582 // asynchronously complete with OK.
2583 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2584 pool_->Flush();
2585 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2586 EXPECT_EQ(OK, callback.WaitForNestedResult());
2587}
2588
[email protected]25eea382010-07-10 23:55:262589// Cancel a pending socket request while we're at max sockets,
2590// and verify that the backup socket firing doesn't cause a crash.
2591TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2592 // Max 4 sockets globally, max 4 sockets per group.
2593 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222594 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262595
[email protected]4baaf9d2010-08-31 15:15:442596 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2597 // timer.
[email protected]25eea382010-07-10 23:55:262598 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2599 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522600 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132601 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2602 params_,
2603 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522604 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132605 pool_.get(),
2606 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262607
2608 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2609 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2610 ClientSocketHandle handles[kDefaultMaxSockets];
2611 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522612 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132613 EXPECT_EQ(OK, handles[i].Init("bar",
2614 params_,
2615 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522616 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132617 pool_.get(),
2618 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262619 }
2620
2621 MessageLoop::current()->RunAllPending();
2622
2623 // Cancel the pending request.
2624 handle.Reset();
2625
2626 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002627 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2628 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]25eea382010-07-10 23:55:262629
2630 MessageLoop::current()->RunAllPending();
2631 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2632}
2633
[email protected]3f00be82010-09-27 19:50:022634TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442635 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2636 pool_->EnableConnectBackupJobs();
2637
2638 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2639 // timer.
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2641 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522642 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132643 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2644 params_,
2645 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522646 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132647 pool_.get(),
2648 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442649 ASSERT_TRUE(pool_->HasGroup("bar"));
2650 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
[email protected]8159a1c2012-06-07 00:00:102651 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("bar"));
[email protected]4baaf9d2010-08-31 15:15:442652
2653 // Cancel the socket request. This should cancel the backup timer. Wait for
2654 // the backup time to see if it indeed got canceled.
2655 handle.Reset();
2656 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002657 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2658 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]4baaf9d2010-08-31 15:15:442659 MessageLoop::current()->RunAllPending();
2660 ASSERT_TRUE(pool_->HasGroup("bar"));
2661 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2662}
2663
[email protected]3f00be82010-09-27 19:50:022664TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2665 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2666 pool_->EnableConnectBackupJobs();
2667
2668 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2669 // timer.
2670 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2671 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522672 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132673 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2674 params_,
2675 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522676 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132677 pool_.get(),
2678 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022679 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2680 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522681 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132682 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2683 params_,
2684 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522685 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132686 pool_.get(),
2687 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022688 ASSERT_TRUE(pool_->HasGroup("bar"));
2689 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2690
2691 // Cancel request 1 and then complete request 2. With the requests finished,
2692 // the backup timer should be cancelled.
2693 handle.Reset();
2694 EXPECT_EQ(OK, callback2.WaitForResult());
2695 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]26b9973962012-01-28 00:57:002696 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
2697 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3));
[email protected]3f00be82010-09-27 19:50:022698 MessageLoop::current()->RunAllPending();
2699}
2700
[email protected]eb5a99382010-07-11 03:18:262701// Test delayed socket binding for the case where we have two connects,
2702// and while one is waiting on a connect, the other frees up.
2703// The socket waiting on a connect should switch immediately to the freed
2704// up socket.
2705TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2706 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2707 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2708
2709 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522710 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132711 EXPECT_EQ(ERR_IO_PENDING,
2712 handle1.Init("a",
2713 params_,
2714 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522715 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132716 pool_.get(),
2717 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262718 EXPECT_EQ(OK, callback.WaitForResult());
2719
2720 // No idle sockets, no pending jobs.
2721 EXPECT_EQ(0, pool_->IdleSocketCount());
2722 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2723
2724 // Create a second socket to the same host, but this one will wait.
2725 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2726 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132727 EXPECT_EQ(ERR_IO_PENDING,
2728 handle2.Init("a",
2729 params_,
2730 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522731 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132732 pool_.get(),
2733 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262734 // No idle sockets, and one connecting job.
2735 EXPECT_EQ(0, pool_->IdleSocketCount());
2736 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2737
2738 // Return the first handle to the pool. This will initiate the delayed
2739 // binding.
2740 handle1.Reset();
2741
2742 MessageLoop::current()->RunAllPending();
2743
2744 // Still no idle sockets, still one pending connect job.
2745 EXPECT_EQ(0, pool_->IdleSocketCount());
2746 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2747
2748 // The second socket connected, even though it was a Waiting Job.
2749 EXPECT_EQ(OK, callback.WaitForResult());
2750
2751 // And we can see there is still one job waiting.
2752 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2753
2754 // Finally, signal the waiting Connect.
2755 client_socket_factory_.SignalJobs();
2756 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2757
2758 MessageLoop::current()->RunAllPending();
2759}
2760
2761// Test delayed socket binding when a group is at capacity and one
2762// of the group's sockets frees up.
2763TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2764 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2765 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2766
2767 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522768 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132769 EXPECT_EQ(ERR_IO_PENDING,
2770 handle1.Init("a",
2771 params_,
2772 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522773 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132774 pool_.get(),
2775 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262776 EXPECT_EQ(OK, callback.WaitForResult());
2777
2778 // No idle sockets, no pending jobs.
2779 EXPECT_EQ(0, pool_->IdleSocketCount());
2780 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2781
2782 // Create a second socket to the same host, but this one will wait.
2783 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2784 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132785 EXPECT_EQ(ERR_IO_PENDING,
2786 handle2.Init("a",
2787 params_,
2788 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522789 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132790 pool_.get(),
2791 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262792 // No idle sockets, and one connecting job.
2793 EXPECT_EQ(0, pool_->IdleSocketCount());
2794 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2795
2796 // Return the first handle to the pool. This will initiate the delayed
2797 // binding.
2798 handle1.Reset();
2799
2800 MessageLoop::current()->RunAllPending();
2801
2802 // Still no idle sockets, still one pending connect job.
2803 EXPECT_EQ(0, pool_->IdleSocketCount());
2804 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2805
2806 // The second socket connected, even though it was a Waiting Job.
2807 EXPECT_EQ(OK, callback.WaitForResult());
2808
2809 // And we can see there is still one job waiting.
2810 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2811
2812 // Finally, signal the waiting Connect.
2813 client_socket_factory_.SignalJobs();
2814 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2815
2816 MessageLoop::current()->RunAllPending();
2817}
2818
2819// Test out the case where we have one socket connected, one
2820// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512821// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262822// should complete, by taking the first socket's idle socket.
2823TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2824 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2825 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2826
2827 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522828 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132829 EXPECT_EQ(ERR_IO_PENDING,
2830 handle1.Init("a",
2831 params_,
2832 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522833 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132834 pool_.get(),
2835 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262836 EXPECT_EQ(OK, callback.WaitForResult());
2837
2838 // No idle sockets, no pending jobs.
2839 EXPECT_EQ(0, pool_->IdleSocketCount());
2840 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2841
2842 // Create a second socket to the same host, but this one will wait.
2843 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2844 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132845 EXPECT_EQ(ERR_IO_PENDING,
2846 handle2.Init("a",
2847 params_,
2848 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522849 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132850 pool_.get(),
2851 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262852 // No idle sockets, and one connecting job.
2853 EXPECT_EQ(0, pool_->IdleSocketCount());
2854 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2855
2856 // Return the first handle to the pool. This will initiate the delayed
2857 // binding.
2858 handle1.Reset();
2859
2860 MessageLoop::current()->RunAllPending();
2861
2862 // Still no idle sockets, still one pending connect job.
2863 EXPECT_EQ(0, pool_->IdleSocketCount());
2864 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2865
2866 // The second socket connected, even though it was a Waiting Job.
2867 EXPECT_EQ(OK, callback.WaitForResult());
2868
2869 // And we can see there is still one job waiting.
2870 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2871
2872 // Finally, signal the waiting Connect.
2873 client_socket_factory_.SignalJobs();
2874 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2875
2876 MessageLoop::current()->RunAllPending();
2877}
2878
[email protected]2abfe90a2010-08-25 17:49:512879// Cover the case where on an available socket slot, we have one pending
2880// request that completes synchronously, thereby making the Group empty.
2881TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2882 const int kUnlimitedSockets = 100;
2883 const int kOneSocketPerGroup = 1;
2884 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2885
2886 // Make the first request asynchronous fail.
2887 // This will free up a socket slot later.
2888 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2889
2890 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522891 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132892 EXPECT_EQ(ERR_IO_PENDING,
2893 handle1.Init("a",
2894 params_,
2895 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522896 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132897 pool_.get(),
2898 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512899 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2900
2901 // Make the second request synchronously fail. This should make the Group
2902 // empty.
2903 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2904 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522905 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512906 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2907 // when created.
[email protected]2431756e2010-09-29 20:26:132908 EXPECT_EQ(ERR_IO_PENDING,
2909 handle2.Init("a",
2910 params_,
2911 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522912 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132913 pool_.get(),
2914 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512915
2916 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2917
2918 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2919 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2920 EXPECT_FALSE(pool_->HasGroup("a"));
2921}
2922
[email protected]e1b54dc2010-10-06 21:27:222923TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2924 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2925
2926 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2927
2928 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522929 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222930 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2931 params_,
2932 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522933 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222934 pool_.get(),
2935 BoundNetLog()));
2936
2937 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522938 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222939 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2940 params_,
2941 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522942 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222943 pool_.get(),
2944 BoundNetLog()));
2945 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522946 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222947 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2948 params_,
2949 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522950 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222951 pool_.get(),
2952 BoundNetLog()));
2953
2954 EXPECT_EQ(OK, callback1.WaitForResult());
2955 EXPECT_EQ(OK, callback2.WaitForResult());
2956 EXPECT_EQ(OK, callback3.WaitForResult());
2957
2958 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552959 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2960 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222961
2962 handle1.Reset();
2963 handle2.Reset();
2964 handle3.Reset();
2965
2966 EXPECT_EQ(OK, handle1.Init("a",
2967 params_,
2968 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522969 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222970 pool_.get(),
2971 BoundNetLog()));
2972 EXPECT_EQ(OK, handle2.Init("a",
2973 params_,
2974 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522975 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222976 pool_.get(),
2977 BoundNetLog()));
2978 EXPECT_EQ(OK, handle3.Init("a",
2979 params_,
2980 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522981 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222982 pool_.get(),
2983 BoundNetLog()));
2984
2985 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2986 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2987 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2988}
2989
[email protected]2c2bef152010-10-13 00:55:032990TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2992 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2993
2994 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2995
2996 ASSERT_TRUE(pool_->HasGroup("a"));
2997 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:102998 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:032999 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3000
3001 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523002 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033003 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3004 params_,
3005 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523006 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033007 pool_.get(),
3008 BoundNetLog()));
3009
3010 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523011 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033012 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3013 params_,
3014 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523015 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033016 pool_.get(),
3017 BoundNetLog()));
3018
3019 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103020 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033021 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3022
3023 EXPECT_EQ(OK, callback1.WaitForResult());
3024 EXPECT_EQ(OK, callback2.WaitForResult());
3025 handle1.Reset();
3026 handle2.Reset();
3027
3028 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103029 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033030 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3031}
3032
3033TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
3034 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3035 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3036
3037 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523038 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033039 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3040 params_,
3041 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523042 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033043 pool_.get(),
3044 BoundNetLog()));
3045
3046 ASSERT_TRUE(pool_->HasGroup("a"));
3047 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103048 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033049 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3050
3051 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3052
3053 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103054 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033055 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3056
3057 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523058 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033059 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3060 params_,
3061 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523062 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033063 pool_.get(),
3064 BoundNetLog()));
3065
3066 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103067 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033068 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3069
3070 EXPECT_EQ(OK, callback1.WaitForResult());
3071 EXPECT_EQ(OK, callback2.WaitForResult());
3072 handle1.Reset();
3073 handle2.Reset();
3074
3075 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103076 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033077 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3078}
3079
3080TEST_F(ClientSocketPoolBaseTest,
3081 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
3082 CreatePool(4, 4);
3083 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3084
3085 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523086 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033087 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3088 params_,
3089 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523090 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033091 pool_.get(),
3092 BoundNetLog()));
3093
3094 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523095 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033096 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3097 params_,
3098 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523099 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033100 pool_.get(),
3101 BoundNetLog()));
3102
3103 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523104 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033105 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3106 params_,
3107 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523108 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033109 pool_.get(),
3110 BoundNetLog()));
3111
3112 ASSERT_TRUE(pool_->HasGroup("a"));
3113 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103114 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033115 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3116
3117 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3118
3119 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103120 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033121 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3122
3123 EXPECT_EQ(OK, callback1.WaitForResult());
3124 EXPECT_EQ(OK, callback2.WaitForResult());
3125 EXPECT_EQ(OK, callback3.WaitForResult());
3126 handle1.Reset();
3127 handle2.Reset();
3128 handle3.Reset();
3129
3130 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103131 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033132 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3133}
3134
3135TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3136 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3137 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3138
3139 ASSERT_FALSE(pool_->HasGroup("a"));
3140
3141 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3142 BoundNetLog());
3143
3144 ASSERT_TRUE(pool_->HasGroup("a"));
3145 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103146 EXPECT_EQ(kDefaultMaxSockets, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033147
3148 ASSERT_FALSE(pool_->HasGroup("b"));
3149
3150 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3151 BoundNetLog());
3152
3153 ASSERT_FALSE(pool_->HasGroup("b"));
3154}
3155
3156TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3157 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3158 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3159
3160 ASSERT_FALSE(pool_->HasGroup("a"));
3161
3162 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3163 BoundNetLog());
3164
3165 ASSERT_TRUE(pool_->HasGroup("a"));
3166 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103167 EXPECT_EQ(kDefaultMaxSockets - 1,
3168 pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]51fdc7c2012-04-10 19:19:483169 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033170
3171 ASSERT_FALSE(pool_->HasGroup("b"));
3172
3173 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3174 BoundNetLog());
3175
3176 ASSERT_TRUE(pool_->HasGroup("b"));
3177 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]51fdc7c2012-04-10 19:19:483178 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033179}
3180
3181TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3182 CreatePool(4, 4);
3183 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3184
3185 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523186 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033187 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3188 params_,
3189 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523190 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033191 pool_.get(),
3192 BoundNetLog()));
3193 ASSERT_EQ(OK, callback1.WaitForResult());
3194 handle1.Reset();
3195
3196 ASSERT_TRUE(pool_->HasGroup("a"));
3197 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103198 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033199 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3200
3201 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3202
3203 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103204 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033205 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3206}
3207
3208TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3209 CreatePool(4, 4);
3210 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3211
3212 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523213 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033214 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3215 params_,
3216 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523217 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033218 pool_.get(),
3219 BoundNetLog()));
3220 ASSERT_EQ(OK, callback1.WaitForResult());
3221
3222 ASSERT_TRUE(pool_->HasGroup("a"));
3223 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103224 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033225 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3226 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3227
3228 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3229
3230 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103231 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033232 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3233 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3234}
3235
3236TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3237 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3238 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3239
3240 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3241 BoundNetLog());
3242
3243 ASSERT_TRUE(pool_->HasGroup("a"));
3244 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103245 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033246 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3247
3248 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3249 BoundNetLog());
3250
3251 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103252 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]2c2bef152010-10-13 00:55:033253 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3254}
3255
[email protected]3c819f522010-12-02 02:03:123256TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3257 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3258 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3259
3260 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3261 BoundNetLog());
3262
3263 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523264
3265 connect_job_factory_->set_job_type(
3266 TestConnectJob::kMockAdditionalErrorStateJob);
3267 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3268 BoundNetLog());
3269
3270 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123271}
3272
[email protected]8159a1c2012-06-07 00:00:103273TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
[email protected]2c2bef152010-10-13 00:55:033274 CreatePool(4, 4);
3275 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3276
3277 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3278
3279 ASSERT_TRUE(pool_->HasGroup("a"));
3280 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103281 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033282 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3283
3284 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3285 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103286 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033287 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3288
3289 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523290 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033291 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3292 params_,
3293 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523294 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033295 pool_.get(),
3296 BoundNetLog()));
3297 ASSERT_EQ(OK, callback1.WaitForResult());
3298
3299 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523300 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033301 int rv = handle2.Init("a",
3302 params_,
3303 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523304 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033305 pool_.get(),
3306 BoundNetLog());
3307 if (rv != OK) {
3308 EXPECT_EQ(ERR_IO_PENDING, rv);
3309 EXPECT_EQ(OK, callback2.WaitForResult());
3310 }
3311
[email protected]8159a1c2012-06-07 00:00:103312 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3313 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
3314 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("a"));
3315 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3316
[email protected]2c2bef152010-10-13 00:55:033317 handle1.Reset();
3318 handle2.Reset();
3319
[email protected]8159a1c2012-06-07 00:00:103320 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3321 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033322 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3323
3324 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3325 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103326 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033327 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3328}
3329
3330TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3331 CreatePool(4, 4);
3332 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3333
3334 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3335
3336 ASSERT_TRUE(pool_->HasGroup("a"));
3337 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103338 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033339 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3340
3341 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3342 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103343 EXPECT_EQ(2, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033344 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3345
3346 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3347 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103348 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033349 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3350
3351 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3352 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103353 EXPECT_EQ(3, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033354 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3355}
3356
3357TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3359 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3360
3361 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3362
3363 ASSERT_TRUE(pool_->HasGroup("a"));
3364 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103365 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033366 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3367
3368 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523369 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033370 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3371 params_,
3372 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523373 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033374 pool_.get(),
3375 BoundNetLog()));
3376
3377 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103378 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]2c2bef152010-10-13 00:55:033379 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3380
3381 ASSERT_EQ(OK, callback1.WaitForResult());
3382
3383 handle1.Reset();
3384
3385 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3386}
3387
[email protected]dcbe168a2010-12-02 03:14:463388// http://crbug.com/64940 regression test.
3389TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3390 const int kMaxTotalSockets = 3;
3391 const int kMaxSocketsPerGroup = 2;
3392 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3393 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3394
3395 // Note that group name ordering matters here. "a" comes before "b", so
3396 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3397
3398 // Set up one idle socket in "a".
3399 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523400 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463401 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3402 params_,
3403 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523404 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463405 pool_.get(),
3406 BoundNetLog()));
3407
3408 ASSERT_EQ(OK, callback1.WaitForResult());
3409 handle1.Reset();
3410 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3411
3412 // Set up two active sockets in "b".
3413 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523414 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463415 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3416 params_,
3417 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523418 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463419 pool_.get(),
3420 BoundNetLog()));
3421 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3422 params_,
3423 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523424 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463425 pool_.get(),
3426 BoundNetLog()));
3427
3428 ASSERT_EQ(OK, callback1.WaitForResult());
3429 ASSERT_EQ(OK, callback2.WaitForResult());
3430 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103431 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463432 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3433
3434 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3435 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3436 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3437 // sockets for "a", and "b" should still have 2 active sockets.
3438
3439 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3440 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103441 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463442 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3443 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3444 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103445 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463446 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3447 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3448
3449 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3450 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3451 // "a" should result in closing 1 for "b".
3452 handle1.Reset();
3453 handle2.Reset();
3454 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3455 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3456
3457 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3458 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103459 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]dcbe168a2010-12-02 03:14:463460 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3461 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3462 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
[email protected]8159a1c2012-06-07 00:00:103463 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("b"));
[email protected]dcbe168a2010-12-02 03:14:463464 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3465 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3466}
3467
[email protected]b7b8be42011-07-12 12:46:413468TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073469 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3470 pool_->EnableConnectBackupJobs();
3471
3472 // Make the ConnectJob hang until it times out, shorten the timeout.
3473 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3474 connect_job_factory_->set_timeout_duration(
3475 base::TimeDelta::FromMilliseconds(500));
3476 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3477 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103478 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073479 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073480
[email protected]b7b8be42011-07-12 12:46:413481 // Verify the backup timer doesn't create a backup job, by making
3482 // the backup job a pending job instead of a waiting job, so it
3483 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073484 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5761ab9c2012-02-04 16:44:533485 MessageLoop::current()->PostDelayedTask(
3486 FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(1));
[email protected]b7b8be42011-07-12 12:46:413487 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073488 EXPECT_FALSE(pool_->HasGroup("a"));
3489}
3490
[email protected]b7b8be42011-07-12 12:46:413491TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073492 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3493 pool_->EnableConnectBackupJobs();
3494
3495 // Make the ConnectJob hang forever.
3496 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3497 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3498 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103499 EXPECT_EQ(1, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073500 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3501 MessageLoop::current()->RunAllPending();
3502
3503 // Make the backup job be a pending job, so it completes normally.
3504 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3505 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523506 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073507 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3508 params_,
3509 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523510 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073511 pool_.get(),
3512 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413513 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073514 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103515 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073516 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3517 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3518 ASSERT_EQ(OK, callback.WaitForResult());
3519
3520 // The hung connect job should still be there, but everything else should be
3521 // complete.
3522 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
[email protected]8159a1c2012-06-07 00:00:103523 EXPECT_EQ(0, pool_->NumUnassignedConnectJobsInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073524 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3525 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3526}
3527
[email protected]f6d1d6eb2009-06-24 20:16:093528} // namespace
3529
3530} // namespace net