blob: 9a25172f283fe4d50479f5782ae54c67808b1cff [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 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]6ecf2b92011-12-15 01:14:527#include "base/bind.h"
8#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:599#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:0910#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1313#include "base/memory/weak_ptr.h"
[email protected]f6d1d6eb2009-06-24 20:16:0914#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4015#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2516#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0817#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0318#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0619#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5320#include "net/base/net_log.h"
21#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3122#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0923#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3524#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0925#include "net/socket/client_socket_factory.h"
26#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0027#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1728#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1929#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1030#include "net/socket/stream_socket.h"
[email protected]d4dfdab2011-12-07 16:56:5931#include "testing/gmock/include/gmock/gmock.h"
[email protected]f6d1d6eb2009-06-24 20:16:0932#include "testing/gtest/include/gtest/gtest.h"
33
[email protected]d4dfdab2011-12-07 16:56:5934using ::testing::Invoke;
35using ::testing::Return;
36
[email protected]f6d1d6eb2009-06-24 20:16:0937namespace net {
38
39namespace {
40
[email protected]211d21722009-07-22 15:48:5341const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2042const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5243const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0144
[email protected]df4b4ef2010-07-12 18:25:2145class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2046 public:
[email protected]d4dfdab2011-12-07 16:56:5947 TestSocketParams() : ignore_limits_(false) {}
48
49 void set_ignore_limits(bool ignore_limits) {
50 ignore_limits_ = ignore_limits;
51 }
52 bool ignore_limits() { return ignore_limits_; }
53
[email protected]df4b4ef2010-07-12 18:25:2154 private:
55 friend class base::RefCounted<TestSocketParams>;
56 ~TestSocketParams() {}
[email protected]d4dfdab2011-12-07 16:56:5957
58 bool ignore_limits_;
[email protected]df4b4ef2010-07-12 18:25:2159};
[email protected]7fc5b09a2010-02-27 00:07:3860typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4961
[email protected]3268023f2011-05-05 00:08:1062class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0963 public:
[email protected]5e6efa52011-06-27 17:26:4164 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
65 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0966
[email protected]3f55aa12011-12-07 02:03:3367 // Socket implementation.
[email protected]ab838892009-06-30 18:49:0568 virtual int Read(
[email protected]83039bb2011-12-09 18:43:5569 IOBuffer* /* buf */, int len,
70 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]3f55aa12011-12-07 02:03:3371 num_bytes_read_ += len;
72 return len;
73 }
[email protected]ab838892009-06-30 18:49:0574
75 virtual int Write(
[email protected]83039bb2011-12-09 18:43:5576 IOBuffer* /* buf */, int len,
77 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:0178 was_used_to_convey_data_ = true;
79 return len;
[email protected]ab838892009-06-30 18:49:0580 }
[email protected]06650c52010-06-03 00:49:1781 virtual bool SetReceiveBufferSize(int32 size) { return true; }
82 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0583
[email protected]dbf036f2011-12-06 23:33:2484 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:5585 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:2486 connected_ = true;
87 return OK;
88 }
[email protected]f6d1d6eb2009-06-24 20:16:0989
[email protected]ab838892009-06-30 18:49:0590 virtual void Disconnect() { connected_ = false; }
91 virtual bool IsConnected() const { return connected_; }
92 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0193
[email protected]ac9eec62010-02-20 18:50:3894 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1695 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0996 }
[email protected]f6d1d6eb2009-06-24 20:16:0997
[email protected]e7f74da2011-04-19 23:49:3598 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
99 return ERR_UNEXPECTED;
100 }
101
[email protected]a2006ece2010-04-23 16:44:02102 virtual const BoundNetLog& NetLog() const {
103 return net_log_;
104 }
105
[email protected]9b5614a2010-08-25 20:29:45106 virtual void SetSubresourceSpeculation() {}
107 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:41108 virtual bool WasEverUsed() const {
109 return was_used_to_convey_data_ || num_bytes_read_ > 0;
110 }
[email protected]7f7e92392010-10-26 18:29:29111 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:41112 virtual int64 NumBytesRead() const { return num_bytes_read_; }
113 virtual base::TimeDelta GetConnectTimeMicros() const {
114 static const base::TimeDelta kDummyConnectTimeMicros =
115 base::TimeDelta::FromMicroseconds(10);
116 return kDummyConnectTimeMicros; // Dummy value.
117 }
[email protected]9b5614a2010-08-25 20:29:45118
[email protected]f6d1d6eb2009-06-24 20:16:09119 private:
120 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02121 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01122 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41123 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09124
[email protected]ab838892009-06-30 18:49:05125 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09126};
127
[email protected]5fc08e32009-07-15 17:09:57128class TestConnectJob;
129
[email protected]f6d1d6eb2009-06-24 20:16:09130class MockClientSocketFactory : public ClientSocketFactory {
131 public:
[email protected]ab838892009-06-30 18:49:05132 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09133
[email protected]98b0e582011-06-22 14:31:41134 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04135 DatagramSocket::BindType bind_type,
136 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41137 NetLog* net_log,
138 const NetLog::Source& source) {
139 NOTREACHED();
140 return NULL;
141 }
142
[email protected]3268023f2011-05-05 00:08:10143 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07144 const AddressList& addresses,
145 NetLog* /* net_log */,
146 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09147 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05148 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09149 }
150
151 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18152 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27153 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21154 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12155 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17156 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09157 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21158 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09159 return NULL;
160 }
161
[email protected]25f47352011-02-25 16:31:59162 virtual void ClearSSLSessionCache() {
163 NOTIMPLEMENTED();
164 }
165
[email protected]5fc08e32009-07-15 17:09:57166 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
167 void SignalJobs();
168
[email protected]f6d1d6eb2009-06-24 20:16:09169 int allocation_count() const { return allocation_count_; }
170
[email protected]f6d1d6eb2009-06-24 20:16:09171 private:
172 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57173 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09174};
175
[email protected]ab838892009-06-30 18:49:05176class TestConnectJob : public ConnectJob {
177 public:
178 enum JobType {
179 kMockJob,
180 kMockFailingJob,
181 kMockPendingJob,
182 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57183 kMockWaitingJob,
184 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13185 kMockRecoverableJob,
186 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18187 kMockAdditionalErrorStateJob,
188 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05189 };
190
[email protected]994d4932010-07-12 17:55:13191 // The kMockPendingJob uses a slight delay before allowing the connect
192 // to complete.
193 static const int kPendingConnectDelay = 2;
194
[email protected]ab838892009-06-30 18:49:05195 TestConnectJob(JobType job_type,
196 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49197 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34198 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05199 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30200 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17201 NetLog* net_log)
202 : ConnectJob(group_name, timeout_duration, delegate,
203 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58204 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05205 client_socket_factory_(client_socket_factory),
[email protected]6ea7b152011-12-21 21:21:13206 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
[email protected]e60e47a2010-07-14 03:37:18207 load_state_(LOAD_STATE_IDLE),
208 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05209
[email protected]974ebd62009-08-03 23:14:34210 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13211 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34212 }
213
[email protected]46451352009-09-01 14:54:21214 virtual LoadState GetLoadState() const { return load_state_; }
215
[email protected]e60e47a2010-07-14 03:37:18216 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
217 if (store_additional_error_state_) {
218 // Set all of the additional error state fields in some way.
219 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43220 HttpResponseInfo info;
221 info.headers = new HttpResponseHeaders("");
222 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18223 }
224 }
225
[email protected]974ebd62009-08-03 23:14:34226 private:
[email protected]3f55aa12011-12-07 02:03:33227 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05228
[email protected]974ebd62009-08-03 23:14:34229 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05230 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28231 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07232 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40233 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05234 switch (job_type_) {
235 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13236 return DoConnect(true /* successful */, false /* sync */,
237 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05238 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13239 return DoConnect(false /* error */, false /* sync */,
240 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05241 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57242 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47243
244 // Depending on execution timings, posting a delayed task can result
245 // in the task getting executed the at the earliest possible
246 // opportunity or only after returning once from the message loop and
247 // then a second call into the message loop. In order to make behavior
248 // more deterministic, we change the default delay to 2ms. This should
249 // always require us to wait for the second call into the message loop.
250 //
251 // N.B. The correct fix for this and similar timing problems is to
252 // abstract time for the purpose of unittests. Unfortunately, we have
253 // a lot of third-party components that directly call the various
254 // time functions, so this change would be rather invasive.
255 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05256 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13257 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
258 weak_factory_.GetWeakPtr(),
259 true /* successful */,
260 true /* async */,
261 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13262 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05263 return ERR_IO_PENDING;
264 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57265 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47266 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05267 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13268 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
269 weak_factory_.GetWeakPtr(),
270 false /* error */,
271 true /* async */,
272 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47273 2);
[email protected]ab838892009-06-30 18:49:05274 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57275 case kMockWaitingJob:
276 client_socket_factory_->WaitForSignal(this);
277 waiting_success_ = true;
278 return ERR_IO_PENDING;
279 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46280 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13281 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
282 weak_factory_.GetWeakPtr(), load_state_));
[email protected]5fc08e32009-07-15 17:09:57283 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13284 case kMockRecoverableJob:
285 return DoConnect(false /* error */, false /* sync */,
286 true /* recoverable */);
287 case kMockPendingRecoverableJob:
288 set_load_state(LOAD_STATE_CONNECTING);
289 MessageLoop::current()->PostDelayedTask(
290 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13291 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
292 weak_factory_.GetWeakPtr(),
293 false /* error */,
294 true /* async */,
295 true /* recoverable */),
[email protected]e772db3f2010-07-12 18:11:13296 2);
297 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18298 case kMockAdditionalErrorStateJob:
299 store_additional_error_state_ = true;
300 return DoConnect(false /* error */, false /* sync */,
301 false /* recoverable */);
302 case kMockPendingAdditionalErrorStateJob:
303 set_load_state(LOAD_STATE_CONNECTING);
304 store_additional_error_state_ = true;
305 MessageLoop::current()->PostDelayedTask(
306 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13307 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
308 weak_factory_.GetWeakPtr(),
309 false /* error */,
310 true /* async */,
311 false /* recoverable */),
[email protected]e60e47a2010-07-14 03:37:18312 2);
313 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05314 default:
315 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40316 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05317 return ERR_FAILED;
318 }
319 }
320
[email protected]46451352009-09-01 14:54:21321 void set_load_state(LoadState load_state) { load_state_ = load_state; }
322
[email protected]e772db3f2010-07-12 18:11:13323 int DoConnect(bool succeed, bool was_async, bool recoverable) {
324 int result = OK;
[email protected]ab838892009-06-30 18:49:05325 if (succeed) {
[email protected]83039bb2011-12-09 18:43:55326 socket()->Connect(CompletionCallback());
[email protected]e772db3f2010-07-12 18:11:13327 } else if (recoverable) {
328 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40329 } else {
[email protected]e772db3f2010-07-12 18:11:13330 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40331 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05332 }
[email protected]2ab05b52009-07-01 23:57:58333
334 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30335 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05336 return result;
337 }
338
[email protected]cfa8228c2010-06-17 01:07:56339 // This function helps simulate the progress of load states on a ConnectJob.
340 // Each time it is called it advances the load state and posts a task to be
341 // called again. It stops at the last connecting load state (the one
342 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57343 void AdvanceLoadState(LoadState state) {
344 int tmp = state;
345 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56346 if (tmp < LOAD_STATE_SENDING_REQUEST) {
347 state = static_cast<LoadState>(tmp);
348 set_load_state(state);
349 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13350 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
351 weak_factory_.GetWeakPtr(), state));
[email protected]cfa8228c2010-06-17 01:07:56352 }
[email protected]5fc08e32009-07-15 17:09:57353 }
354
355 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05356 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57357 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13358 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21359 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18360 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05361
362 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
363};
364
[email protected]d80a4322009-08-14 07:07:49365class TestConnectJobFactory
366 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05367 public:
[email protected]5fc08e32009-07-15 17:09:57368 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05369 : job_type_(TestConnectJob::kMockJob),
370 client_socket_factory_(client_socket_factory) {}
371
372 virtual ~TestConnectJobFactory() {}
373
374 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
375
[email protected]974ebd62009-08-03 23:14:34376 void set_timeout_duration(base::TimeDelta timeout_duration) {
377 timeout_duration_ = timeout_duration;
378 }
379
[email protected]3f55aa12011-12-07 02:03:33380 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55381
[email protected]ab838892009-06-30 18:49:05382 virtual ConnectJob* NewConnectJob(
383 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49384 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17385 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05386 return new TestConnectJob(job_type_,
387 group_name,
388 request,
[email protected]974ebd62009-08-03 23:14:34389 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05390 delegate,
[email protected]fd7b7c92009-08-20 19:38:30391 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17392 NULL);
[email protected]ab838892009-06-30 18:49:05393 }
394
[email protected]a796bcec2010-03-22 17:17:26395 virtual base::TimeDelta ConnectionTimeout() const {
396 return timeout_duration_;
397 }
398
[email protected]ab838892009-06-30 18:49:05399 private:
400 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34401 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57402 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05403
404 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
405};
406
407class TestClientSocketPool : public ClientSocketPool {
408 public:
409 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53410 int max_sockets,
[email protected]ab838892009-06-30 18:49:05411 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13412 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16413 base::TimeDelta unused_idle_socket_timeout,
414 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49415 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00416 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16417 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38418 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05419
[email protected]2431756e2010-09-29 20:26:13420 virtual ~TestClientSocketPool() {}
421
[email protected]ab838892009-06-30 18:49:05422 virtual int RequestSocket(
423 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49424 const void* params,
[email protected]ac790b42009-12-02 04:31:31425 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05426 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41427 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59428 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21429 const scoped_refptr<TestSocketParams>* casted_socket_params =
430 static_cast<const scoped_refptr<TestSocketParams>*>(params);
431 return base_.RequestSocket(group_name, *casted_socket_params, priority,
432 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05433 }
434
[email protected]2c2bef152010-10-13 00:55:03435 virtual void RequestSockets(const std::string& group_name,
436 const void* params,
437 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59438 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03439 const scoped_refptr<TestSocketParams>* casted_params =
440 static_cast<const scoped_refptr<TestSocketParams>*>(params);
441
442 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
443 }
444
[email protected]ab838892009-06-30 18:49:05445 virtual void CancelRequest(
446 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59447 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49448 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05449 }
450
451 virtual void ReleaseSocket(
452 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10453 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59454 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24455 base_.ReleaseSocket(group_name, socket, id);
456 }
457
[email protected]d4dfdab2011-12-07 16:56:59458 virtual void Flush() OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24459 base_.Flush();
[email protected]ab838892009-06-30 18:49:05460 }
461
[email protected]d4dfdab2011-12-07 16:56:59462 virtual bool IsStalled() const OVERRIDE {
463 return base_.IsStalled();
464 }
465
466 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49467 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05468 }
469
[email protected]d4dfdab2011-12-07 16:56:59470 virtual int IdleSocketCount() const OVERRIDE {
471 return base_.idle_socket_count();
472 }
[email protected]ab838892009-06-30 18:49:05473
[email protected]d4dfdab2011-12-07 16:56:59474 virtual int IdleSocketCountInGroup(
475 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49476 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05477 }
478
[email protected]d4dfdab2011-12-07 16:56:59479 virtual LoadState GetLoadState(
480 const std::string& group_name,
481 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49482 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05483 }
484
[email protected]d4dfdab2011-12-07 16:56:59485 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
486 base_.AddLayeredPool(pool);
487 }
488
489 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
490 base_.RemoveLayeredPool(pool);
491 }
492
493 virtual DictionaryValue* GetInfoAsValue(
494 const std::string& name,
495 const std::string& type,
496 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27497 return base_.GetInfoAsValue(name, type);
498 }
499
[email protected]d4dfdab2011-12-07 16:56:59500 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26501 return base_.ConnectionTimeout();
502 }
503
[email protected]d4dfdab2011-12-07 16:56:59504 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00505 return base_.histograms();
506 }
[email protected]a796bcec2010-03-22 17:17:26507
[email protected]d80a4322009-08-14 07:07:49508 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20509
[email protected]974ebd62009-08-03 23:14:34510 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49511 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34512 }
513
[email protected]2c2bef152010-10-13 00:55:03514 int NumActiveSocketsInGroup(const std::string& group_name) const {
515 return base_.NumActiveSocketsInGroup(group_name);
516 }
517
[email protected]2abfe90a2010-08-25 17:49:51518 bool HasGroup(const std::string& group_name) const {
519 return base_.HasGroup(group_name);
520 }
521
[email protected]9bf28db2009-08-29 01:35:16522 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
523
[email protected]06d94042010-08-25 01:45:22524 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54525
[email protected]d4dfdab2011-12-07 16:56:59526 bool CloseOneIdleConnectionInLayeredPool() {
527 return base_.CloseOneIdleConnectionInLayeredPool();
528 }
529
[email protected]ab838892009-06-30 18:49:05530 private:
[email protected]d80a4322009-08-14 07:07:49531 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05532
533 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
534};
535
[email protected]a937a06d2009-08-19 21:19:24536} // namespace
537
[email protected]7fc5b09a2010-02-27 00:07:38538REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24539
540namespace {
541
[email protected]5fc08e32009-07-15 17:09:57542void MockClientSocketFactory::SignalJobs() {
543 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
544 it != waiting_jobs_.end(); ++it) {
545 (*it)->Signal();
546 }
547 waiting_jobs_.clear();
548}
549
[email protected]974ebd62009-08-03 23:14:34550class TestConnectJobDelegate : public ConnectJob::Delegate {
551 public:
552 TestConnectJobDelegate()
553 : have_result_(false), waiting_for_result_(false), result_(OK) {}
554 virtual ~TestConnectJobDelegate() {}
555
556 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
557 result_ = result;
[email protected]3268023f2011-05-05 00:08:10558 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07559 // socket.get() should be NULL iff result != OK
560 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34561 delete job;
562 have_result_ = true;
563 if (waiting_for_result_)
564 MessageLoop::current()->Quit();
565 }
566
567 int WaitForResult() {
568 DCHECK(!waiting_for_result_);
569 while (!have_result_) {
570 waiting_for_result_ = true;
571 MessageLoop::current()->Run();
572 waiting_for_result_ = false;
573 }
574 have_result_ = false; // auto-reset for next callback
575 return result_;
576 }
577
578 private:
579 bool have_result_;
580 bool waiting_for_result_;
581 int result_;
582};
583
[email protected]2431756e2010-09-29 20:26:13584class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09585 protected:
[email protected]b89f7e42010-05-20 20:37:00586 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21587 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54588 histograms_("ClientSocketPoolTest") {
589 connect_backup_jobs_enabled_ =
590 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
591 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41592 cleanup_timer_enabled_ =
593 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54594 }
[email protected]2431756e2010-09-29 20:26:13595
[email protected]636b8252011-04-08 19:56:54596 virtual ~ClientSocketPoolBaseTest() {
597 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
598 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41599 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
600 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54601 }
[email protected]c9d6a1d2009-07-14 16:15:20602
[email protected]211d21722009-07-22 15:48:53603 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16604 CreatePoolWithIdleTimeouts(
605 max_sockets,
606 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30607 ClientSocketPool::unused_idle_socket_timeout(),
608 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16609 }
610
611 void CreatePoolWithIdleTimeouts(
612 int max_sockets, int max_sockets_per_group,
613 base::TimeDelta unused_idle_socket_timeout,
614 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20615 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04616 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13617 pool_.reset(new TestClientSocketPool(max_sockets,
618 max_sockets_per_group,
619 &histograms_,
620 unused_idle_socket_timeout,
621 used_idle_socket_timeout,
622 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20623 }
[email protected]f6d1d6eb2009-06-24 20:16:09624
[email protected]ac790b42009-12-02 04:31:31625 int StartRequest(const std::string& group_name,
626 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13627 return test_base_.StartRequestUsingPool<
628 TestClientSocketPool, TestSocketParams>(
629 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09630 }
631
[email protected]2431756e2010-09-29 20:26:13632 int GetOrderOfRequest(size_t index) const {
633 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09634 }
635
[email protected]2431756e2010-09-29 20:26:13636 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
637 return test_base_.ReleaseOneConnection(keep_alive);
638 }
639
640 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
641 test_base_.ReleaseAllConnections(keep_alive);
642 }
643
644 TestSocketRequest* request(int i) { return test_base_.request(i); }
645 size_t requests_size() const { return test_base_.requests_size(); }
646 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
647 size_t completion_count() const { return test_base_.completion_count(); }
648
[email protected]636b8252011-04-08 19:56:54649 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41650 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09651 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04652 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21653 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13654 ClientSocketPoolHistograms histograms_;
655 scoped_ptr<TestClientSocketPool> pool_;
656 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09657};
658
[email protected]5e6efa52011-06-27 17:26:41659TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
660 CreatePool(4, 4);
661 net::SetSocketReusePolicy(0);
662
663 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
664 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
665 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
666 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
667
668 std::map<int, StreamSocket*> sockets_;
669 for (size_t i = 0; i < test_base_.requests_size(); i++) {
670 TestSocketRequest* req = test_base_.request(i);
671 StreamSocket* s = req->handle()->socket();
672 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
673 CHECK(sock);
674 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55675 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41676 }
677
678 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
679
680 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
681 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
682
683 // First socket is warmest.
684 EXPECT_EQ(sockets_[0], req->handle()->socket());
685
686 // Test that NumBytes are as expected.
687 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
688 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
689 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
690 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
691
692 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
693}
694
695TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
696 CreatePool(4, 4);
697 net::SetSocketReusePolicy(2);
698
699 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
700 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
701 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
702 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
703
704 std::map<int, StreamSocket*> sockets_;
705 for (size_t i = 0; i < test_base_.requests_size(); i++) {
706 TestSocketRequest* req = test_base_.request(i);
707 StreamSocket* s = req->handle()->socket();
708 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
709 CHECK(sock);
710 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55711 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41712 }
713
714 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
715
716 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
717 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
718
719 // Last socket is most recently accessed.
720 EXPECT_EQ(sockets_[3], req->handle()->socket());
721 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
722}
723
[email protected]974ebd62009-08-03 23:14:34724// Even though a timeout is specified, it doesn't time out on a synchronous
725// completion.
726TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
727 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06728 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49729 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41730 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03731 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20732 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34733 scoped_ptr<TestConnectJob> job(
734 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12735 "a",
[email protected]974ebd62009-08-03 23:14:34736 request,
737 base::TimeDelta::FromMicroseconds(1),
738 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30739 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17740 NULL));
[email protected]974ebd62009-08-03 23:14:34741 EXPECT_EQ(OK, job->Connect());
742}
743
744TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
745 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06746 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17747 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53748
[email protected]d80a4322009-08-14 07:07:49749 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41750 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03751 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20752 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34753 // Deleted by TestConnectJobDelegate.
754 TestConnectJob* job =
755 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12756 "a",
[email protected]974ebd62009-08-03 23:14:34757 request,
758 base::TimeDelta::FromMicroseconds(1),
759 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30760 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17761 &log);
[email protected]974ebd62009-08-03 23:14:34762 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08763 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34764 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30765
[email protected]b2fcd0e2010-12-01 15:19:40766 net::CapturingNetLog::EntryList entries;
767 log.GetEntries(&entries);
768
769 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46770 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40771 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17772 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40773 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46774 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40775 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17776 NetLog::PHASE_NONE));
777 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40778 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53779 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46780 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40781 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17782 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40783 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34784}
785
[email protected]5fc08e32009-07-15 17:09:57786TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53787 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20788
[email protected]6ecf2b92011-12-15 01:14:52789 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06790 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53791 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
792
[email protected]2431756e2010-09-29 20:26:13793 EXPECT_EQ(OK,
794 handle.Init("a",
795 params_,
796 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52797 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13798 pool_.get(),
799 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09800 EXPECT_TRUE(handle.is_initialized());
801 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09802 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30803
[email protected]b2fcd0e2010-12-01 15:19:40804 net::CapturingNetLog::EntryList entries;
805 log.GetEntries(&entries);
806
807 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46808 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40809 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53810 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40811 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17812 NetLog::PHASE_NONE));
813 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40814 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53815 NetLog::PHASE_NONE));
816 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40817 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09818}
819
[email protected]ab838892009-06-30 18:49:05820TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20822
[email protected]ab838892009-06-30 18:49:05823 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53824 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
825
[email protected]2431756e2010-09-29 20:26:13826 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52827 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18828 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13829 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43830 HttpResponseInfo info;
831 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13832 handle.set_ssl_error_response_info(info);
833 EXPECT_EQ(ERR_CONNECTION_FAILED,
834 handle.Init("a",
835 params_,
836 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52837 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13838 pool_.get(),
839 log.bound()));
840 EXPECT_FALSE(handle.socket());
841 EXPECT_FALSE(handle.is_ssl_error());
842 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30843
[email protected]b2fcd0e2010-12-01 15:19:40844 net::CapturingNetLog::EntryList entries;
845 log.GetEntries(&entries);
846
847 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27848 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40849 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17850 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40851 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17852 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02853 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40854 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09855}
856
[email protected]211d21722009-07-22 15:48:53857TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
858 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
859
[email protected]9e743cd2010-03-16 07:03:53860 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30861
[email protected]211d21722009-07-22 15:48:53862 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
863 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
864 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
865 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
866
[email protected]2431756e2010-09-29 20:26:13867 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53868 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13869 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53870
871 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
872 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
873 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
874
[email protected]2431756e2010-09-29 20:26:13875 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53876
[email protected]2431756e2010-09-29 20:26:13877 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53878 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13879 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53880
881 EXPECT_EQ(1, GetOrderOfRequest(1));
882 EXPECT_EQ(2, GetOrderOfRequest(2));
883 EXPECT_EQ(3, GetOrderOfRequest(3));
884 EXPECT_EQ(4, GetOrderOfRequest(4));
885 EXPECT_EQ(5, GetOrderOfRequest(5));
886 EXPECT_EQ(6, GetOrderOfRequest(6));
887 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17888
889 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13890 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53891}
892
893TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
894 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
895
[email protected]9e743cd2010-03-16 07:03:53896 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30897
[email protected]211d21722009-07-22 15:48:53898 // Reach all limits: max total sockets, and max sockets per group.
899 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
900 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
901 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
902 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
903
[email protected]2431756e2010-09-29 20:26:13904 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53905 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13906 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53907
908 // Now create a new group and verify that we don't starve it.
909 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
910
[email protected]2431756e2010-09-29 20:26:13911 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53912
[email protected]2431756e2010-09-29 20:26:13913 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53914 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13915 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53916
917 EXPECT_EQ(1, GetOrderOfRequest(1));
918 EXPECT_EQ(2, GetOrderOfRequest(2));
919 EXPECT_EQ(3, GetOrderOfRequest(3));
920 EXPECT_EQ(4, GetOrderOfRequest(4));
921 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17922
923 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13924 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53925}
926
927TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
928 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
929
[email protected]ac790b42009-12-02 04:31:31930 EXPECT_EQ(OK, StartRequest("b", LOWEST));
931 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
932 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
933 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[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());
937
[email protected]ac790b42009-12-02 04:31:31938 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
939 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
940 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53941
[email protected]2431756e2010-09-29 20:26:13942 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53943
[email protected]2431756e2010-09-29 20:26:13944 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53945
946 // First 4 requests don't have to wait, and finish in order.
947 EXPECT_EQ(1, GetOrderOfRequest(1));
948 EXPECT_EQ(2, GetOrderOfRequest(2));
949 EXPECT_EQ(3, GetOrderOfRequest(3));
950 EXPECT_EQ(4, GetOrderOfRequest(4));
951
[email protected]ac790b42009-12-02 04:31:31952 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
953 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53954 EXPECT_EQ(7, GetOrderOfRequest(5));
955 EXPECT_EQ(6, GetOrderOfRequest(6));
956 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17957
958 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13959 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53960}
961
962TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
963 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
964
[email protected]ac790b42009-12-02 04:31:31965 EXPECT_EQ(OK, StartRequest("a", LOWEST));
966 EXPECT_EQ(OK, StartRequest("a", LOW));
967 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
968 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53969
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53971 client_socket_factory_.allocation_count());
972
[email protected]ac790b42009-12-02 04:31:31973 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
974 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
975 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53976
[email protected]2431756e2010-09-29 20:26:13977 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53978
[email protected]2431756e2010-09-29 20:26:13979 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53980 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13981 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53982
983 // First 4 requests don't have to wait, and finish in order.
984 EXPECT_EQ(1, GetOrderOfRequest(1));
985 EXPECT_EQ(2, GetOrderOfRequest(2));
986 EXPECT_EQ(3, GetOrderOfRequest(3));
987 EXPECT_EQ(4, GetOrderOfRequest(4));
988
989 // Request ("b", 7) has the highest priority, but we can't make new socket for
990 // group "b", because it has reached the per-group limit. Then we make
991 // socket for ("c", 6), because it has higher priority than ("a", 4),
992 // and we still can't make a socket for group "b".
993 EXPECT_EQ(5, GetOrderOfRequest(5));
994 EXPECT_EQ(6, GetOrderOfRequest(6));
995 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17996
997 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53999}
1000
1001// Make sure that we count connecting sockets against the total limit.
1002TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
1003 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1004
1005 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1006 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1007 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
1008
1009 // Create one asynchronous request.
1010 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1011 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
1012
[email protected]6b175382009-10-13 06:47:471013 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1014 // actually become pending until 2ms after they have been created. In order
1015 // to flush all tasks, we need to wait so that we know there are no
1016 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081017 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:471018 MessageLoop::current()->RunAllPending();
1019
[email protected]211d21722009-07-22 15:48:531020 // The next synchronous request should wait for its turn.
1021 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1022 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
1023
[email protected]2431756e2010-09-29 20:26:131024 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:531025
[email protected]2431756e2010-09-29 20:26:131026 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:531027 client_socket_factory_.allocation_count());
1028
1029 EXPECT_EQ(1, GetOrderOfRequest(1));
1030 EXPECT_EQ(2, GetOrderOfRequest(2));
1031 EXPECT_EQ(3, GetOrderOfRequest(3));
1032 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171033 EXPECT_EQ(5, GetOrderOfRequest(5));
1034
1035 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131036 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531037}
1038
[email protected]6427fe22010-04-16 22:27:411039TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1040 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1041 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1042
1043 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1044 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1045 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1046 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1047
1048 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1049
1050 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1051
1052 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1053 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1054
1055 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1056
[email protected]2431756e2010-09-29 20:26:131057 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411058 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131059 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411060 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131061 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1062 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411063 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1064}
1065
[email protected]d7027bb2010-05-10 18:58:541066TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1067 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1068 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1069
1070 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521071 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131072 EXPECT_EQ(ERR_IO_PENDING,
1073 handle.Init("a",
1074 params_,
1075 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521076 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131077 pool_.get(),
1078 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541079
1080 ClientSocketHandle handles[4];
1081 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521082 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_EQ(ERR_IO_PENDING,
1084 handles[i].Init("b",
1085 params_,
1086 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521087 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131088 pool_.get(),
1089 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541090 }
1091
1092 // One will be stalled, cancel all the handles now.
1093 // This should hit the OnAvailableSocketSlot() code where we previously had
1094 // stalled groups, but no longer have any.
1095 for (size_t i = 0; i < arraysize(handles); ++i)
1096 handles[i].Reset();
1097}
1098
[email protected]eb5a99382010-07-11 03:18:261099TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541100 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1101 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1102
[email protected]eb5a99382010-07-11 03:18:261103 {
1104 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521105 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261106 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131107 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1108 params_,
[email protected]e83326f2010-07-31 17:29:251109 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521110 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131111 pool_.get(),
1112 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261113 }
1114
1115 // Force a stalled group.
1116 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521117 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131118 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1119 params_,
1120 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521121 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131122 pool_.get(),
1123 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261124
1125 // Cancel the stalled request.
1126 stalled_handle.Reset();
1127
1128 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1129 EXPECT_EQ(0, pool_->IdleSocketCount());
1130
1131 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541132 }
1133
[email protected]43a21b82010-06-10 21:30:541134 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1135 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261136}
[email protected]43a21b82010-06-10 21:30:541137
[email protected]eb5a99382010-07-11 03:18:261138TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1139 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1140 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1141
1142 {
1143 ClientSocketHandle handles[kDefaultMaxSockets];
1144 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521145 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131146 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1147 params_,
1148 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521149 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131150 pool_.get(),
1151 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261152 }
1153
1154 // Force a stalled group.
1155 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1156 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521157 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131158 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1159 params_,
1160 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521161 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131162 pool_.get(),
1163 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261164
1165 // Since it is stalled, it should have no connect jobs.
1166 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1167
1168 // Cancel the stalled request.
1169 handles[0].Reset();
1170
[email protected]eb5a99382010-07-11 03:18:261171 // Now we should have a connect job.
1172 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1173
1174 // The stalled socket should connect.
1175 EXPECT_EQ(OK, callback.WaitForResult());
1176
1177 EXPECT_EQ(kDefaultMaxSockets + 1,
1178 client_socket_factory_.allocation_count());
1179 EXPECT_EQ(0, pool_->IdleSocketCount());
1180 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1181
1182 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541183 }
1184
[email protected]eb5a99382010-07-11 03:18:261185 EXPECT_EQ(1, pool_->IdleSocketCount());
1186}
[email protected]43a21b82010-06-10 21:30:541187
[email protected]eb5a99382010-07-11 03:18:261188TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1189 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1190 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541191
[email protected]eb5a99382010-07-11 03:18:261192 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521193 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261194 {
[email protected]d4dfdab2011-12-07 16:56:591195 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261196 ClientSocketHandle handles[kDefaultMaxSockets];
1197 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521198 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401199 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1200 "Take 2: %d", i),
1201 params_,
1202 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521203 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401204 pool_.get(),
1205 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261206 }
1207
1208 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1209 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]d4dfdab2011-12-07 16:56:591210 EXPECT_FALSE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261211
1212 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131213 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1214 params_,
1215 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521216 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131217 pool_.get(),
1218 BoundNetLog()));
[email protected]d4dfdab2011-12-07 16:56:591219 EXPECT_TRUE(pool_->IsStalled());
[email protected]eb5a99382010-07-11 03:18:261220
1221 // Dropping out of scope will close all handles and return them to idle.
1222 }
[email protected]43a21b82010-06-10 21:30:541223
1224 // But if we wait for it, the released idle sockets will be closed in
1225 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101226 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261227
1228 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1229 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541230}
1231
1232// Regression test for http://crbug.com/40952.
1233TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1234 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221235 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541236 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1237
1238 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1239 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521240 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131241 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1242 params_,
1243 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521244 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131245 pool_.get(),
1246 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541247 }
1248
1249 // Flush all the DoReleaseSocket tasks.
1250 MessageLoop::current()->RunAllPending();
1251
1252 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1253 // reuse a socket.
1254 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1255 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521256 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541257
1258 // "0" is special here, since it should be the first entry in the sorted map,
1259 // which is the one which we would close an idle socket for. We shouldn't
1260 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131261 EXPECT_EQ(OK, handle.Init("0",
1262 params_,
1263 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521264 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131265 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211266 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541267
1268 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1269 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1270}
1271
[email protected]ab838892009-06-30 18:49:051272TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531273 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091274
[email protected]c9d6a1d2009-07-14 16:15:201275 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1276 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031277 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311278 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1279 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1280 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1281 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1282 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091283
[email protected]2431756e2010-09-29 20:26:131284 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091285
[email protected]c9d6a1d2009-07-14 16:15:201286 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1287 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131288 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1289 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091290
[email protected]c9d6a1d2009-07-14 16:15:201291 EXPECT_EQ(1, GetOrderOfRequest(1));
1292 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031293 EXPECT_EQ(8, GetOrderOfRequest(3));
1294 EXPECT_EQ(6, GetOrderOfRequest(4));
1295 EXPECT_EQ(4, GetOrderOfRequest(5));
1296 EXPECT_EQ(3, GetOrderOfRequest(6));
1297 EXPECT_EQ(5, GetOrderOfRequest(7));
1298 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171299
1300 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131301 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091302}
1303
[email protected]ab838892009-06-30 18:49:051304TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531305 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091306
[email protected]c9d6a1d2009-07-14 16:15:201307 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1308 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311309 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1310 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1311 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1312 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1313 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091314
[email protected]2431756e2010-09-29 20:26:131315 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091316
[email protected]2431756e2010-09-29 20:26:131317 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1318 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201319
[email protected]2431756e2010-09-29 20:26:131320 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201321 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131322 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1323 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091324}
1325
1326// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051327// The pending connect job will be cancelled and should not call back into
1328// ClientSocketPoolBase.
1329TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201331
[email protected]ab838892009-06-30 18:49:051332 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131333 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521334 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131335 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1336 params_,
1337 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521338 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131339 pool_.get(),
1340 BoundNetLog()));
1341 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091342}
1343
[email protected]ab838892009-06-30 18:49:051344TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531345 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201346
[email protected]ab838892009-06-30 18:49:051347 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061348 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521349 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091350
[email protected]2431756e2010-09-29 20:26:131351 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1352 params_,
1353 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521354 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131355 pool_.get(),
1356 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091357
1358 handle.Reset();
1359
[email protected]6ecf2b92011-12-15 01:14:521360 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131361 EXPECT_EQ(ERR_IO_PENDING,
1362 handle.Init("a",
1363 params_,
1364 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521365 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131366 pool_.get(),
1367 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091368
1369 EXPECT_EQ(OK, callback2.WaitForResult());
1370 EXPECT_FALSE(callback.have_result());
1371
1372 handle.Reset();
1373}
1374
[email protected]ab838892009-06-30 18:49:051375TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531376 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091377
[email protected]c9d6a1d2009-07-14 16:15:201378 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1379 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311380 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1381 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1382 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1383 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1384 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091385
1386 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201387 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131388 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1389 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091390
[email protected]2431756e2010-09-29 20:26:131391 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091392
[email protected]c9d6a1d2009-07-14 16:15:201393 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1394 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131395 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1396 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091397
[email protected]c9d6a1d2009-07-14 16:15:201398 EXPECT_EQ(1, GetOrderOfRequest(1));
1399 EXPECT_EQ(2, GetOrderOfRequest(2));
1400 EXPECT_EQ(5, GetOrderOfRequest(3));
1401 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131402 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1403 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201404 EXPECT_EQ(4, GetOrderOfRequest(6));
1405 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171406
1407 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131408 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091409}
1410
[email protected]6ecf2b92011-12-15 01:14:521411class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091412 public:
[email protected]2ab05b52009-07-01 23:57:581413 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241414 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581415 TestConnectJobFactory* test_connect_job_factory,
1416 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091417 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061418 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581419 within_callback_(false),
1420 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521421 next_job_type_(next_job_type),
1422 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1423 base::Bind(&RequestSocketCallback::OnComplete,
1424 base::Unretained(this)))) {
1425 }
[email protected]f6d1d6eb2009-06-24 20:16:091426
[email protected]6ecf2b92011-12-15 01:14:521427 virtual ~RequestSocketCallback() {}
1428
1429 const CompletionCallback& callback() const { return callback_; }
1430
1431 private:
1432 void OnComplete(int result) {
1433 SetResult(result);
1434 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091435
1436 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581437 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111438
1439 // Don't allow reuse of the socket. Disconnect it and then release it and
1440 // run through the MessageLoop once to get it completely released.
1441 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091442 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111443 {
1444 MessageLoop::ScopedNestableTaskAllower nestable(
1445 MessageLoop::current());
1446 MessageLoop::current()->RunAllPending();
1447 }
[email protected]f6d1d6eb2009-06-24 20:16:091448 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521449 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271450 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131451 int rv = handle_->Init("a",
1452 params,
1453 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521454 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131455 pool_,
1456 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581457 switch (next_job_type_) {
1458 case TestConnectJob::kMockJob:
1459 EXPECT_EQ(OK, rv);
1460 break;
1461 case TestConnectJob::kMockPendingJob:
1462 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471463
1464 // For pending jobs, wait for new socket to be created. This makes
1465 // sure there are no more pending operations nor any unclosed sockets
1466 // when the test finishes.
1467 // We need to give it a little bit of time to run, so that all the
1468 // operations that happen on timers (e.g. cleanup of idle
1469 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111470 {
1471 MessageLoop::ScopedNestableTaskAllower nestable(
1472 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081473 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111474 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1475 }
[email protected]2ab05b52009-07-01 23:57:581476 break;
1477 default:
1478 FAIL() << "Unexpected job type: " << next_job_type_;
1479 break;
1480 }
[email protected]f6d1d6eb2009-06-24 20:16:091481 }
1482 }
1483
[email protected]f6d1d6eb2009-06-24 20:16:091484 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131485 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091486 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581487 TestConnectJobFactory* const test_connect_job_factory_;
1488 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521489 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091490};
1491
[email protected]2ab05b52009-07-01 23:57:581492TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531493 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201494
[email protected]0b7648c2009-07-06 20:14:011495 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061496 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581497 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061498 &handle, pool_.get(), connect_job_factory_,
1499 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131500 int rv = handle.Init("a",
1501 params_,
1502 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521503 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131504 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211505 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091506 ASSERT_EQ(ERR_IO_PENDING, rv);
1507
1508 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581509}
[email protected]f6d1d6eb2009-06-24 20:16:091510
[email protected]2ab05b52009-07-01 23:57:581511TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201513
[email protected]0b7648c2009-07-06 20:14:011514 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061515 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581516 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061517 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131518 int rv = handle.Init("a",
1519 params_,
1520 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521521 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131522 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211523 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581524 ASSERT_EQ(ERR_IO_PENDING, rv);
1525
1526 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091527}
1528
1529// Make sure that pending requests get serviced after active requests get
1530// cancelled.
[email protected]ab838892009-06-30 18:49:051531TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531532 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201533
[email protected]0b7648c2009-07-06 20:14:011534 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091535
[email protected]c9d6a1d2009-07-14 16:15:201536 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1537 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1538 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1539 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091543
[email protected]c9d6a1d2009-07-14 16:15:201544 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1545 // Let's cancel them.
1546 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131547 ASSERT_FALSE(request(i)->handle()->is_initialized());
1548 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091549 }
1550
[email protected]f6d1d6eb2009-06-24 20:16:091551 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131552 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1553 EXPECT_EQ(OK, request(i)->WaitForResult());
1554 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091555 }
1556
[email protected]2431756e2010-09-29 20:26:131557 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1558 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091559}
1560
1561// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051562TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531563 const size_t kMaxSockets = 5;
1564 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201565
[email protected]0b7648c2009-07-06 20:14:011566 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091567
[email protected]211d21722009-07-22 15:48:531568 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1569 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091570
1571 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531572 for (size_t i = 0; i < kNumberOfRequests; ++i)
1573 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091574
[email protected]211d21722009-07-22 15:48:531575 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131576 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091577}
1578
[email protected]5fc08e32009-07-15 17:09:571579TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531580 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571581
1582 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1583
[email protected]2431756e2010-09-29 20:26:131584 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521585 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131586 int rv = handle.Init("a",
1587 params_,
1588 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521589 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131590 pool_.get(),
1591 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571592 EXPECT_EQ(ERR_IO_PENDING, rv);
1593
1594 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131595 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571596
[email protected]2431756e2010-09-29 20:26:131597 rv = handle.Init("a",
1598 params_,
1599 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521600 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131601 pool_.get(),
1602 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571603 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131604 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571605
[email protected]2431756e2010-09-29 20:26:131606 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571607 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1608}
1609
[email protected]2b7523d2009-07-29 20:29:231610// Regression test for http://crbug.com/17985.
1611TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1612 const int kMaxSockets = 3;
1613 const int kMaxSocketsPerGroup = 2;
1614 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1615
[email protected]ac790b42009-12-02 04:31:311616 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231617
1618 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1619 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1620
1621 // This is going to be a pending request in an otherwise empty group.
1622 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1623
1624 // Reach the maximum socket limit.
1625 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1626
1627 // Create a stalled group with high priorities.
1628 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1629 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231630
[email protected]eb5a99382010-07-11 03:18:261631 // Release the first two sockets from "a". Because this is a keepalive,
1632 // the first release will unblock the pending request for "a". The
1633 // second release will unblock a request for "c", becaue it is the next
1634 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131635 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1636 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231637
1638 // Closing idle sockets should not get us into trouble, but in the bug
1639 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411640 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541641 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261642
1643 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231644}
1645
[email protected]4d3b05d2010-01-27 21:27:291646TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531647 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571648
1649 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131650 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521651 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531652 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131653 int rv = handle.Init("a",
1654 params_,
1655 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521656 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131657 pool_.get(),
1658 log.bound());
[email protected]5fc08e32009-07-15 17:09:571659 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131660 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1661 EXPECT_EQ(OK, callback.WaitForResult());
1662 EXPECT_TRUE(handle.is_initialized());
1663 EXPECT_TRUE(handle.socket());
1664 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301665
[email protected]b2fcd0e2010-12-01 15:19:401666 net::CapturingNetLog::EntryList entries;
1667 log.GetEntries(&entries);
1668
1669 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461670 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401671 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171672 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401673 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171674 NetLog::PHASE_NONE));
1675 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401676 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171677 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461678 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401679 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571680}
1681
[email protected]4d3b05d2010-01-27 21:27:291682TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571683 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531684 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571685
1686 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131687 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521688 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531689 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181690 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131691 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431692 HttpResponseInfo info;
1693 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131694 handle.set_ssl_error_response_info(info);
1695 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1696 params_,
1697 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521698 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131699 pool_.get(),
1700 log.bound()));
1701 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1702 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1703 EXPECT_FALSE(handle.is_ssl_error());
1704 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301705
[email protected]b2fcd0e2010-12-01 15:19:401706 net::CapturingNetLog::EntryList entries;
1707 log.GetEntries(&entries);
1708
1709 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461710 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401711 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171712 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401713 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171714 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321715 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401716 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571717}
1718
[email protected]4d3b05d2010-01-27 21:27:291719TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101720 // TODO(eroman): Add back the log expectations! Removed them because the
1721 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531722 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571723
1724 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131725 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521726 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131727 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521728 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571729
[email protected]2431756e2010-09-29 20:26:131730 EXPECT_EQ(ERR_IO_PENDING,
1731 handle.Init("a",
1732 params_,
1733 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521734 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131735 pool_.get(),
1736 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531737 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131738 EXPECT_EQ(ERR_IO_PENDING,
1739 handle2.Init("a",
1740 params_,
1741 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521742 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131743 pool_.get(),
1744 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571745
[email protected]2431756e2010-09-29 20:26:131746 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571747
[email protected]fd7b7c92009-08-20 19:38:301748
1749 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301750
[email protected]2431756e2010-09-29 20:26:131751 EXPECT_EQ(OK, callback2.WaitForResult());
1752 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301753
1754 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531755 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571756}
1757
[email protected]4d3b05d2010-01-27 21:27:291758TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341759 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1760
[email protected]17a0c6c2009-08-04 00:07:041761 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1762
[email protected]ac790b42009-12-02 04:31:311763 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1764 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1765 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1766 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341767
1768 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131769 (*requests())[2]->handle()->Reset();
1770 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341771 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1772
[email protected]2431756e2010-09-29 20:26:131773 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341774 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1775
[email protected]2431756e2010-09-29 20:26:131776 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261777 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341778}
1779
[email protected]5fc08e32009-07-15 17:09:571780// When requests and ConnectJobs are not coupled, the request will get serviced
1781// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291782TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531783 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571784
1785 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321786 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571787
[email protected]2431756e2010-09-29 20:26:131788 std::vector<TestSocketRequest*> request_order;
1789 size_t completion_count; // unused
1790 TestSocketRequest req1(&request_order, &completion_count);
1791 int rv = req1.handle()->Init("a",
1792 params_,
1793 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521794 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211795 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571796 EXPECT_EQ(ERR_IO_PENDING, rv);
1797 EXPECT_EQ(OK, req1.WaitForResult());
1798
1799 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1800 // without a job.
1801 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1802
[email protected]2431756e2010-09-29 20:26:131803 TestSocketRequest req2(&request_order, &completion_count);
1804 rv = req2.handle()->Init("a",
1805 params_,
1806 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521807 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131808 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211809 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571810 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131811 TestSocketRequest req3(&request_order, &completion_count);
1812 rv = req3.handle()->Init("a",
1813 params_,
1814 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521815 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131816 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211817 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571818 EXPECT_EQ(ERR_IO_PENDING, rv);
1819
1820 // Both Requests 2 and 3 are pending. We release socket 1 which should
1821 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331822 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261823 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331824 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571825 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331826 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571827
1828 // Signal job 2, which should service request 3.
1829
1830 client_socket_factory_.SignalJobs();
1831 EXPECT_EQ(OK, req3.WaitForResult());
1832
[email protected]2431756e2010-09-29 20:26:131833 ASSERT_EQ(3U, request_order.size());
1834 EXPECT_EQ(&req1, request_order[0]);
1835 EXPECT_EQ(&req2, request_order[1]);
1836 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571837 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1838}
1839
1840// The requests are not coupled to the jobs. So, the requests should finish in
1841// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291842TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531843 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571844 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321845 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571846
[email protected]2431756e2010-09-29 20:26:131847 std::vector<TestSocketRequest*> request_order;
1848 size_t completion_count; // unused
1849 TestSocketRequest req1(&request_order, &completion_count);
1850 int rv = req1.handle()->Init("a",
1851 params_,
1852 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521853 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131854 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211855 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571856 EXPECT_EQ(ERR_IO_PENDING, rv);
1857
[email protected]2431756e2010-09-29 20:26:131858 TestSocketRequest req2(&request_order, &completion_count);
1859 rv = req2.handle()->Init("a",
1860 params_,
1861 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521862 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131863 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211864 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571865 EXPECT_EQ(ERR_IO_PENDING, rv);
1866
1867 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321868 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571869
[email protected]2431756e2010-09-29 20:26:131870 TestSocketRequest req3(&request_order, &completion_count);
1871 rv = req3.handle()->Init("a",
1872 params_,
1873 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521874 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131875 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211876 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571877 EXPECT_EQ(ERR_IO_PENDING, rv);
1878
1879 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1880 EXPECT_EQ(OK, req2.WaitForResult());
1881 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1882
[email protected]2431756e2010-09-29 20:26:131883 ASSERT_EQ(3U, request_order.size());
1884 EXPECT_EQ(&req1, request_order[0]);
1885 EXPECT_EQ(&req2, request_order[1]);
1886 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571887}
1888
[email protected]e6ec67b2010-06-16 00:12:461889TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531890 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571891 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321892 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571893
[email protected]2431756e2010-09-29 20:26:131894 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521895 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131896 int rv = handle.Init("a",
1897 params_,
1898 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521899 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131900 pool_.get(),
1901 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131903 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571904
1905 MessageLoop::current()->RunAllPending();
1906
[email protected]2431756e2010-09-29 20:26:131907 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521908 TestCompletionCallback callback2;
1909 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1910 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571911 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131912 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1913 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571914}
1915
[email protected]e772db3f2010-07-12 18:11:131916TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1917 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1918 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1919
[email protected]2431756e2010-09-29 20:26:131920 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521921 TestCompletionCallback callback;
1922 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1923 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1924 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131925 EXPECT_TRUE(handle.is_initialized());
1926 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131927}
1928
1929TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1930 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1931
1932 connect_job_factory_->set_job_type(
1933 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131934 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521935 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131936 EXPECT_EQ(ERR_IO_PENDING,
1937 handle.Init("a",
1938 params_,
1939 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521940 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131941 pool_.get(),
1942 BoundNetLog()));
1943 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1944 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1945 EXPECT_TRUE(handle.is_initialized());
1946 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131947}
1948
[email protected]e60e47a2010-07-14 03:37:181949TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1951 connect_job_factory_->set_job_type(
1952 TestConnectJob::kMockAdditionalErrorStateJob);
1953
[email protected]2431756e2010-09-29 20:26:131954 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521955 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131956 EXPECT_EQ(ERR_CONNECTION_FAILED,
1957 handle.Init("a",
1958 params_,
1959 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521960 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131961 pool_.get(),
1962 BoundNetLog()));
1963 EXPECT_FALSE(handle.is_initialized());
1964 EXPECT_FALSE(handle.socket());
1965 EXPECT_TRUE(handle.is_ssl_error());
1966 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181967}
1968
1969TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1971
1972 connect_job_factory_->set_job_type(
1973 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131974 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521975 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131976 EXPECT_EQ(ERR_IO_PENDING,
1977 handle.Init("a",
1978 params_,
1979 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521980 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131981 pool_.get(),
1982 BoundNetLog()));
1983 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1984 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1985 EXPECT_FALSE(handle.is_initialized());
1986 EXPECT_FALSE(handle.socket());
1987 EXPECT_TRUE(handle.is_ssl_error());
1988 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181989}
1990
[email protected]64770b7d2011-11-16 04:30:411991TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1992 // Disable cleanup timer.
1993 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1994
1995 CreatePoolWithIdleTimeouts(
1996 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1997 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
1998 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
1999
2000 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2001
2002 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2003
2004 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522005 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:412006 int rv = handle.Init("a",
2007 params_,
2008 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522009 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:412010 pool_.get(),
2011 BoundNetLog());
2012 EXPECT_EQ(ERR_IO_PENDING, rv);
2013 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
2014
2015 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522016 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:412017 rv = handle2.Init("a",
2018 params_,
2019 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522020 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:412021 pool_.get(),
2022 BoundNetLog());
2023 EXPECT_EQ(ERR_IO_PENDING, rv);
2024 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
2025
2026 // Cancel one of the requests. Wait for the other, which will get the first
2027 // job. Release the socket. Run the loop again to make sure the second
2028 // socket is sitting idle and the first one is released (since ReleaseSocket()
2029 // just posts a DoReleaseSocket() task).
2030
2031 handle.Reset();
2032 EXPECT_EQ(OK, callback2.WaitForResult());
2033 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552034 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412035 handle2.Reset();
2036
[email protected]d4dfdab2011-12-07 16:56:592037 // The idle socket timeout value was set to 10 milliseconds. Wait 100
[email protected]64770b7d2011-11-16 04:30:412038 // milliseconds so the sockets timeout.
[email protected]d4dfdab2011-12-07 16:56:592039 base::PlatformThread::Sleep(100);
[email protected]64770b7d2011-11-16 04:30:412040 MessageLoop::current()->RunAllPending();
2041
2042 ASSERT_EQ(2, pool_->IdleSocketCount());
2043
2044 // Request a new socket. This should cleanup the unused and timed out ones.
2045 // A new socket will be created rather than reusing the idle one.
2046 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]6ecf2b92011-12-15 01:14:522047 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412048 rv = handle.Init("a",
2049 params_,
2050 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522051 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412052 pool_.get(),
2053 log.bound());
2054 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6ecf2b92011-12-15 01:14:522055 EXPECT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412056 EXPECT_FALSE(handle.is_reused());
2057
2058 // Make sure the idle socket is closed
2059 ASSERT_TRUE(pool_->HasGroup("a"));
2060 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2061 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2062
2063 net::CapturingNetLog::EntryList entries;
2064 log.GetEntries(&entries);
2065 EXPECT_FALSE(LogContainsEntryWithType(
2066 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2067}
2068
[email protected]4d3b05d2010-01-27 21:27:292069TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162070 CreatePoolWithIdleTimeouts(
2071 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2072 base::TimeDelta(), // Time out unused sockets immediately.
2073 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2074
2075 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2076
2077 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2078
[email protected]2431756e2010-09-29 20:26:132079 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522080 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132081 int rv = handle.Init("a",
2082 params_,
2083 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522084 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132085 pool_.get(),
2086 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162087 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132088 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162089
[email protected]2431756e2010-09-29 20:26:132090 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522091 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132092 rv = handle2.Init("a",
2093 params_,
2094 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522095 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132096 pool_.get(),
2097 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162098 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132099 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162100
2101 // Cancel one of the requests. Wait for the other, which will get the first
2102 // job. Release the socket. Run the loop again to make sure the second
2103 // socket is sitting idle and the first one is released (since ReleaseSocket()
2104 // just posts a DoReleaseSocket() task).
2105
[email protected]2431756e2010-09-29 20:26:132106 handle.Reset();
2107 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012108 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552109 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132110 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472111
2112 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2113 // actually become pending until 2ms after they have been created. In order
2114 // to flush all tasks, we need to wait so that we know there are no
2115 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:082116 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:162117 MessageLoop::current()->RunAllPending();
2118
2119 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042120
[email protected]9bf28db2009-08-29 01:35:162121 // Invoke the idle socket cleanup check. Only one socket should be left, the
2122 // used socket. Request it to make sure that it's used.
2123
2124 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532125 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132126 rv = handle.Init("a",
2127 params_,
2128 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522129 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132130 pool_.get(),
2131 log.bound());
[email protected]9bf28db2009-08-29 01:35:162132 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132133 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402134
2135 net::CapturingNetLog::EntryList entries;
2136 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152137 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402138 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162139}
2140
[email protected]2041cf342010-02-19 03:15:592141// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162142// because of multiple releasing disconnected sockets.
2143TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2144 CreatePoolWithIdleTimeouts(
2145 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2146 base::TimeDelta(), // Time out unused sockets immediately.
2147 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2148
2149 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2150
2151 // Startup 4 connect jobs. Two of them will be pending.
2152
[email protected]2431756e2010-09-29 20:26:132153 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522154 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132155 int rv = handle.Init("a",
2156 params_,
2157 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522158 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132159 pool_.get(),
2160 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162161 EXPECT_EQ(OK, rv);
2162
[email protected]2431756e2010-09-29 20:26:132163 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522164 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132165 rv = handle2.Init("a",
2166 params_,
2167 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522168 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132169 pool_.get(),
2170 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162171 EXPECT_EQ(OK, rv);
2172
[email protected]2431756e2010-09-29 20:26:132173 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522174 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132175 rv = handle3.Init("a",
2176 params_,
2177 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522178 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132179 pool_.get(),
2180 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162181 EXPECT_EQ(ERR_IO_PENDING, rv);
2182
[email protected]2431756e2010-09-29 20:26:132183 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522184 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132185 rv = handle4.Init("a",
2186 params_,
2187 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522188 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132189 pool_.get(),
2190 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162191 EXPECT_EQ(ERR_IO_PENDING, rv);
2192
2193 // Release two disconnected sockets.
2194
[email protected]2431756e2010-09-29 20:26:132195 handle.socket()->Disconnect();
2196 handle.Reset();
2197 handle2.socket()->Disconnect();
2198 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162199
[email protected]2431756e2010-09-29 20:26:132200 EXPECT_EQ(OK, callback3.WaitForResult());
2201 EXPECT_FALSE(handle3.is_reused());
2202 EXPECT_EQ(OK, callback4.WaitForResult());
2203 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162204}
2205
[email protected]d7027bb2010-05-10 18:58:542206// Regression test for http://crbug.com/42267.
2207// When DoReleaseSocket() is processed for one socket, it is blocked because the
2208// other stalled groups all have releasing sockets, so no progress can be made.
2209TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2210 CreatePoolWithIdleTimeouts(
2211 4 /* socket limit */, 4 /* socket limit per group */,
2212 base::TimeDelta(), // Time out unused sockets immediately.
2213 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2214
2215 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2216
2217 // Max out the socket limit with 2 per group.
2218
[email protected]2431756e2010-09-29 20:26:132219 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522220 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132221 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522222 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542223
2224 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132225 EXPECT_EQ(OK, handle_a[i].Init("a",
2226 params_,
2227 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522228 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132229 pool_.get(),
2230 BoundNetLog()));
2231 EXPECT_EQ(OK, handle_b[i].Init("b",
2232 params_,
2233 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522234 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132235 pool_.get(),
2236 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542237 }
[email protected]b89f7e42010-05-20 20:37:002238
[email protected]d7027bb2010-05-10 18:58:542239 // Make 4 pending requests, 2 per group.
2240
2241 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132242 EXPECT_EQ(ERR_IO_PENDING,
2243 handle_a[i].Init("a",
2244 params_,
2245 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522246 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132247 pool_.get(),
2248 BoundNetLog()));
2249 EXPECT_EQ(ERR_IO_PENDING,
2250 handle_b[i].Init("b",
2251 params_,
2252 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522253 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132254 pool_.get(),
2255 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542256 }
2257
2258 // Release b's socket first. The order is important, because in
2259 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2260 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2261 // first, which has a releasing socket, so it refuses to start up another
2262 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132263 handle_b[0].socket()->Disconnect();
2264 handle_b[0].Reset();
2265 handle_a[0].socket()->Disconnect();
2266 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542267
2268 // Used to get stuck here.
2269 MessageLoop::current()->RunAllPending();
2270
[email protected]2431756e2010-09-29 20:26:132271 handle_b[1].socket()->Disconnect();
2272 handle_b[1].Reset();
2273 handle_a[1].socket()->Disconnect();
2274 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542275
2276 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132277 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2278 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542279 }
2280}
2281
[email protected]fd4fe0b2010-02-08 23:02:152282TEST_F(ClientSocketPoolBaseTest,
2283 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2284 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2285
2286 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2287
2288 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2289 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2290 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2291 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2292
[email protected]2431756e2010-09-29 20:26:132293 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2294 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2295 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152296
2297 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132298 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2299 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152300
[email protected]2431756e2010-09-29 20:26:132301 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2302 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2303 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152304
2305 EXPECT_EQ(1, GetOrderOfRequest(1));
2306 EXPECT_EQ(2, GetOrderOfRequest(2));
2307 EXPECT_EQ(3, GetOrderOfRequest(3));
2308 EXPECT_EQ(4, GetOrderOfRequest(4));
2309
2310 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132311 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152312}
2313
[email protected]6ecf2b92011-12-15 01:14:522314class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042315 public:
[email protected]2431756e2010-09-29 20:26:132316 TestReleasingSocketRequest(TestClientSocketPool* pool,
2317 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182318 bool reset_releasing_handle)
2319 : pool_(pool),
2320 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522321 reset_releasing_handle_(reset_releasing_handle),
2322 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2323 base::Bind(&TestReleasingSocketRequest::OnComplete,
2324 base::Unretained(this)))) {
2325 }
2326
2327 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042328
2329 ClientSocketHandle* handle() { return &handle_; }
2330
[email protected]6ecf2b92011-12-15 01:14:522331 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042332
2333 private:
[email protected]6ecf2b92011-12-15 01:14:522334 void OnComplete(int result) {
2335 SetResult(result);
2336 if (reset_releasing_handle_)
2337 handle_.Reset();
2338
2339 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2340 EXPECT_EQ(expected_result_,
2341 handle2_.Init("a", con_params, kDefaultPriority,
2342 callback2_.callback(), pool_, BoundNetLog()));
2343 }
2344
[email protected]2431756e2010-09-29 20:26:132345 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182346 int expected_result_;
2347 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042348 ClientSocketHandle handle_;
2349 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522350 CompletionCallback callback_;
2351 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042352};
2353
[email protected]e60e47a2010-07-14 03:37:182354
2355TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2356 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2357
2358 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2359 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2360 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2361
[email protected]2431756e2010-09-29 20:26:132362 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182363 client_socket_factory_.allocation_count());
2364
2365 connect_job_factory_->set_job_type(
2366 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2367 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132368 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522369 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2370 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182371 // The next job should complete synchronously
2372 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2373
2374 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2375 EXPECT_FALSE(req.handle()->is_initialized());
2376 EXPECT_FALSE(req.handle()->socket());
2377 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432378 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182379}
2380
[email protected]b6501d3d2010-06-03 23:53:342381// http://crbug.com/44724 regression test.
2382// We start releasing the pool when we flush on network change. When that
2383// happens, the only active references are in the ClientSocketHandles. When a
2384// ConnectJob completes and calls back into the last ClientSocketHandle, that
2385// callback can release the last reference and delete the pool. After the
2386// callback finishes, we go back to the stack frame within the now-deleted pool.
2387// Executing any code that refers to members of the now-deleted pool can cause
2388// crashes.
2389TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2390 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2391 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2392
2393 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522394 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132395 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2396 params_,
2397 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522398 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132399 pool_.get(),
2400 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342401
[email protected]2431756e2010-09-29 20:26:132402 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342403
2404 // We'll call back into this now.
2405 callback.WaitForResult();
2406}
2407
[email protected]a7e38572010-06-07 18:22:242408TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2409 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2410 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2411
2412 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522413 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132414 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2415 params_,
2416 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522417 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132418 pool_.get(),
2419 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242420 EXPECT_EQ(OK, callback.WaitForResult());
2421 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2422
2423 pool_->Flush();
2424
2425 handle.Reset();
2426 MessageLoop::current()->RunAllPending();
2427
[email protected]2431756e2010-09-29 20:26:132428 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2429 params_,
2430 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522431 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132432 pool_.get(),
2433 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242434 EXPECT_EQ(OK, callback.WaitForResult());
2435 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2436}
2437
[email protected]6ecf2b92011-12-15 01:14:522438class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142439 public:
2440 ConnectWithinCallback(
2441 const std::string& group_name,
2442 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132443 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522444 : group_name_(group_name),
2445 params_(params),
2446 pool_(pool),
2447 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2448 base::Bind(&ConnectWithinCallback::OnComplete,
2449 base::Unretained(this)))) {
[email protected]06f92462010-08-31 19:24:142450 }
2451
[email protected]6ecf2b92011-12-15 01:14:522452 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142453
2454 int WaitForNestedResult() {
2455 return nested_callback_.WaitForResult();
2456 }
2457
[email protected]6ecf2b92011-12-15 01:14:522458 const CompletionCallback& callback() const { return callback_; }
2459
[email protected]06f92462010-08-31 19:24:142460 private:
[email protected]6ecf2b92011-12-15 01:14:522461 void OnComplete(int result) {
2462 SetResult(result);
2463 EXPECT_EQ(ERR_IO_PENDING,
2464 handle_.Init(group_name_,
2465 params_,
2466 kDefaultPriority,
2467 nested_callback_.callback(),
2468 pool_,
2469 BoundNetLog()));
2470 }
2471
[email protected]06f92462010-08-31 19:24:142472 const std::string group_name_;
2473 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132474 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142475 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522476 CompletionCallback callback_;
2477 TestCompletionCallback nested_callback_;
2478
2479 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142480};
2481
2482TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2483 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2484
2485 // First job will be waiting until it gets aborted.
2486 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2487
2488 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132489 ConnectWithinCallback callback("a", params_, pool_.get());
2490 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2491 params_,
2492 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522493 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132494 pool_.get(),
2495 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142496
2497 // Second job will be started during the first callback, and will
2498 // asynchronously complete with OK.
2499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2500 pool_->Flush();
2501 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2502 EXPECT_EQ(OK, callback.WaitForNestedResult());
2503}
2504
[email protected]25eea382010-07-10 23:55:262505// Cancel a pending socket request while we're at max sockets,
2506// and verify that the backup socket firing doesn't cause a crash.
2507TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2508 // Max 4 sockets globally, max 4 sockets per group.
2509 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222510 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262511
[email protected]4baaf9d2010-08-31 15:15:442512 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2513 // timer.
[email protected]25eea382010-07-10 23:55:262514 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2515 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522516 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132517 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2518 params_,
2519 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522520 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132521 pool_.get(),
2522 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262523
2524 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2525 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2526 ClientSocketHandle handles[kDefaultMaxSockets];
2527 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522528 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132529 EXPECT_EQ(OK, handles[i].Init("bar",
2530 params_,
2531 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522532 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132533 pool_.get(),
2534 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262535 }
2536
2537 MessageLoop::current()->RunAllPending();
2538
2539 // Cancel the pending request.
2540 handle.Reset();
2541
2542 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082543 base::PlatformThread::Sleep(
2544 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262545
2546 MessageLoop::current()->RunAllPending();
2547 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2548}
2549
[email protected]3f00be82010-09-27 19:50:022550TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442551 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2552 pool_->EnableConnectBackupJobs();
2553
2554 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2555 // timer.
2556 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2557 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522558 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2560 params_,
2561 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522562 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132563 pool_.get(),
2564 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442565 ASSERT_TRUE(pool_->HasGroup("bar"));
2566 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2567
2568 // Cancel the socket request. This should cancel the backup timer. Wait for
2569 // the backup time to see if it indeed got canceled.
2570 handle.Reset();
2571 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082572 base::PlatformThread::Sleep(
2573 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442574 MessageLoop::current()->RunAllPending();
2575 ASSERT_TRUE(pool_->HasGroup("bar"));
2576 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2577}
2578
[email protected]3f00be82010-09-27 19:50:022579TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2580 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2581 pool_->EnableConnectBackupJobs();
2582
2583 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2584 // timer.
2585 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2586 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522587 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132588 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2589 params_,
2590 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522591 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132592 pool_.get(),
2593 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022594 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2595 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522596 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132597 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2598 params_,
2599 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522600 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132601 pool_.get(),
2602 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022603 ASSERT_TRUE(pool_->HasGroup("bar"));
2604 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2605
2606 // Cancel request 1 and then complete request 2. With the requests finished,
2607 // the backup timer should be cancelled.
2608 handle.Reset();
2609 EXPECT_EQ(OK, callback2.WaitForResult());
2610 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082611 base::PlatformThread::Sleep(
2612 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022613 MessageLoop::current()->RunAllPending();
2614}
2615
[email protected]eb5a99382010-07-11 03:18:262616// Test delayed socket binding for the case where we have two connects,
2617// and while one is waiting on a connect, the other frees up.
2618// The socket waiting on a connect should switch immediately to the freed
2619// up socket.
2620TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2621 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2622 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2623
2624 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522625 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132626 EXPECT_EQ(ERR_IO_PENDING,
2627 handle1.Init("a",
2628 params_,
2629 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522630 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132631 pool_.get(),
2632 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262633 EXPECT_EQ(OK, callback.WaitForResult());
2634
2635 // No idle sockets, no pending jobs.
2636 EXPECT_EQ(0, pool_->IdleSocketCount());
2637 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2638
2639 // Create a second socket to the same host, but this one will wait.
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2641 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132642 EXPECT_EQ(ERR_IO_PENDING,
2643 handle2.Init("a",
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]eb5a99382010-07-11 03:18:262649 // No idle sockets, and one connecting job.
2650 EXPECT_EQ(0, pool_->IdleSocketCount());
2651 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2652
2653 // Return the first handle to the pool. This will initiate the delayed
2654 // binding.
2655 handle1.Reset();
2656
2657 MessageLoop::current()->RunAllPending();
2658
2659 // Still no idle sockets, still one pending connect job.
2660 EXPECT_EQ(0, pool_->IdleSocketCount());
2661 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2662
2663 // The second socket connected, even though it was a Waiting Job.
2664 EXPECT_EQ(OK, callback.WaitForResult());
2665
2666 // And we can see there is still one job waiting.
2667 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2668
2669 // Finally, signal the waiting Connect.
2670 client_socket_factory_.SignalJobs();
2671 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2672
2673 MessageLoop::current()->RunAllPending();
2674}
2675
2676// Test delayed socket binding when a group is at capacity and one
2677// of the group's sockets frees up.
2678TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2679 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2680 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2681
2682 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522683 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132684 EXPECT_EQ(ERR_IO_PENDING,
2685 handle1.Init("a",
2686 params_,
2687 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522688 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132689 pool_.get(),
2690 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262691 EXPECT_EQ(OK, callback.WaitForResult());
2692
2693 // No idle sockets, no pending jobs.
2694 EXPECT_EQ(0, pool_->IdleSocketCount());
2695 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2696
2697 // Create a second socket to the same host, but this one will wait.
2698 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2699 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132700 EXPECT_EQ(ERR_IO_PENDING,
2701 handle2.Init("a",
2702 params_,
2703 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522704 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132705 pool_.get(),
2706 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262707 // No idle sockets, and one connecting job.
2708 EXPECT_EQ(0, pool_->IdleSocketCount());
2709 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2710
2711 // Return the first handle to the pool. This will initiate the delayed
2712 // binding.
2713 handle1.Reset();
2714
2715 MessageLoop::current()->RunAllPending();
2716
2717 // Still no idle sockets, still one pending connect job.
2718 EXPECT_EQ(0, pool_->IdleSocketCount());
2719 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2720
2721 // The second socket connected, even though it was a Waiting Job.
2722 EXPECT_EQ(OK, callback.WaitForResult());
2723
2724 // And we can see there is still one job waiting.
2725 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2726
2727 // Finally, signal the waiting Connect.
2728 client_socket_factory_.SignalJobs();
2729 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2730
2731 MessageLoop::current()->RunAllPending();
2732}
2733
2734// Test out the case where we have one socket connected, one
2735// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512736// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262737// should complete, by taking the first socket's idle socket.
2738TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2740 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2741
2742 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522743 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132744 EXPECT_EQ(ERR_IO_PENDING,
2745 handle1.Init("a",
2746 params_,
2747 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522748 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132749 pool_.get(),
2750 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262751 EXPECT_EQ(OK, callback.WaitForResult());
2752
2753 // No idle sockets, no pending jobs.
2754 EXPECT_EQ(0, pool_->IdleSocketCount());
2755 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2756
2757 // Create a second socket to the same host, but this one will wait.
2758 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2759 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132760 EXPECT_EQ(ERR_IO_PENDING,
2761 handle2.Init("a",
2762 params_,
2763 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522764 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132765 pool_.get(),
2766 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262767 // No idle sockets, and one connecting job.
2768 EXPECT_EQ(0, pool_->IdleSocketCount());
2769 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2770
2771 // Return the first handle to the pool. This will initiate the delayed
2772 // binding.
2773 handle1.Reset();
2774
2775 MessageLoop::current()->RunAllPending();
2776
2777 // Still no idle sockets, still one pending connect job.
2778 EXPECT_EQ(0, pool_->IdleSocketCount());
2779 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2780
2781 // The second socket connected, even though it was a Waiting Job.
2782 EXPECT_EQ(OK, callback.WaitForResult());
2783
2784 // And we can see there is still one job waiting.
2785 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2786
2787 // Finally, signal the waiting Connect.
2788 client_socket_factory_.SignalJobs();
2789 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2790
2791 MessageLoop::current()->RunAllPending();
2792}
2793
[email protected]2abfe90a2010-08-25 17:49:512794// Cover the case where on an available socket slot, we have one pending
2795// request that completes synchronously, thereby making the Group empty.
2796TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2797 const int kUnlimitedSockets = 100;
2798 const int kOneSocketPerGroup = 1;
2799 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2800
2801 // Make the first request asynchronous fail.
2802 // This will free up a socket slot later.
2803 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2804
2805 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522806 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132807 EXPECT_EQ(ERR_IO_PENDING,
2808 handle1.Init("a",
2809 params_,
2810 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522811 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132812 pool_.get(),
2813 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512814 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2815
2816 // Make the second request synchronously fail. This should make the Group
2817 // empty.
2818 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2819 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522820 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512821 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2822 // when created.
[email protected]2431756e2010-09-29 20:26:132823 EXPECT_EQ(ERR_IO_PENDING,
2824 handle2.Init("a",
2825 params_,
2826 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522827 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132828 pool_.get(),
2829 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512830
2831 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2832
2833 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2834 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2835 EXPECT_FALSE(pool_->HasGroup("a"));
2836}
2837
[email protected]e1b54dc2010-10-06 21:27:222838TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2839 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2840
2841 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2842
2843 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522844 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222845 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2846 params_,
2847 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522848 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222849 pool_.get(),
2850 BoundNetLog()));
2851
2852 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522853 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222854 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2855 params_,
2856 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522857 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222858 pool_.get(),
2859 BoundNetLog()));
2860 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522861 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222862 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2863 params_,
2864 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522865 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222866 pool_.get(),
2867 BoundNetLog()));
2868
2869 EXPECT_EQ(OK, callback1.WaitForResult());
2870 EXPECT_EQ(OK, callback2.WaitForResult());
2871 EXPECT_EQ(OK, callback3.WaitForResult());
2872
2873 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552874 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2875 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222876
2877 handle1.Reset();
2878 handle2.Reset();
2879 handle3.Reset();
2880
2881 EXPECT_EQ(OK, handle1.Init("a",
2882 params_,
2883 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522884 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222885 pool_.get(),
2886 BoundNetLog()));
2887 EXPECT_EQ(OK, handle2.Init("a",
2888 params_,
2889 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522890 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222891 pool_.get(),
2892 BoundNetLog()));
2893 EXPECT_EQ(OK, handle3.Init("a",
2894 params_,
2895 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522896 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222897 pool_.get(),
2898 BoundNetLog()));
2899
2900 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2901 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2902 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2903}
2904
[email protected]2c2bef152010-10-13 00:55:032905TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2907 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2908
2909 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2910
2911 ASSERT_TRUE(pool_->HasGroup("a"));
2912 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2913 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2914
2915 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522916 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032917 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2918 params_,
2919 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522920 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032921 pool_.get(),
2922 BoundNetLog()));
2923
2924 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522925 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032926 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2927 params_,
2928 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522929 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:032930 pool_.get(),
2931 BoundNetLog()));
2932
2933 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2934 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2935
2936 EXPECT_EQ(OK, callback1.WaitForResult());
2937 EXPECT_EQ(OK, callback2.WaitForResult());
2938 handle1.Reset();
2939 handle2.Reset();
2940
2941 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2942 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2943}
2944
2945TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2946 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2947 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2948
2949 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522950 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032951 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2952 params_,
2953 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522954 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032955 pool_.get(),
2956 BoundNetLog()));
2957
2958 ASSERT_TRUE(pool_->HasGroup("a"));
2959 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2960 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2961
2962 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2963
2964 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2965 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2966
2967 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522968 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032969 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2970 params_,
2971 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522972 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:032973 pool_.get(),
2974 BoundNetLog()));
2975
2976 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2977 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2978
2979 EXPECT_EQ(OK, callback1.WaitForResult());
2980 EXPECT_EQ(OK, callback2.WaitForResult());
2981 handle1.Reset();
2982 handle2.Reset();
2983
2984 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2985 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2986}
2987
2988TEST_F(ClientSocketPoolBaseTest,
2989 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2990 CreatePool(4, 4);
2991 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2992
2993 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522994 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032995 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2996 params_,
2997 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522998 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032999 pool_.get(),
3000 BoundNetLog()));
3001
3002 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523003 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033004 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
3005 params_,
3006 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523007 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033008 pool_.get(),
3009 BoundNetLog()));
3010
3011 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:523012 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:033013 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
3014 params_,
3015 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523016 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:033017 pool_.get(),
3018 BoundNetLog()));
3019
3020 ASSERT_TRUE(pool_->HasGroup("a"));
3021 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3022 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3023
3024 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3025
3026 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3027 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3028
3029 EXPECT_EQ(OK, callback1.WaitForResult());
3030 EXPECT_EQ(OK, callback2.WaitForResult());
3031 EXPECT_EQ(OK, callback3.WaitForResult());
3032 handle1.Reset();
3033 handle2.Reset();
3034 handle3.Reset();
3035
3036 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3037 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3038}
3039
3040TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3041 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3043
3044 ASSERT_FALSE(pool_->HasGroup("a"));
3045
3046 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3047 BoundNetLog());
3048
3049 ASSERT_TRUE(pool_->HasGroup("a"));
3050 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3051
3052 ASSERT_FALSE(pool_->HasGroup("b"));
3053
3054 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3055 BoundNetLog());
3056
3057 ASSERT_FALSE(pool_->HasGroup("b"));
3058}
3059
3060TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3061 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3062 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3063
3064 ASSERT_FALSE(pool_->HasGroup("a"));
3065
3066 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3067 BoundNetLog());
3068
3069 ASSERT_TRUE(pool_->HasGroup("a"));
3070 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]d4dfdab2011-12-07 16:56:593071 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033072
3073 ASSERT_FALSE(pool_->HasGroup("b"));
3074
3075 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3076 BoundNetLog());
3077
3078 ASSERT_TRUE(pool_->HasGroup("b"));
3079 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
[email protected]d4dfdab2011-12-07 16:56:593080 EXPECT_FALSE(pool_->IsStalled());
[email protected]2c2bef152010-10-13 00:55:033081}
3082
3083TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3084 CreatePool(4, 4);
3085 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3086
3087 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523088 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033089 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3090 params_,
3091 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523092 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033093 pool_.get(),
3094 BoundNetLog()));
3095 ASSERT_EQ(OK, callback1.WaitForResult());
3096 handle1.Reset();
3097
3098 ASSERT_TRUE(pool_->HasGroup("a"));
3099 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3100 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3101
3102 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3103
3104 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3105 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3106}
3107
3108TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3109 CreatePool(4, 4);
3110 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3111
3112 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523113 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033114 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3115 params_,
3116 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523117 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033118 pool_.get(),
3119 BoundNetLog()));
3120 ASSERT_EQ(OK, callback1.WaitForResult());
3121
3122 ASSERT_TRUE(pool_->HasGroup("a"));
3123 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3124 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3125 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3126
3127 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3128
3129 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3130 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3131 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3132}
3133
3134TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3135 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3136 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3137
3138 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3139 BoundNetLog());
3140
3141 ASSERT_TRUE(pool_->HasGroup("a"));
3142 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3143 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3144
3145 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3146 BoundNetLog());
3147
3148 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3149 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3150}
3151
[email protected]3c819f522010-12-02 02:03:123152TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3153 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3154 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3155
3156 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3157 BoundNetLog());
3158
3159 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523160
3161 connect_job_factory_->set_job_type(
3162 TestConnectJob::kMockAdditionalErrorStateJob);
3163 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3164 BoundNetLog());
3165
3166 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123167}
3168
[email protected]2c2bef152010-10-13 00:55:033169TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3170 CreatePool(4, 4);
3171 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3172
3173 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3174
3175 ASSERT_TRUE(pool_->HasGroup("a"));
3176 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3177 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3178
3179 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3180 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3181 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3182
3183 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523184 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033185 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3186 params_,
3187 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523188 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033189 pool_.get(),
3190 BoundNetLog()));
3191 ASSERT_EQ(OK, callback1.WaitForResult());
3192
3193 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523194 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033195 int rv = handle2.Init("a",
3196 params_,
3197 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523198 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033199 pool_.get(),
3200 BoundNetLog());
3201 if (rv != OK) {
3202 EXPECT_EQ(ERR_IO_PENDING, rv);
3203 EXPECT_EQ(OK, callback2.WaitForResult());
3204 }
3205
3206 handle1.Reset();
3207 handle2.Reset();
3208
3209 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3210
3211 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3212 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3213 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3214}
3215
3216TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3217 CreatePool(4, 4);
3218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3219
3220 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3221
3222 ASSERT_TRUE(pool_->HasGroup("a"));
3223 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3224 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3225
3226 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3227 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3228 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3229
3230 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3231 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3232 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3233
3234 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3235 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3236 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3237}
3238
3239TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3240 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3241 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3242
3243 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3244
3245 ASSERT_TRUE(pool_->HasGroup("a"));
3246 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3247 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3248
3249 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523250 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033251 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3252 params_,
3253 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523254 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033255 pool_.get(),
3256 BoundNetLog()));
3257
3258 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3259 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3260
3261 ASSERT_EQ(OK, callback1.WaitForResult());
3262
3263 handle1.Reset();
3264
3265 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3266}
3267
[email protected]dcbe168a2010-12-02 03:14:463268// http://crbug.com/64940 regression test.
3269TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3270 const int kMaxTotalSockets = 3;
3271 const int kMaxSocketsPerGroup = 2;
3272 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3273 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3274
3275 // Note that group name ordering matters here. "a" comes before "b", so
3276 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3277
3278 // Set up one idle socket in "a".
3279 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523280 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463281 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3282 params_,
3283 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523284 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463285 pool_.get(),
3286 BoundNetLog()));
3287
3288 ASSERT_EQ(OK, callback1.WaitForResult());
3289 handle1.Reset();
3290 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3291
3292 // Set up two active sockets in "b".
3293 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523294 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463295 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3296 params_,
3297 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523298 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463299 pool_.get(),
3300 BoundNetLog()));
3301 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3302 params_,
3303 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523304 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463305 pool_.get(),
3306 BoundNetLog()));
3307
3308 ASSERT_EQ(OK, callback1.WaitForResult());
3309 ASSERT_EQ(OK, callback2.WaitForResult());
3310 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3311 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3312
3313 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3314 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3315 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3316 // sockets for "a", and "b" should still have 2 active sockets.
3317
3318 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3319 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3320 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3321 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3322 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3323 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3324 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3325
3326 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3327 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3328 // "a" should result in closing 1 for "b".
3329 handle1.Reset();
3330 handle2.Reset();
3331 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3332 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3333
3334 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3335 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3336 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3337 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3338 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3339 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3340 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3341}
3342
[email protected]b7b8be42011-07-12 12:46:413343TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073344 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3345 pool_->EnableConnectBackupJobs();
3346
3347 // Make the ConnectJob hang until it times out, shorten the timeout.
3348 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3349 connect_job_factory_->set_timeout_duration(
3350 base::TimeDelta::FromMilliseconds(500));
3351 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3352 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3353 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073354
[email protected]b7b8be42011-07-12 12:46:413355 // Verify the backup timer doesn't create a backup job, by making
3356 // the backup job a pending job instead of a waiting job, so it
3357 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073358 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413359 MessageLoop::current()->PostDelayedTask(FROM_HERE,
[email protected]72d27ce2011-12-09 00:41:123360 MessageLoop::QuitClosure(), 1000);
[email protected]b7b8be42011-07-12 12:46:413361 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073362 EXPECT_FALSE(pool_->HasGroup("a"));
3363}
3364
[email protected]b7b8be42011-07-12 12:46:413365TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073366 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3367 pool_->EnableConnectBackupJobs();
3368
3369 // Make the ConnectJob hang forever.
3370 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3371 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3372 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3373 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3374 MessageLoop::current()->RunAllPending();
3375
3376 // Make the backup job be a pending job, so it completes normally.
3377 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3378 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523379 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073380 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3381 params_,
3382 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523383 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073384 pool_.get(),
3385 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413386 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073387 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3388 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3389 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3390 ASSERT_EQ(OK, callback.WaitForResult());
3391
3392 // The hung connect job should still be there, but everything else should be
3393 // complete.
3394 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3395 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3396 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3397}
3398
[email protected]d4dfdab2011-12-07 16:56:593399class MockLayeredPool : public LayeredPool {
3400 public:
3401 MockLayeredPool(TestClientSocketPool* pool,
3402 const std::string& group_name)
3403 : pool_(pool),
3404 params_(new TestSocketParams),
3405 group_name_(group_name) {
3406 pool_->AddLayeredPool(this);
3407 }
3408
3409 ~MockLayeredPool() {
3410 pool_->RemoveLayeredPool(this);
3411 }
3412
3413 int RequestSocket(TestClientSocketPool* pool) {
[email protected]6ecf2b92011-12-15 01:14:523414 return handle_.Init(group_name_, params_, kDefaultPriority,
3415 callback_.callback(), pool, BoundNetLog());
[email protected]d4dfdab2011-12-07 16:56:593416 }
3417
3418 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3419 params_->set_ignore_limits(true);
[email protected]6ecf2b92011-12-15 01:14:523420 return handle_.Init(group_name_, params_, kDefaultPriority,
3421 callback_.callback(), pool, BoundNetLog());
[email protected]d4dfdab2011-12-07 16:56:593422 }
3423
3424 bool ReleaseOneConnection() {
3425 if (!handle_.is_initialized()) {
3426 return false;
3427 }
3428 handle_.socket()->Disconnect();
3429 handle_.Reset();
3430 return true;
3431 }
3432
3433 MOCK_METHOD0(CloseOneIdleConnection, bool());
3434
3435 private:
3436 TestClientSocketPool* const pool_;
3437 scoped_refptr<TestSocketParams> params_;
3438 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:523439 TestCompletionCallback callback_;
[email protected]d4dfdab2011-12-07 16:56:593440 const std::string group_name_;
3441};
3442
3443TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3444 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3445 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3446
3447 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3448 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3449 .WillOnce(Return(false));
3450 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3451 EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool());
3452}
3453
3454TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3455 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3456 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3457
3458 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3459 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3460 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3461 .WillOnce(Invoke(&mock_layered_pool,
3462 &MockLayeredPool::ReleaseOneConnection));
3463 EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool());
3464}
3465
3466TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3467 CreatePool(1, 1);
3468 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3469
3470 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3471 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3472 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3473 .WillOnce(Invoke(&mock_layered_pool,
3474 &MockLayeredPool::ReleaseOneConnection));
3475 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523476 TestCompletionCallback callback;
[email protected]d4dfdab2011-12-07 16:56:593477 EXPECT_EQ(OK, handle.Init("a",
3478 params_,
3479 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523480 callback.callback(),
[email protected]d4dfdab2011-12-07 16:56:593481 pool_.get(),
3482 BoundNetLog()));
3483}
3484
3485TEST_F(ClientSocketPoolBaseTest,
3486 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3487 CreatePool(1, 1);
3488 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3489
3490 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3491 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3492 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3493 .WillRepeatedly(Invoke(&mock_layered_pool1,
3494 &MockLayeredPool::ReleaseOneConnection));
3495 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3496 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3497 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3498 .WillRepeatedly(Invoke(&mock_layered_pool2,
3499 &MockLayeredPool::ReleaseOneConnection));
3500 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523501 TestCompletionCallback callback;
[email protected]d4dfdab2011-12-07 16:56:593502 EXPECT_EQ(OK, handle.Init("a",
3503 params_,
3504 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523505 callback.callback(),
[email protected]d4dfdab2011-12-07 16:56:593506 pool_.get(),
3507 BoundNetLog()));
3508}
3509
[email protected]f6d1d6eb2009-06-24 20:16:093510} // namespace
3511
3512} // namespace net