blob: d318dd6fab48fc6e05dbde9468f492d9e8f253c3 [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]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_vector.h"
[email protected]f6d1d6eb2009-06-24 20:16:0911#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4012#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0814#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0315#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0616#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5317#include "net/base/net_log.h"
18#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3119#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0920#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3521#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0922#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1027#include "net/socket/stream_socket.h"
[email protected]f6d1d6eb2009-06-24 20:16:0928#include "testing/gtest/include/gtest/gtest.h"
29
30namespace net {
31
32namespace {
33
[email protected]211d21722009-07-22 15:48:5334const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2035const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5236const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0137
[email protected]df4b4ef2010-07-12 18:25:2138class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2039 public:
[email protected]83e43302011-11-30 06:14:4240 bool ignore_limits() { return false; }
[email protected]df4b4ef2010-07-12 18:25:2141 private:
42 friend class base::RefCounted<TestSocketParams>;
43 ~TestSocketParams() {}
44};
[email protected]7fc5b09a2010-02-27 00:07:3845typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4946
[email protected]3268023f2011-05-05 00:08:1047class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0948 public:
[email protected]5e6efa52011-06-27 17:26:4149 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
50 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0951
[email protected]ab838892009-06-30 18:49:0552 // Socket methods:
53 virtual int Read(
[email protected]f1f3f0f82011-10-01 20:38:1054 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]5e6efa52011-06-27 17:26:4155 num_bytes_read_ += len;
56 return len;
[email protected]ab838892009-06-30 18:49:0557 }
58
59 virtual int Write(
[email protected]f1f3f0f82011-10-01 20:38:1060 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]0f873e82010-09-02 16:09:0161 was_used_to_convey_data_ = true;
62 return len;
[email protected]ab838892009-06-30 18:49:0563 }
[email protected]06650c52010-06-03 00:49:1764 virtual bool SetReceiveBufferSize(int32 size) { return true; }
65 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0566
[email protected]dbf036f2011-12-06 23:33:2467 // StreamSocket implementation.
[email protected]f1f3f0f82011-10-01 20:38:1068 virtual int Connect(OldCompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0969 connected_ = true;
70 return OK;
71 }
[email protected]dbf036f2011-12-06 23:33:2472 virtual int Connect(const net::CompletionCallback& callback) {
73 connected_ = true;
74 return OK;
75 }
[email protected]f6d1d6eb2009-06-24 20:16:0976
[email protected]ab838892009-06-30 18:49:0577 virtual void Disconnect() { connected_ = false; }
78 virtual bool IsConnected() const { return connected_; }
79 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0180
[email protected]ac9eec62010-02-20 18:50:3881 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1682 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0983 }
[email protected]f6d1d6eb2009-06-24 20:16:0984
[email protected]e7f74da2011-04-19 23:49:3585 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
86 return ERR_UNEXPECTED;
87 }
88
[email protected]a2006ece2010-04-23 16:44:0289 virtual const BoundNetLog& NetLog() const {
90 return net_log_;
91 }
92
[email protected]9b5614a2010-08-25 20:29:4593 virtual void SetSubresourceSpeculation() {}
94 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:4195 virtual bool WasEverUsed() const {
96 return was_used_to_convey_data_ || num_bytes_read_ > 0;
97 }
[email protected]7f7e92392010-10-26 18:29:2998 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:4199 virtual int64 NumBytesRead() const { return num_bytes_read_; }
100 virtual base::TimeDelta GetConnectTimeMicros() const {
101 static const base::TimeDelta kDummyConnectTimeMicros =
102 base::TimeDelta::FromMicroseconds(10);
103 return kDummyConnectTimeMicros; // Dummy value.
104 }
[email protected]9b5614a2010-08-25 20:29:45105
[email protected]f6d1d6eb2009-06-24 20:16:09106 private:
107 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02108 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01109 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41110 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09111
[email protected]ab838892009-06-30 18:49:05112 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09113};
114
[email protected]5fc08e32009-07-15 17:09:57115class TestConnectJob;
116
[email protected]f6d1d6eb2009-06-24 20:16:09117class MockClientSocketFactory : public ClientSocketFactory {
118 public:
[email protected]ab838892009-06-30 18:49:05119 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09120
[email protected]98b0e582011-06-22 14:31:41121 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04122 DatagramSocket::BindType bind_type,
123 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41124 NetLog* net_log,
125 const NetLog::Source& source) {
126 NOTREACHED();
127 return NULL;
128 }
129
[email protected]3268023f2011-05-05 00:08:10130 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07131 const AddressList& addresses,
132 NetLog* /* net_log */,
133 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09134 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05135 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09136 }
137
138 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18139 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27140 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21141 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12142 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17143 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09144 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21145 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09146 return NULL;
147 }
148
[email protected]25f47352011-02-25 16:31:59149 virtual void ClearSSLSessionCache() {
150 NOTIMPLEMENTED();
151 }
152
[email protected]5fc08e32009-07-15 17:09:57153 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
154 void SignalJobs();
155
[email protected]f6d1d6eb2009-06-24 20:16:09156 int allocation_count() const { return allocation_count_; }
157
[email protected]f6d1d6eb2009-06-24 20:16:09158 private:
159 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57160 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09161};
162
[email protected]ab838892009-06-30 18:49:05163class TestConnectJob : public ConnectJob {
164 public:
165 enum JobType {
166 kMockJob,
167 kMockFailingJob,
168 kMockPendingJob,
169 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57170 kMockWaitingJob,
171 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13172 kMockRecoverableJob,
173 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18174 kMockAdditionalErrorStateJob,
175 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05176 };
177
[email protected]994d4932010-07-12 17:55:13178 // The kMockPendingJob uses a slight delay before allowing the connect
179 // to complete.
180 static const int kPendingConnectDelay = 2;
181
[email protected]ab838892009-06-30 18:49:05182 TestConnectJob(JobType job_type,
183 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49184 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34185 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05186 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30187 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17188 NetLog* net_log)
189 : ConnectJob(group_name, timeout_duration, delegate,
190 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58191 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05192 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21193 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18194 load_state_(LOAD_STATE_IDLE),
195 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05196
[email protected]974ebd62009-08-03 23:14:34197 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13198 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34199 }
200
[email protected]46451352009-09-01 14:54:21201 virtual LoadState GetLoadState() const { return load_state_; }
202
[email protected]e60e47a2010-07-14 03:37:18203 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
204 if (store_additional_error_state_) {
205 // Set all of the additional error state fields in some way.
206 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43207 HttpResponseInfo info;
208 info.headers = new HttpResponseHeaders("");
209 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18210 }
211 }
212
[email protected]974ebd62009-08-03 23:14:34213 private:
[email protected]ab838892009-06-30 18:49:05214 // ConnectJob methods:
215
[email protected]974ebd62009-08-03 23:14:34216 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05217 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28218 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07219 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40220 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05221 switch (job_type_) {
222 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13223 return DoConnect(true /* successful */, false /* sync */,
224 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05225 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13226 return DoConnect(false /* error */, false /* sync */,
227 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05228 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57229 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47230
231 // Depending on execution timings, posting a delayed task can result
232 // in the task getting executed the at the earliest possible
233 // opportunity or only after returning once from the message loop and
234 // then a second call into the message loop. In order to make behavior
235 // more deterministic, we change the default delay to 2ms. This should
236 // always require us to wait for the second call into the message loop.
237 //
238 // N.B. The correct fix for this and similar timing problems is to
239 // abstract time for the purpose of unittests. Unfortunately, we have
240 // a lot of third-party components that directly call the various
241 // time functions, so this change would be rather invasive.
242 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05243 FROM_HERE,
244 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47245 &TestConnectJob::DoConnect,
246 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13247 true /* async */,
248 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13249 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05250 return ERR_IO_PENDING;
251 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57252 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47253 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05254 FROM_HERE,
255 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47256 &TestConnectJob::DoConnect,
257 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13258 true /* async */,
259 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47260 2);
[email protected]ab838892009-06-30 18:49:05261 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57262 case kMockWaitingJob:
263 client_socket_factory_->WaitForSignal(this);
264 waiting_success_ = true;
265 return ERR_IO_PENDING;
266 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46267 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57268 FROM_HERE,
269 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46270 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57271 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13272 case kMockRecoverableJob:
273 return DoConnect(false /* error */, false /* sync */,
274 true /* recoverable */);
275 case kMockPendingRecoverableJob:
276 set_load_state(LOAD_STATE_CONNECTING);
277 MessageLoop::current()->PostDelayedTask(
278 FROM_HERE,
279 method_factory_.NewRunnableMethod(
280 &TestConnectJob::DoConnect,
281 false /* error */,
282 true /* async */,
283 true /* recoverable */),
284 2);
285 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18286 case kMockAdditionalErrorStateJob:
287 store_additional_error_state_ = true;
288 return DoConnect(false /* error */, false /* sync */,
289 false /* recoverable */);
290 case kMockPendingAdditionalErrorStateJob:
291 set_load_state(LOAD_STATE_CONNECTING);
292 store_additional_error_state_ = true;
293 MessageLoop::current()->PostDelayedTask(
294 FROM_HERE,
295 method_factory_.NewRunnableMethod(
296 &TestConnectJob::DoConnect,
297 false /* error */,
298 true /* async */,
299 false /* recoverable */),
300 2);
301 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05302 default:
303 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40304 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05305 return ERR_FAILED;
306 }
307 }
308
[email protected]46451352009-09-01 14:54:21309 void set_load_state(LoadState load_state) { load_state_ = load_state; }
310
[email protected]e772db3f2010-07-12 18:11:13311 int DoConnect(bool succeed, bool was_async, bool recoverable) {
312 int result = OK;
[email protected]ab838892009-06-30 18:49:05313 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02314 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13315 } else if (recoverable) {
316 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40317 } else {
[email protected]e772db3f2010-07-12 18:11:13318 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40319 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05320 }
[email protected]2ab05b52009-07-01 23:57:58321
322 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30323 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05324 return result;
325 }
326
[email protected]cfa8228c2010-06-17 01:07:56327 // This function helps simulate the progress of load states on a ConnectJob.
328 // Each time it is called it advances the load state and posts a task to be
329 // called again. It stops at the last connecting load state (the one
330 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57331 void AdvanceLoadState(LoadState state) {
332 int tmp = state;
333 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56334 if (tmp < LOAD_STATE_SENDING_REQUEST) {
335 state = static_cast<LoadState>(tmp);
336 set_load_state(state);
337 MessageLoop::current()->PostTask(
338 FROM_HERE,
339 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
340 state));
341 }
[email protected]5fc08e32009-07-15 17:09:57342 }
343
344 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05345 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57346 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05347 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21348 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18349 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05350
351 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
352};
353
[email protected]d80a4322009-08-14 07:07:49354class TestConnectJobFactory
355 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05356 public:
[email protected]5fc08e32009-07-15 17:09:57357 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05358 : job_type_(TestConnectJob::kMockJob),
359 client_socket_factory_(client_socket_factory) {}
360
361 virtual ~TestConnectJobFactory() {}
362
363 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
364
[email protected]974ebd62009-08-03 23:14:34365 void set_timeout_duration(base::TimeDelta timeout_duration) {
366 timeout_duration_ = timeout_duration;
367 }
368
[email protected]ab838892009-06-30 18:49:05369 // ConnectJobFactory methods:
370
371 virtual ConnectJob* NewConnectJob(
372 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49373 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17374 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05375 return new TestConnectJob(job_type_,
376 group_name,
377 request,
[email protected]974ebd62009-08-03 23:14:34378 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05379 delegate,
[email protected]fd7b7c92009-08-20 19:38:30380 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17381 NULL);
[email protected]ab838892009-06-30 18:49:05382 }
383
[email protected]a796bcec2010-03-22 17:17:26384 virtual base::TimeDelta ConnectionTimeout() const {
385 return timeout_duration_;
386 }
387
[email protected]ab838892009-06-30 18:49:05388 private:
389 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34390 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57391 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05392
393 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
394};
395
396class TestClientSocketPool : public ClientSocketPool {
397 public:
398 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53399 int max_sockets,
[email protected]ab838892009-06-30 18:49:05400 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13401 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16402 base::TimeDelta unused_idle_socket_timeout,
403 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49404 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00405 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16406 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38407 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05408
[email protected]2431756e2010-09-29 20:26:13409 virtual ~TestClientSocketPool() {}
410
[email protected]ab838892009-06-30 18:49:05411 virtual int RequestSocket(
412 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49413 const void* params,
[email protected]ac790b42009-12-02 04:31:31414 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05415 ClientSocketHandle* handle,
[email protected]f1f3f0f82011-10-01 20:38:10416 OldCompletionCallback* callback,
[email protected]83e43302011-11-30 06:14:42417 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21418 const scoped_refptr<TestSocketParams>* casted_socket_params =
419 static_cast<const scoped_refptr<TestSocketParams>*>(params);
420 return base_.RequestSocket(group_name, *casted_socket_params, priority,
421 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05422 }
423
[email protected]2c2bef152010-10-13 00:55:03424 virtual void RequestSockets(const std::string& group_name,
425 const void* params,
426 int num_sockets,
[email protected]83e43302011-11-30 06:14:42427 const BoundNetLog& net_log) {
[email protected]2c2bef152010-10-13 00:55:03428 const scoped_refptr<TestSocketParams>* casted_params =
429 static_cast<const scoped_refptr<TestSocketParams>*>(params);
430
431 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
432 }
433
[email protected]ab838892009-06-30 18:49:05434 virtual void CancelRequest(
435 const std::string& group_name,
[email protected]83e43302011-11-30 06:14:42436 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49437 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05438 }
439
440 virtual void ReleaseSocket(
441 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10442 StreamSocket* socket,
[email protected]83e43302011-11-30 06:14:42443 int id) {
[email protected]a7e38572010-06-07 18:22:24444 base_.ReleaseSocket(group_name, socket, id);
445 }
446
[email protected]83e43302011-11-30 06:14:42447 virtual void Flush() {
[email protected]a7e38572010-06-07 18:22:24448 base_.Flush();
[email protected]ab838892009-06-30 18:49:05449 }
450
[email protected]83e43302011-11-30 06:14:42451 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49452 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05453 }
454
[email protected]83e43302011-11-30 06:14:42455 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05456
[email protected]83e43302011-11-30 06:14:42457 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49458 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05459 }
460
[email protected]83e43302011-11-30 06:14:42461 virtual LoadState GetLoadState(const std::string& group_name,
462 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49463 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05464 }
465
[email protected]83e43302011-11-30 06:14:42466 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
467 const std::string& type,
468 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27469 return base_.GetInfoAsValue(name, type);
470 }
471
[email protected]83e43302011-11-30 06:14:42472 virtual base::TimeDelta ConnectionTimeout() const {
[email protected]a796bcec2010-03-22 17:17:26473 return base_.ConnectionTimeout();
474 }
475
[email protected]83e43302011-11-30 06:14:42476 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00477 return base_.histograms();
478 }
[email protected]a796bcec2010-03-22 17:17:26479
[email protected]d80a4322009-08-14 07:07:49480 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20481
[email protected]974ebd62009-08-03 23:14:34482 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49483 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34484 }
485
[email protected]2c2bef152010-10-13 00:55:03486 int NumActiveSocketsInGroup(const std::string& group_name) const {
487 return base_.NumActiveSocketsInGroup(group_name);
488 }
489
[email protected]2abfe90a2010-08-25 17:49:51490 bool HasGroup(const std::string& group_name) const {
491 return base_.HasGroup(group_name);
492 }
493
[email protected]9bf28db2009-08-29 01:35:16494 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
495
[email protected]06d94042010-08-25 01:45:22496 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54497
[email protected]ab838892009-06-30 18:49:05498 private:
[email protected]d80a4322009-08-14 07:07:49499 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05500
501 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
502};
503
[email protected]a937a06d2009-08-19 21:19:24504} // namespace
505
[email protected]7fc5b09a2010-02-27 00:07:38506REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24507
508namespace {
509
[email protected]5fc08e32009-07-15 17:09:57510void MockClientSocketFactory::SignalJobs() {
511 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
512 it != waiting_jobs_.end(); ++it) {
513 (*it)->Signal();
514 }
515 waiting_jobs_.clear();
516}
517
[email protected]974ebd62009-08-03 23:14:34518class TestConnectJobDelegate : public ConnectJob::Delegate {
519 public:
520 TestConnectJobDelegate()
521 : have_result_(false), waiting_for_result_(false), result_(OK) {}
522 virtual ~TestConnectJobDelegate() {}
523
524 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
525 result_ = result;
[email protected]3268023f2011-05-05 00:08:10526 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07527 // socket.get() should be NULL iff result != OK
528 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34529 delete job;
530 have_result_ = true;
531 if (waiting_for_result_)
532 MessageLoop::current()->Quit();
533 }
534
535 int WaitForResult() {
536 DCHECK(!waiting_for_result_);
537 while (!have_result_) {
538 waiting_for_result_ = true;
539 MessageLoop::current()->Run();
540 waiting_for_result_ = false;
541 }
542 have_result_ = false; // auto-reset for next callback
543 return result_;
544 }
545
546 private:
547 bool have_result_;
548 bool waiting_for_result_;
549 int result_;
550};
551
[email protected]2431756e2010-09-29 20:26:13552class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09553 protected:
[email protected]b89f7e42010-05-20 20:37:00554 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21555 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54556 histograms_("ClientSocketPoolTest") {
557 connect_backup_jobs_enabled_ =
558 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
559 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41560 cleanup_timer_enabled_ =
561 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54562 }
[email protected]2431756e2010-09-29 20:26:13563
[email protected]636b8252011-04-08 19:56:54564 virtual ~ClientSocketPoolBaseTest() {
565 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
566 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41567 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
568 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54569 }
[email protected]c9d6a1d2009-07-14 16:15:20570
[email protected]211d21722009-07-22 15:48:53571 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16572 CreatePoolWithIdleTimeouts(
573 max_sockets,
574 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30575 ClientSocketPool::unused_idle_socket_timeout(),
576 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16577 }
578
579 void CreatePoolWithIdleTimeouts(
580 int max_sockets, int max_sockets_per_group,
581 base::TimeDelta unused_idle_socket_timeout,
582 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20583 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04584 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13585 pool_.reset(new TestClientSocketPool(max_sockets,
586 max_sockets_per_group,
587 &histograms_,
588 unused_idle_socket_timeout,
589 used_idle_socket_timeout,
590 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20591 }
[email protected]f6d1d6eb2009-06-24 20:16:09592
[email protected]ac790b42009-12-02 04:31:31593 int StartRequest(const std::string& group_name,
594 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13595 return test_base_.StartRequestUsingPool<
596 TestClientSocketPool, TestSocketParams>(
597 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09598 }
599
[email protected]2431756e2010-09-29 20:26:13600 int GetOrderOfRequest(size_t index) const {
601 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09602 }
603
[email protected]2431756e2010-09-29 20:26:13604 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
605 return test_base_.ReleaseOneConnection(keep_alive);
606 }
607
608 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
609 test_base_.ReleaseAllConnections(keep_alive);
610 }
611
612 TestSocketRequest* request(int i) { return test_base_.request(i); }
613 size_t requests_size() const { return test_base_.requests_size(); }
614 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
615 size_t completion_count() const { return test_base_.completion_count(); }
616
[email protected]636b8252011-04-08 19:56:54617 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41618 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09619 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04620 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21621 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13622 ClientSocketPoolHistograms histograms_;
623 scoped_ptr<TestClientSocketPool> pool_;
624 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09625};
626
[email protected]5e6efa52011-06-27 17:26:41627TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
628 CreatePool(4, 4);
629 net::SetSocketReusePolicy(0);
630
631 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
632 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
633 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
634 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
635
636 std::map<int, StreamSocket*> sockets_;
637 for (size_t i = 0; i < test_base_.requests_size(); i++) {
638 TestSocketRequest* req = test_base_.request(i);
639 StreamSocket* s = req->handle()->socket();
640 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
641 CHECK(sock);
642 sockets_[i] = sock;
643 sock->Read(NULL, 1024 - i, NULL);
644 }
645
646 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
647
648 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
649 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
650
651 // First socket is warmest.
652 EXPECT_EQ(sockets_[0], req->handle()->socket());
653
654 // Test that NumBytes are as expected.
655 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
656 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
657 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
658 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
659
660 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
661}
662
663TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
664 CreatePool(4, 4);
665 net::SetSocketReusePolicy(2);
666
667 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
668 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
669 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
670 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
671
672 std::map<int, StreamSocket*> sockets_;
673 for (size_t i = 0; i < test_base_.requests_size(); i++) {
674 TestSocketRequest* req = test_base_.request(i);
675 StreamSocket* s = req->handle()->socket();
676 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
677 CHECK(sock);
678 sockets_[i] = sock;
679 sock->Read(NULL, 1024 - i, NULL);
680 }
681
682 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
683
684 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
685 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
686
687 // Last socket is most recently accessed.
688 EXPECT_EQ(sockets_[3], req->handle()->socket());
689 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
690}
691
[email protected]974ebd62009-08-03 23:14:34692// Even though a timeout is specified, it doesn't time out on a synchronous
693// completion.
694TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
695 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06696 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49697 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03698 &ignored, NULL, kDefaultPriority,
699 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20700 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34701 scoped_ptr<TestConnectJob> job(
702 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12703 "a",
[email protected]974ebd62009-08-03 23:14:34704 request,
705 base::TimeDelta::FromMicroseconds(1),
706 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30707 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17708 NULL));
[email protected]974ebd62009-08-03 23:14:34709 EXPECT_EQ(OK, job->Connect());
710}
711
712TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
713 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06714 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17715 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53716
[email protected]d80a4322009-08-14 07:07:49717 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03718 &ignored, NULL, kDefaultPriority,
719 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20720 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34721 // Deleted by TestConnectJobDelegate.
722 TestConnectJob* job =
723 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12724 "a",
[email protected]974ebd62009-08-03 23:14:34725 request,
726 base::TimeDelta::FromMicroseconds(1),
727 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30728 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17729 &log);
[email protected]974ebd62009-08-03 23:14:34730 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08731 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34732 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30733
[email protected]b2fcd0e2010-12-01 15:19:40734 net::CapturingNetLog::EntryList entries;
735 log.GetEntries(&entries);
736
737 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46738 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40739 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17740 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40741 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46742 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40743 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17744 NetLog::PHASE_NONE));
745 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40746 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53747 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46748 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40749 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17750 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40751 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34752}
753
[email protected]5fc08e32009-07-15 17:09:57754TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53755 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20756
[email protected]f1f3f0f82011-10-01 20:38:10757 TestOldCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06758 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53759 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
760
[email protected]2431756e2010-09-29 20:26:13761 EXPECT_EQ(OK,
762 handle.Init("a",
763 params_,
764 kDefaultPriority,
765 &callback,
766 pool_.get(),
767 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09768 EXPECT_TRUE(handle.is_initialized());
769 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09770 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30771
[email protected]b2fcd0e2010-12-01 15:19:40772 net::CapturingNetLog::EntryList entries;
773 log.GetEntries(&entries);
774
775 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46776 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40777 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53778 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40779 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17780 NetLog::PHASE_NONE));
781 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40782 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53783 NetLog::PHASE_NONE));
784 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40785 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09786}
787
[email protected]ab838892009-06-30 18:49:05788TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53789 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20790
[email protected]ab838892009-06-30 18:49:05791 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53792 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
793
[email protected]2431756e2010-09-29 20:26:13794 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:10795 TestOldCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18796 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13797 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43798 HttpResponseInfo info;
799 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13800 handle.set_ssl_error_response_info(info);
801 EXPECT_EQ(ERR_CONNECTION_FAILED,
802 handle.Init("a",
803 params_,
804 kDefaultPriority,
805 &callback,
806 pool_.get(),
807 log.bound()));
808 EXPECT_FALSE(handle.socket());
809 EXPECT_FALSE(handle.is_ssl_error());
810 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30811
[email protected]b2fcd0e2010-12-01 15:19:40812 net::CapturingNetLog::EntryList entries;
813 log.GetEntries(&entries);
814
815 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27816 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40817 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17818 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40819 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17820 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02821 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40822 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09823}
824
[email protected]211d21722009-07-22 15:48:53825TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
826 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
827
[email protected]9e743cd2010-03-16 07:03:53828 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30829
[email protected]211d21722009-07-22 15:48:53830 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
831 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
832 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
833 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
834
[email protected]2431756e2010-09-29 20:26:13835 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53836 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13837 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53838
839 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
840 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
841 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
842
[email protected]2431756e2010-09-29 20:26:13843 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53844
[email protected]2431756e2010-09-29 20:26:13845 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53846 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13847 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53848
849 EXPECT_EQ(1, GetOrderOfRequest(1));
850 EXPECT_EQ(2, GetOrderOfRequest(2));
851 EXPECT_EQ(3, GetOrderOfRequest(3));
852 EXPECT_EQ(4, GetOrderOfRequest(4));
853 EXPECT_EQ(5, GetOrderOfRequest(5));
854 EXPECT_EQ(6, GetOrderOfRequest(6));
855 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17856
857 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13858 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53859}
860
861TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
862 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
863
[email protected]9e743cd2010-03-16 07:03:53864 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30865
[email protected]211d21722009-07-22 15:48:53866 // Reach all limits: max total sockets, and max sockets per group.
867 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
868 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
869 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
870 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
871
[email protected]2431756e2010-09-29 20:26:13872 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53873 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13874 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53875
876 // Now create a new group and verify that we don't starve it.
877 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
878
[email protected]2431756e2010-09-29 20:26:13879 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53880
[email protected]2431756e2010-09-29 20:26:13881 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53882 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13883 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53884
885 EXPECT_EQ(1, GetOrderOfRequest(1));
886 EXPECT_EQ(2, GetOrderOfRequest(2));
887 EXPECT_EQ(3, GetOrderOfRequest(3));
888 EXPECT_EQ(4, GetOrderOfRequest(4));
889 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17890
891 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13892 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53893}
894
895TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
896 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
897
[email protected]ac790b42009-12-02 04:31:31898 EXPECT_EQ(OK, StartRequest("b", LOWEST));
899 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
900 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
901 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53902
[email protected]2431756e2010-09-29 20:26:13903 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53904 client_socket_factory_.allocation_count());
905
[email protected]ac790b42009-12-02 04:31:31906 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
907 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
908 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53909
[email protected]2431756e2010-09-29 20:26:13910 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53911
[email protected]2431756e2010-09-29 20:26:13912 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53913
914 // First 4 requests don't have to wait, and finish in order.
915 EXPECT_EQ(1, GetOrderOfRequest(1));
916 EXPECT_EQ(2, GetOrderOfRequest(2));
917 EXPECT_EQ(3, GetOrderOfRequest(3));
918 EXPECT_EQ(4, GetOrderOfRequest(4));
919
[email protected]ac790b42009-12-02 04:31:31920 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
921 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53922 EXPECT_EQ(7, GetOrderOfRequest(5));
923 EXPECT_EQ(6, GetOrderOfRequest(6));
924 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17925
926 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13927 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53928}
929
930TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
931 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
932
[email protected]ac790b42009-12-02 04:31:31933 EXPECT_EQ(OK, StartRequest("a", LOWEST));
934 EXPECT_EQ(OK, StartRequest("a", LOW));
935 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
936 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53937
[email protected]2431756e2010-09-29 20:26:13938 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53939 client_socket_factory_.allocation_count());
940
[email protected]ac790b42009-12-02 04:31:31941 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
942 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
943 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53944
[email protected]2431756e2010-09-29 20:26:13945 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53946
[email protected]2431756e2010-09-29 20:26:13947 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53948 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13949 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53950
951 // First 4 requests don't have to wait, and finish in order.
952 EXPECT_EQ(1, GetOrderOfRequest(1));
953 EXPECT_EQ(2, GetOrderOfRequest(2));
954 EXPECT_EQ(3, GetOrderOfRequest(3));
955 EXPECT_EQ(4, GetOrderOfRequest(4));
956
957 // Request ("b", 7) has the highest priority, but we can't make new socket for
958 // group "b", because it has reached the per-group limit. Then we make
959 // socket for ("c", 6), because it has higher priority than ("a", 4),
960 // and we still can't make a socket for group "b".
961 EXPECT_EQ(5, GetOrderOfRequest(5));
962 EXPECT_EQ(6, GetOrderOfRequest(6));
963 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17964
965 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53967}
968
969// Make sure that we count connecting sockets against the total limit.
970TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
971 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
972
973 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
974 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
975 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
976
977 // Create one asynchronous request.
978 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
979 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
980
[email protected]6b175382009-10-13 06:47:47981 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
982 // actually become pending until 2ms after they have been created. In order
983 // to flush all tasks, we need to wait so that we know there are no
984 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08985 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47986 MessageLoop::current()->RunAllPending();
987
[email protected]211d21722009-07-22 15:48:53988 // The next synchronous request should wait for its turn.
989 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
990 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
991
[email protected]2431756e2010-09-29 20:26:13992 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53993
[email protected]2431756e2010-09-29 20:26:13994 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53995 client_socket_factory_.allocation_count());
996
997 EXPECT_EQ(1, GetOrderOfRequest(1));
998 EXPECT_EQ(2, GetOrderOfRequest(2));
999 EXPECT_EQ(3, GetOrderOfRequest(3));
1000 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171001 EXPECT_EQ(5, GetOrderOfRequest(5));
1002
1003 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131004 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531005}
1006
[email protected]6427fe22010-04-16 22:27:411007TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1008 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1009 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1010
1011 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1012 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1013 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1014 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1015
1016 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1017
1018 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1019
1020 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1021 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1022
1023 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1024
[email protected]2431756e2010-09-29 20:26:131025 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411026 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131027 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411028 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131029 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1030 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411031 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1032}
1033
[email protected]d7027bb2010-05-10 18:58:541034TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1035 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1036 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1037
1038 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101039 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131040 EXPECT_EQ(ERR_IO_PENDING,
1041 handle.Init("a",
1042 params_,
1043 kDefaultPriority,
1044 &callback,
1045 pool_.get(),
1046 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541047
1048 ClientSocketHandle handles[4];
1049 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101050 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131051 EXPECT_EQ(ERR_IO_PENDING,
1052 handles[i].Init("b",
1053 params_,
1054 kDefaultPriority,
1055 &callback,
1056 pool_.get(),
1057 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541058 }
1059
1060 // One will be stalled, cancel all the handles now.
1061 // This should hit the OnAvailableSocketSlot() code where we previously had
1062 // stalled groups, but no longer have any.
1063 for (size_t i = 0; i < arraysize(handles); ++i)
1064 handles[i].Reset();
1065}
1066
[email protected]eb5a99382010-07-11 03:18:261067TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541068 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1069 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1070
[email protected]eb5a99382010-07-11 03:18:261071 {
1072 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]f1f3f0f82011-10-01 20:38:101073 TestOldCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261074 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131075 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1076 params_,
[email protected]e83326f2010-07-31 17:29:251077 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:131078 &callbacks[i],
1079 pool_.get(),
1080 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261081 }
1082
1083 // Force a stalled group.
1084 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101085 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131086 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1087 params_,
1088 kDefaultPriority,
1089 &callback,
1090 pool_.get(),
1091 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261092
1093 // Cancel the stalled request.
1094 stalled_handle.Reset();
1095
1096 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1097 EXPECT_EQ(0, pool_->IdleSocketCount());
1098
1099 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541100 }
1101
[email protected]43a21b82010-06-10 21:30:541102 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1103 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261104}
[email protected]43a21b82010-06-10 21:30:541105
[email protected]eb5a99382010-07-11 03:18:261106TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1107 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1108 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1109
1110 {
1111 ClientSocketHandle handles[kDefaultMaxSockets];
1112 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101113 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131114 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1115 params_,
1116 kDefaultPriority,
1117 &callback,
1118 pool_.get(),
1119 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261120 }
1121
1122 // Force a stalled group.
1123 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1124 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101125 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131126 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1127 params_,
1128 kDefaultPriority,
1129 &callback,
1130 pool_.get(),
1131 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261132
1133 // Since it is stalled, it should have no connect jobs.
1134 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1135
1136 // Cancel the stalled request.
1137 handles[0].Reset();
1138
[email protected]eb5a99382010-07-11 03:18:261139 // Now we should have a connect job.
1140 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1141
1142 // The stalled socket should connect.
1143 EXPECT_EQ(OK, callback.WaitForResult());
1144
1145 EXPECT_EQ(kDefaultMaxSockets + 1,
1146 client_socket_factory_.allocation_count());
1147 EXPECT_EQ(0, pool_->IdleSocketCount());
1148 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1149
1150 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541151 }
1152
[email protected]eb5a99382010-07-11 03:18:261153 EXPECT_EQ(1, pool_->IdleSocketCount());
1154}
[email protected]43a21b82010-06-10 21:30:541155
[email protected]eb5a99382010-07-11 03:18:261156TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1157 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1158 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541159
[email protected]eb5a99382010-07-11 03:18:261160 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101161 TestOldCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261162 {
1163 ClientSocketHandle handles[kDefaultMaxSockets];
1164 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101165 TestOldCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401166 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1167 "Take 2: %d", i),
1168 params_,
1169 kDefaultPriority,
1170 &callback,
1171 pool_.get(),
1172 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261173 }
1174
1175 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1176 EXPECT_EQ(0, pool_->IdleSocketCount());
1177
1178 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131179 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1180 params_,
1181 kDefaultPriority,
1182 &callback,
1183 pool_.get(),
1184 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261185
1186 // Dropping out of scope will close all handles and return them to idle.
1187 }
[email protected]43a21b82010-06-10 21:30:541188
1189 // But if we wait for it, the released idle sockets will be closed in
1190 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101191 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261192
1193 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1194 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541195}
1196
1197// Regression test for http://crbug.com/40952.
1198TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221200 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541201 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1202
1203 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1204 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101205 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131206 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1207 params_,
1208 kDefaultPriority,
1209 &callback,
1210 pool_.get(),
1211 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541212 }
1213
1214 // Flush all the DoReleaseSocket tasks.
1215 MessageLoop::current()->RunAllPending();
1216
1217 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1218 // reuse a socket.
1219 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1220 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101221 TestOldCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541222
1223 // "0" is special here, since it should be the first entry in the sorted map,
1224 // which is the one which we would close an idle socket for. We shouldn't
1225 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131226 EXPECT_EQ(OK, handle.Init("0",
1227 params_,
1228 kDefaultPriority,
1229 &callback,
1230 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211231 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541232
1233 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1234 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1235}
1236
[email protected]ab838892009-06-30 18:49:051237TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531238 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091239
[email protected]c9d6a1d2009-07-14 16:15:201240 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1241 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031242 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311243 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1244 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1245 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1246 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1247 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091248
[email protected]2431756e2010-09-29 20:26:131249 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091250
[email protected]c9d6a1d2009-07-14 16:15:201251 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1252 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131253 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1254 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091255
[email protected]c9d6a1d2009-07-14 16:15:201256 EXPECT_EQ(1, GetOrderOfRequest(1));
1257 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031258 EXPECT_EQ(8, GetOrderOfRequest(3));
1259 EXPECT_EQ(6, GetOrderOfRequest(4));
1260 EXPECT_EQ(4, GetOrderOfRequest(5));
1261 EXPECT_EQ(3, GetOrderOfRequest(6));
1262 EXPECT_EQ(5, GetOrderOfRequest(7));
1263 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171264
1265 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131266 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091267}
1268
[email protected]ab838892009-06-30 18:49:051269TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531270 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091271
[email protected]c9d6a1d2009-07-14 16:15:201272 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1273 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311274 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1275 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1276 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1277 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1278 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091279
[email protected]2431756e2010-09-29 20:26:131280 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091281
[email protected]2431756e2010-09-29 20:26:131282 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1283 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201284
[email protected]2431756e2010-09-29 20:26:131285 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201286 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131287 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1288 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091289}
1290
1291// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051292// The pending connect job will be cancelled and should not call back into
1293// ClientSocketPoolBase.
1294TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201296
[email protected]ab838892009-06-30 18:49:051297 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131298 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101299 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131300 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1301 params_,
1302 kDefaultPriority,
1303 &callback,
1304 pool_.get(),
1305 BoundNetLog()));
1306 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091307}
1308
[email protected]ab838892009-06-30 18:49:051309TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531310 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201311
[email protected]ab838892009-06-30 18:49:051312 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061313 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101314 TestOldCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091315
[email protected]2431756e2010-09-29 20:26:131316 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1317 params_,
1318 kDefaultPriority,
1319 &callback,
1320 pool_.get(),
1321 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091322
1323 handle.Reset();
1324
[email protected]f1f3f0f82011-10-01 20:38:101325 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131326 EXPECT_EQ(ERR_IO_PENDING,
1327 handle.Init("a",
1328 params_,
1329 kDefaultPriority,
1330 &callback2,
1331 pool_.get(),
1332 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091333
1334 EXPECT_EQ(OK, callback2.WaitForResult());
1335 EXPECT_FALSE(callback.have_result());
1336
1337 handle.Reset();
1338}
1339
[email protected]ab838892009-06-30 18:49:051340TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531341 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091342
[email protected]c9d6a1d2009-07-14 16:15:201343 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1344 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311345 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1346 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1347 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1348 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1349 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091350
1351 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201352 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131353 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1354 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091355
[email protected]2431756e2010-09-29 20:26:131356 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091357
[email protected]c9d6a1d2009-07-14 16:15:201358 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1359 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131360 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1361 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091362
[email protected]c9d6a1d2009-07-14 16:15:201363 EXPECT_EQ(1, GetOrderOfRequest(1));
1364 EXPECT_EQ(2, GetOrderOfRequest(2));
1365 EXPECT_EQ(5, GetOrderOfRequest(3));
1366 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131367 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1368 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201369 EXPECT_EQ(4, GetOrderOfRequest(6));
1370 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171371
1372 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131373 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091374}
1375
1376class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1377 public:
[email protected]2ab05b52009-07-01 23:57:581378 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241379 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581380 TestConnectJobFactory* test_connect_job_factory,
1381 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091382 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061383 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581384 within_callback_(false),
1385 test_connect_job_factory_(test_connect_job_factory),
1386 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091387
1388 virtual void RunWithParams(const Tuple1<int>& params) {
1389 callback_.RunWithParams(params);
1390 ASSERT_EQ(OK, params.a);
1391
1392 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581393 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111394
1395 // Don't allow reuse of the socket. Disconnect it and then release it and
1396 // run through the MessageLoop once to get it completely released.
1397 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091398 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111399 {
1400 MessageLoop::ScopedNestableTaskAllower nestable(
1401 MessageLoop::current());
1402 MessageLoop::current()->RunAllPending();
1403 }
[email protected]f6d1d6eb2009-06-24 20:16:091404 within_callback_ = true;
[email protected]f1f3f0f82011-10-01 20:38:101405 TestOldCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271406 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131407 int rv = handle_->Init("a",
1408 params,
1409 kDefaultPriority,
1410 &next_job_callback,
1411 pool_,
1412 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581413 switch (next_job_type_) {
1414 case TestConnectJob::kMockJob:
1415 EXPECT_EQ(OK, rv);
1416 break;
1417 case TestConnectJob::kMockPendingJob:
1418 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471419
1420 // For pending jobs, wait for new socket to be created. This makes
1421 // sure there are no more pending operations nor any unclosed sockets
1422 // when the test finishes.
1423 // We need to give it a little bit of time to run, so that all the
1424 // operations that happen on timers (e.g. cleanup of idle
1425 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111426 {
1427 MessageLoop::ScopedNestableTaskAllower nestable(
1428 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081429 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111430 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1431 }
[email protected]2ab05b52009-07-01 23:57:581432 break;
1433 default:
1434 FAIL() << "Unexpected job type: " << next_job_type_;
1435 break;
1436 }
[email protected]f6d1d6eb2009-06-24 20:16:091437 }
1438 }
1439
1440 int WaitForResult() {
1441 return callback_.WaitForResult();
1442 }
1443
1444 private:
1445 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131446 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091447 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581448 TestConnectJobFactory* const test_connect_job_factory_;
1449 TestConnectJob::JobType next_job_type_;
[email protected]f1f3f0f82011-10-01 20:38:101450 TestOldCompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091451};
1452
[email protected]2ab05b52009-07-01 23:57:581453TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531454 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201455
[email protected]0b7648c2009-07-06 20:14:011456 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061457 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581458 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061459 &handle, pool_.get(), connect_job_factory_,
1460 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131461 int rv = handle.Init("a",
1462 params_,
1463 kDefaultPriority,
1464 &callback,
1465 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211466 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091467 ASSERT_EQ(ERR_IO_PENDING, rv);
1468
1469 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581470}
[email protected]f6d1d6eb2009-06-24 20:16:091471
[email protected]2ab05b52009-07-01 23:57:581472TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531473 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201474
[email protected]0b7648c2009-07-06 20:14:011475 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061476 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581477 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061478 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131479 int rv = handle.Init("a",
1480 params_,
1481 kDefaultPriority,
1482 &callback,
1483 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211484 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581485 ASSERT_EQ(ERR_IO_PENDING, rv);
1486
1487 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091488}
1489
1490// Make sure that pending requests get serviced after active requests get
1491// cancelled.
[email protected]ab838892009-06-30 18:49:051492TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[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]f6d1d6eb2009-06-24 20:16:091496
[email protected]c9d6a1d2009-07-14 16:15:201497 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1498 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1499 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1500 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1501 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1502 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1503 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091504
[email protected]c9d6a1d2009-07-14 16:15:201505 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1506 // Let's cancel them.
1507 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131508 ASSERT_FALSE(request(i)->handle()->is_initialized());
1509 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091510 }
1511
[email protected]f6d1d6eb2009-06-24 20:16:091512 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131513 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1514 EXPECT_EQ(OK, request(i)->WaitForResult());
1515 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091516 }
1517
[email protected]2431756e2010-09-29 20:26:131518 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1519 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091520}
1521
1522// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051523TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531524 const size_t kMaxSockets = 5;
1525 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201526
[email protected]0b7648c2009-07-06 20:14:011527 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091528
[email protected]211d21722009-07-22 15:48:531529 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1530 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091531
1532 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531533 for (size_t i = 0; i < kNumberOfRequests; ++i)
1534 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091535
[email protected]211d21722009-07-22 15:48:531536 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131537 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091538}
1539
[email protected]5fc08e32009-07-15 17:09:571540TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531541 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571542
1543 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1544
[email protected]2431756e2010-09-29 20:26:131545 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101546 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131547 int rv = handle.Init("a",
1548 params_,
1549 kDefaultPriority,
1550 &callback,
1551 pool_.get(),
1552 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571553 EXPECT_EQ(ERR_IO_PENDING, rv);
1554
1555 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131556 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571557
[email protected]2431756e2010-09-29 20:26:131558 rv = handle.Init("a",
1559 params_,
1560 kDefaultPriority,
1561 &callback,
1562 pool_.get(),
1563 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571564 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131565 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571566
[email protected]2431756e2010-09-29 20:26:131567 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571568 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1569}
1570
[email protected]2b7523d2009-07-29 20:29:231571// Regression test for http://crbug.com/17985.
1572TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1573 const int kMaxSockets = 3;
1574 const int kMaxSocketsPerGroup = 2;
1575 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1576
[email protected]ac790b42009-12-02 04:31:311577 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231578
1579 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1580 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1581
1582 // This is going to be a pending request in an otherwise empty group.
1583 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1584
1585 // Reach the maximum socket limit.
1586 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1587
1588 // Create a stalled group with high priorities.
1589 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1590 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231591
[email protected]eb5a99382010-07-11 03:18:261592 // Release the first two sockets from "a". Because this is a keepalive,
1593 // the first release will unblock the pending request for "a". The
1594 // second release will unblock a request for "c", becaue it is the next
1595 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131596 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1597 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231598
1599 // Closing idle sockets should not get us into trouble, but in the bug
1600 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411601 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541602 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261603
1604 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231605}
1606
[email protected]4d3b05d2010-01-27 21:27:291607TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531608 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571609
1610 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131611 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101612 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531613 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131614 int rv = handle.Init("a",
1615 params_,
1616 LOWEST,
1617 &callback,
1618 pool_.get(),
1619 log.bound());
[email protected]5fc08e32009-07-15 17:09:571620 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131621 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1622 EXPECT_EQ(OK, callback.WaitForResult());
1623 EXPECT_TRUE(handle.is_initialized());
1624 EXPECT_TRUE(handle.socket());
1625 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301626
[email protected]b2fcd0e2010-12-01 15:19:401627 net::CapturingNetLog::EntryList entries;
1628 log.GetEntries(&entries);
1629
1630 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461631 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401632 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171633 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401634 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171635 NetLog::PHASE_NONE));
1636 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401637 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171638 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461639 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401640 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571641}
1642
[email protected]4d3b05d2010-01-27 21:27:291643TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571644 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531645 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571646
1647 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131648 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101649 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531650 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181651 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131652 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431653 HttpResponseInfo info;
1654 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131655 handle.set_ssl_error_response_info(info);
1656 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1657 params_,
1658 kDefaultPriority,
1659 &callback,
1660 pool_.get(),
1661 log.bound()));
1662 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1663 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1664 EXPECT_FALSE(handle.is_ssl_error());
1665 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301666
[email protected]b2fcd0e2010-12-01 15:19:401667 net::CapturingNetLog::EntryList entries;
1668 log.GetEntries(&entries);
1669
1670 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461671 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401672 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171673 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401674 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171675 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321676 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401677 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571678}
1679
[email protected]4d3b05d2010-01-27 21:27:291680TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101681 // TODO(eroman): Add back the log expectations! Removed them because the
1682 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531683 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571684
1685 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131686 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101687 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131688 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101689 TestOldCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571690
[email protected]2431756e2010-09-29 20:26:131691 EXPECT_EQ(ERR_IO_PENDING,
1692 handle.Init("a",
1693 params_,
1694 kDefaultPriority,
1695 &callback,
1696 pool_.get(),
1697 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531698 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131699 EXPECT_EQ(ERR_IO_PENDING,
1700 handle2.Init("a",
1701 params_,
1702 kDefaultPriority,
1703 &callback2,
1704 pool_.get(),
1705 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571706
[email protected]2431756e2010-09-29 20:26:131707 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571708
[email protected]fd7b7c92009-08-20 19:38:301709
1710 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301711
[email protected]2431756e2010-09-29 20:26:131712 EXPECT_EQ(OK, callback2.WaitForResult());
1713 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301714
1715 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531716 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571717}
1718
[email protected]4d3b05d2010-01-27 21:27:291719TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341720 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1721
[email protected]17a0c6c2009-08-04 00:07:041722 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1723
[email protected]ac790b42009-12-02 04:31:311724 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1725 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1726 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1727 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341728
1729 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131730 (*requests())[2]->handle()->Reset();
1731 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341732 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1733
[email protected]2431756e2010-09-29 20:26:131734 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341735 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1736
[email protected]2431756e2010-09-29 20:26:131737 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261738 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341739}
1740
[email protected]5fc08e32009-07-15 17:09:571741// When requests and ConnectJobs are not coupled, the request will get serviced
1742// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291743TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571745
1746 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321747 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571748
[email protected]2431756e2010-09-29 20:26:131749 std::vector<TestSocketRequest*> request_order;
1750 size_t completion_count; // unused
1751 TestSocketRequest req1(&request_order, &completion_count);
1752 int rv = req1.handle()->Init("a",
1753 params_,
1754 kDefaultPriority,
1755 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211756 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571757 EXPECT_EQ(ERR_IO_PENDING, rv);
1758 EXPECT_EQ(OK, req1.WaitForResult());
1759
1760 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1761 // without a job.
1762 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1763
[email protected]2431756e2010-09-29 20:26:131764 TestSocketRequest req2(&request_order, &completion_count);
1765 rv = req2.handle()->Init("a",
1766 params_,
1767 kDefaultPriority,
1768 &req2,
1769 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211770 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571771 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131772 TestSocketRequest req3(&request_order, &completion_count);
1773 rv = req3.handle()->Init("a",
1774 params_,
1775 kDefaultPriority,
1776 &req3,
1777 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211778 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571779 EXPECT_EQ(ERR_IO_PENDING, rv);
1780
1781 // Both Requests 2 and 3 are pending. We release socket 1 which should
1782 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331783 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261784 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331785 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571786 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331787 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571788
1789 // Signal job 2, which should service request 3.
1790
1791 client_socket_factory_.SignalJobs();
1792 EXPECT_EQ(OK, req3.WaitForResult());
1793
[email protected]2431756e2010-09-29 20:26:131794 ASSERT_EQ(3U, request_order.size());
1795 EXPECT_EQ(&req1, request_order[0]);
1796 EXPECT_EQ(&req2, request_order[1]);
1797 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571798 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1799}
1800
1801// The requests are not coupled to the jobs. So, the requests should finish in
1802// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291803TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571805 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321806 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571807
[email protected]2431756e2010-09-29 20:26:131808 std::vector<TestSocketRequest*> request_order;
1809 size_t completion_count; // unused
1810 TestSocketRequest req1(&request_order, &completion_count);
1811 int rv = req1.handle()->Init("a",
1812 params_,
1813 kDefaultPriority,
1814 &req1,
1815 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211816 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571817 EXPECT_EQ(ERR_IO_PENDING, rv);
1818
[email protected]2431756e2010-09-29 20:26:131819 TestSocketRequest req2(&request_order, &completion_count);
1820 rv = req2.handle()->Init("a",
1821 params_,
1822 kDefaultPriority,
1823 &req2,
1824 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211825 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571826 EXPECT_EQ(ERR_IO_PENDING, rv);
1827
1828 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321829 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571830
[email protected]2431756e2010-09-29 20:26:131831 TestSocketRequest req3(&request_order, &completion_count);
1832 rv = req3.handle()->Init("a",
1833 params_,
1834 kDefaultPriority,
1835 &req3,
1836 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211837 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571838 EXPECT_EQ(ERR_IO_PENDING, rv);
1839
1840 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1841 EXPECT_EQ(OK, req2.WaitForResult());
1842 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1843
[email protected]2431756e2010-09-29 20:26:131844 ASSERT_EQ(3U, request_order.size());
1845 EXPECT_EQ(&req1, request_order[0]);
1846 EXPECT_EQ(&req2, request_order[1]);
1847 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571848}
1849
[email protected]e6ec67b2010-06-16 00:12:461850TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531851 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571852 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321853 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571854
[email protected]2431756e2010-09-29 20:26:131855 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101856 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131857 int rv = handle.Init("a",
1858 params_,
1859 kDefaultPriority,
1860 &callback,
1861 pool_.get(),
1862 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571863 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131864 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571865
1866 MessageLoop::current()->RunAllPending();
1867
[email protected]2431756e2010-09-29 20:26:131868 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101869 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131870 rv = handle2.Init("a",
1871 params_,
1872 kDefaultPriority,
1873 &callback2, pool_.get(),
1874 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131876 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1877 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571878}
1879
[email protected]e772db3f2010-07-12 18:11:131880TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1881 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1882 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1883
[email protected]2431756e2010-09-29 20:26:131884 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101885 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131886 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1887 params_,
1888 kDefaultPriority,
1889 &callback, pool_.get(),
1890 BoundNetLog()));
1891 EXPECT_TRUE(handle.is_initialized());
1892 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131893}
1894
1895TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1896 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1897
1898 connect_job_factory_->set_job_type(
1899 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131900 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101901 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131902 EXPECT_EQ(ERR_IO_PENDING,
1903 handle.Init("a",
1904 params_,
1905 kDefaultPriority,
1906 &callback,
1907 pool_.get(),
1908 BoundNetLog()));
1909 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1910 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1911 EXPECT_TRUE(handle.is_initialized());
1912 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131913}
1914
[email protected]e60e47a2010-07-14 03:37:181915TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1916 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1917 connect_job_factory_->set_job_type(
1918 TestConnectJob::kMockAdditionalErrorStateJob);
1919
[email protected]2431756e2010-09-29 20:26:131920 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101921 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131922 EXPECT_EQ(ERR_CONNECTION_FAILED,
1923 handle.Init("a",
1924 params_,
1925 kDefaultPriority,
1926 &callback,
1927 pool_.get(),
1928 BoundNetLog()));
1929 EXPECT_FALSE(handle.is_initialized());
1930 EXPECT_FALSE(handle.socket());
1931 EXPECT_TRUE(handle.is_ssl_error());
1932 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181933}
1934
1935TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1936 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1937
1938 connect_job_factory_->set_job_type(
1939 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131940 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101941 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131942 EXPECT_EQ(ERR_IO_PENDING,
1943 handle.Init("a",
1944 params_,
1945 kDefaultPriority,
1946 &callback,
1947 pool_.get(),
1948 BoundNetLog()));
1949 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1950 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1951 EXPECT_FALSE(handle.is_initialized());
1952 EXPECT_FALSE(handle.socket());
1953 EXPECT_TRUE(handle.is_ssl_error());
1954 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181955}
1956
[email protected]64770b7d2011-11-16 04:30:411957TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1958 // Disable cleanup timer.
1959 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1960
1961 CreatePoolWithIdleTimeouts(
1962 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1963 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
1964 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
1965
1966 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1967
1968 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1969
1970 ClientSocketHandle handle;
1971 TestOldCompletionCallback callback;
1972 int rv = handle.Init("a",
1973 params_,
1974 LOWEST,
1975 &callback,
1976 pool_.get(),
1977 BoundNetLog());
1978 EXPECT_EQ(ERR_IO_PENDING, rv);
1979 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1980
1981 ClientSocketHandle handle2;
1982 TestOldCompletionCallback callback2;
1983 rv = handle2.Init("a",
1984 params_,
1985 LOWEST,
1986 &callback2,
1987 pool_.get(),
1988 BoundNetLog());
1989 EXPECT_EQ(ERR_IO_PENDING, rv);
1990 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1991
1992 // Cancel one of the requests. Wait for the other, which will get the first
1993 // job. Release the socket. Run the loop again to make sure the second
1994 // socket is sitting idle and the first one is released (since ReleaseSocket()
1995 // just posts a DoReleaseSocket() task).
1996
1997 handle.Reset();
1998 EXPECT_EQ(OK, callback2.WaitForResult());
1999 // Use the socket.
2000 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
2001 handle2.Reset();
2002
2003 // The idle socket timeout value was set to 10 milliseconds. Wait 20
2004 // milliseconds so the sockets timeout.
[email protected]83e43302011-11-30 06:14:422005 base::PlatformThread::Sleep(20);
[email protected]64770b7d2011-11-16 04:30:412006 MessageLoop::current()->RunAllPending();
2007
2008 ASSERT_EQ(2, pool_->IdleSocketCount());
2009
2010 // Request a new socket. This should cleanup the unused and timed out ones.
2011 // A new socket will be created rather than reusing the idle one.
2012 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2013 rv = handle.Init("a",
2014 params_,
2015 LOWEST,
2016 &callback,
2017 pool_.get(),
2018 log.bound());
2019 EXPECT_EQ(ERR_IO_PENDING, rv);
2020 EXPECT_EQ(OK, callback.WaitForResult());
2021 EXPECT_FALSE(handle.is_reused());
2022
2023 // Make sure the idle socket is closed
2024 ASSERT_TRUE(pool_->HasGroup("a"));
2025 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2026 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2027
2028 net::CapturingNetLog::EntryList entries;
2029 log.GetEntries(&entries);
2030 EXPECT_FALSE(LogContainsEntryWithType(
2031 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2032}
2033
[email protected]4d3b05d2010-01-27 21:27:292034TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162035 CreatePoolWithIdleTimeouts(
2036 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2037 base::TimeDelta(), // Time out unused sockets immediately.
2038 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2039
2040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2041
2042 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2043
[email protected]2431756e2010-09-29 20:26:132044 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102045 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132046 int rv = handle.Init("a",
2047 params_,
2048 LOWEST,
2049 &callback,
2050 pool_.get(),
2051 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162052 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132053 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162054
[email protected]2431756e2010-09-29 20:26:132055 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102056 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132057 rv = handle2.Init("a",
2058 params_,
2059 LOWEST,
2060 &callback2,
2061 pool_.get(),
2062 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162063 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132064 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162065
2066 // Cancel one of the requests. Wait for the other, which will get the first
2067 // job. Release the socket. Run the loop again to make sure the second
2068 // socket is sitting idle and the first one is released (since ReleaseSocket()
2069 // just posts a DoReleaseSocket() task).
2070
[email protected]2431756e2010-09-29 20:26:132071 handle.Reset();
2072 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012073 // Use the socket.
[email protected]2431756e2010-09-29 20:26:132074 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
2075 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472076
2077 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2078 // actually become pending until 2ms after they have been created. In order
2079 // to flush all tasks, we need to wait so that we know there are no
2080 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:082081 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:162082 MessageLoop::current()->RunAllPending();
2083
2084 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042085
[email protected]9bf28db2009-08-29 01:35:162086 // Invoke the idle socket cleanup check. Only one socket should be left, the
2087 // used socket. Request it to make sure that it's used.
2088
2089 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532090 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132091 rv = handle.Init("a",
2092 params_,
2093 LOWEST,
2094 &callback,
2095 pool_.get(),
2096 log.bound());
[email protected]9bf28db2009-08-29 01:35:162097 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132098 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402099
2100 net::CapturingNetLog::EntryList entries;
2101 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152102 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402103 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162104}
2105
[email protected]2041cf342010-02-19 03:15:592106// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162107// because of multiple releasing disconnected sockets.
2108TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2109 CreatePoolWithIdleTimeouts(
2110 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2111 base::TimeDelta(), // Time out unused sockets immediately.
2112 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2113
2114 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2115
2116 // Startup 4 connect jobs. Two of them will be pending.
2117
[email protected]2431756e2010-09-29 20:26:132118 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102119 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132120 int rv = handle.Init("a",
2121 params_,
2122 LOWEST,
2123 &callback,
2124 pool_.get(),
2125 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162126 EXPECT_EQ(OK, rv);
2127
[email protected]2431756e2010-09-29 20:26:132128 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102129 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132130 rv = handle2.Init("a",
2131 params_,
2132 LOWEST,
2133 &callback2,
2134 pool_.get(),
2135 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162136 EXPECT_EQ(OK, rv);
2137
[email protected]2431756e2010-09-29 20:26:132138 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102139 TestOldCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132140 rv = handle3.Init("a",
2141 params_,
2142 LOWEST,
2143 &callback3,
2144 pool_.get(),
2145 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162146 EXPECT_EQ(ERR_IO_PENDING, rv);
2147
[email protected]2431756e2010-09-29 20:26:132148 ClientSocketHandle handle4;
[email protected]f1f3f0f82011-10-01 20:38:102149 TestOldCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132150 rv = handle4.Init("a",
2151 params_,
2152 LOWEST,
2153 &callback4,
2154 pool_.get(),
2155 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162156 EXPECT_EQ(ERR_IO_PENDING, rv);
2157
2158 // Release two disconnected sockets.
2159
[email protected]2431756e2010-09-29 20:26:132160 handle.socket()->Disconnect();
2161 handle.Reset();
2162 handle2.socket()->Disconnect();
2163 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162164
[email protected]2431756e2010-09-29 20:26:132165 EXPECT_EQ(OK, callback3.WaitForResult());
2166 EXPECT_FALSE(handle3.is_reused());
2167 EXPECT_EQ(OK, callback4.WaitForResult());
2168 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162169}
2170
[email protected]d7027bb2010-05-10 18:58:542171// Regression test for http://crbug.com/42267.
2172// When DoReleaseSocket() is processed for one socket, it is blocked because the
2173// other stalled groups all have releasing sockets, so no progress can be made.
2174TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2175 CreatePoolWithIdleTimeouts(
2176 4 /* socket limit */, 4 /* socket limit per group */,
2177 base::TimeDelta(), // Time out unused sockets immediately.
2178 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2179
2180 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2181
2182 // Max out the socket limit with 2 per group.
2183
[email protected]2431756e2010-09-29 20:26:132184 ClientSocketHandle handle_a[4];
[email protected]f1f3f0f82011-10-01 20:38:102185 TestOldCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132186 ClientSocketHandle handle_b[4];
[email protected]f1f3f0f82011-10-01 20:38:102187 TestOldCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542188
2189 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132190 EXPECT_EQ(OK, handle_a[i].Init("a",
2191 params_,
2192 LOWEST,
2193 &callback_a[i],
2194 pool_.get(),
2195 BoundNetLog()));
2196 EXPECT_EQ(OK, handle_b[i].Init("b",
2197 params_,
2198 LOWEST,
2199 &callback_b[i],
2200 pool_.get(),
2201 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542202 }
[email protected]b89f7e42010-05-20 20:37:002203
[email protected]d7027bb2010-05-10 18:58:542204 // Make 4 pending requests, 2 per group.
2205
2206 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132207 EXPECT_EQ(ERR_IO_PENDING,
2208 handle_a[i].Init("a",
2209 params_,
2210 LOWEST,
2211 &callback_a[i],
2212 pool_.get(),
2213 BoundNetLog()));
2214 EXPECT_EQ(ERR_IO_PENDING,
2215 handle_b[i].Init("b",
2216 params_,
2217 LOWEST,
2218 &callback_b[i],
2219 pool_.get(),
2220 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542221 }
2222
2223 // Release b's socket first. The order is important, because in
2224 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2225 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2226 // first, which has a releasing socket, so it refuses to start up another
2227 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132228 handle_b[0].socket()->Disconnect();
2229 handle_b[0].Reset();
2230 handle_a[0].socket()->Disconnect();
2231 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542232
2233 // Used to get stuck here.
2234 MessageLoop::current()->RunAllPending();
2235
[email protected]2431756e2010-09-29 20:26:132236 handle_b[1].socket()->Disconnect();
2237 handle_b[1].Reset();
2238 handle_a[1].socket()->Disconnect();
2239 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542240
2241 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132242 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2243 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542244 }
2245}
2246
[email protected]fd4fe0b2010-02-08 23:02:152247TEST_F(ClientSocketPoolBaseTest,
2248 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2249 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2250
2251 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2252
2253 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2254 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2255 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2256 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2257
[email protected]2431756e2010-09-29 20:26:132258 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2259 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2260 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152261
2262 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132263 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2264 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152265
[email protected]2431756e2010-09-29 20:26:132266 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2267 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2268 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152269
2270 EXPECT_EQ(1, GetOrderOfRequest(1));
2271 EXPECT_EQ(2, GetOrderOfRequest(2));
2272 EXPECT_EQ(3, GetOrderOfRequest(3));
2273 EXPECT_EQ(4, GetOrderOfRequest(4));
2274
2275 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132276 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152277}
2278
[email protected]4f1e4982010-03-02 18:31:042279class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2280 public:
[email protected]2431756e2010-09-29 20:26:132281 TestReleasingSocketRequest(TestClientSocketPool* pool,
2282 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182283 bool reset_releasing_handle)
2284 : pool_(pool),
2285 expected_result_(expected_result),
2286 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042287
2288 ClientSocketHandle* handle() { return &handle_; }
2289
2290 int WaitForResult() {
2291 return callback_.WaitForResult();
2292 }
2293
2294 virtual void RunWithParams(const Tuple1<int>& params) {
2295 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182296 if (reset_releasing_handle_)
2297 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272298 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132299 EXPECT_EQ(expected_result_, handle2_.Init("a",
2300 con_params,
2301 kDefaultPriority,
2302 &callback2_,
2303 pool_,
[email protected]e60e47a2010-07-14 03:37:182304 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042305 }
2306
2307 private:
[email protected]2431756e2010-09-29 20:26:132308 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182309 int expected_result_;
2310 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042311 ClientSocketHandle handle_;
2312 ClientSocketHandle handle2_;
[email protected]f1f3f0f82011-10-01 20:38:102313 TestOldCompletionCallback callback_;
2314 TestOldCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042315};
2316
[email protected]e60e47a2010-07-14 03:37:182317
2318TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2319 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2320
2321 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2322 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2323 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2324
[email protected]2431756e2010-09-29 20:26:132325 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182326 client_socket_factory_.allocation_count());
2327
2328 connect_job_factory_->set_job_type(
2329 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2330 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132331 EXPECT_EQ(ERR_IO_PENDING,
2332 req.handle()->Init("a",
2333 params_,
2334 kDefaultPriority,
2335 &req,
2336 pool_.get(),
2337 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182338 // The next job should complete synchronously
2339 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2340
2341 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2342 EXPECT_FALSE(req.handle()->is_initialized());
2343 EXPECT_FALSE(req.handle()->socket());
2344 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432345 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182346}
2347
[email protected]b6501d3d2010-06-03 23:53:342348// http://crbug.com/44724 regression test.
2349// We start releasing the pool when we flush on network change. When that
2350// happens, the only active references are in the ClientSocketHandles. When a
2351// ConnectJob completes and calls back into the last ClientSocketHandle, that
2352// callback can release the last reference and delete the pool. After the
2353// callback finishes, we go back to the stack frame within the now-deleted pool.
2354// Executing any code that refers to members of the now-deleted pool can cause
2355// crashes.
2356TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2357 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2358 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2359
2360 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102361 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132362 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2363 params_,
2364 kDefaultPriority,
2365 &callback,
2366 pool_.get(),
2367 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342368
[email protected]2431756e2010-09-29 20:26:132369 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342370
2371 // We'll call back into this now.
2372 callback.WaitForResult();
2373}
2374
[email protected]a7e38572010-06-07 18:22:242375TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2376 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2377 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2378
2379 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102380 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132381 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2382 params_,
2383 kDefaultPriority,
2384 &callback,
2385 pool_.get(),
2386 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242387 EXPECT_EQ(OK, callback.WaitForResult());
2388 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2389
2390 pool_->Flush();
2391
2392 handle.Reset();
2393 MessageLoop::current()->RunAllPending();
2394
[email protected]2431756e2010-09-29 20:26:132395 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2396 params_,
2397 kDefaultPriority,
2398 &callback,
2399 pool_.get(),
2400 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242401 EXPECT_EQ(OK, callback.WaitForResult());
2402 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2403}
2404
[email protected]06f92462010-08-31 19:24:142405class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2406 public:
2407 ConnectWithinCallback(
2408 const std::string& group_name,
2409 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132410 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142411 : group_name_(group_name), params_(params), pool_(pool) {}
2412
2413 ~ConnectWithinCallback() {}
2414
2415 virtual void RunWithParams(const Tuple1<int>& params) {
2416 callback_.RunWithParams(params);
2417 EXPECT_EQ(ERR_IO_PENDING,
2418 handle_.Init(group_name_,
2419 params_,
2420 kDefaultPriority,
2421 &nested_callback_,
2422 pool_,
2423 BoundNetLog()));
2424 }
2425
2426 int WaitForResult() {
2427 return callback_.WaitForResult();
2428 }
2429
2430 int WaitForNestedResult() {
2431 return nested_callback_.WaitForResult();
2432 }
2433
2434 private:
2435 const std::string group_name_;
2436 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132437 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142438 ClientSocketHandle handle_;
[email protected]f1f3f0f82011-10-01 20:38:102439 TestOldCompletionCallback callback_;
2440 TestOldCompletionCallback nested_callback_;
[email protected]06f92462010-08-31 19:24:142441};
2442
2443TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2444 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2445
2446 // First job will be waiting until it gets aborted.
2447 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2448
2449 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132450 ConnectWithinCallback callback("a", params_, pool_.get());
2451 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2452 params_,
2453 kDefaultPriority,
2454 &callback,
2455 pool_.get(),
2456 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142457
2458 // Second job will be started during the first callback, and will
2459 // asynchronously complete with OK.
2460 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2461 pool_->Flush();
2462 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2463 EXPECT_EQ(OK, callback.WaitForNestedResult());
2464}
2465
[email protected]25eea382010-07-10 23:55:262466// Cancel a pending socket request while we're at max sockets,
2467// and verify that the backup socket firing doesn't cause a crash.
2468TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2469 // Max 4 sockets globally, max 4 sockets per group.
2470 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222471 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262472
[email protected]4baaf9d2010-08-31 15:15:442473 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2474 // timer.
[email protected]25eea382010-07-10 23:55:262475 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2476 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102477 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132478 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2479 params_,
2480 kDefaultPriority,
2481 &callback,
2482 pool_.get(),
2483 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262484
2485 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2486 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2487 ClientSocketHandle handles[kDefaultMaxSockets];
2488 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:102489 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132490 EXPECT_EQ(OK, handles[i].Init("bar",
2491 params_,
2492 kDefaultPriority,
2493 &callback,
2494 pool_.get(),
2495 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262496 }
2497
2498 MessageLoop::current()->RunAllPending();
2499
2500 // Cancel the pending request.
2501 handle.Reset();
2502
2503 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082504 base::PlatformThread::Sleep(
2505 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262506
2507 MessageLoop::current()->RunAllPending();
2508 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2509}
2510
[email protected]3f00be82010-09-27 19:50:022511TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442512 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2513 pool_->EnableConnectBackupJobs();
2514
2515 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2516 // timer.
2517 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2518 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102519 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132520 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2521 params_,
2522 kDefaultPriority,
2523 &callback,
2524 pool_.get(),
2525 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442526 ASSERT_TRUE(pool_->HasGroup("bar"));
2527 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2528
2529 // Cancel the socket request. This should cancel the backup timer. Wait for
2530 // the backup time to see if it indeed got canceled.
2531 handle.Reset();
2532 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082533 base::PlatformThread::Sleep(
2534 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442535 MessageLoop::current()->RunAllPending();
2536 ASSERT_TRUE(pool_->HasGroup("bar"));
2537 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2538}
2539
[email protected]3f00be82010-09-27 19:50:022540TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2541 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2542 pool_->EnableConnectBackupJobs();
2543
2544 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2545 // timer.
2546 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2547 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102548 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132549 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2550 params_,
2551 kDefaultPriority,
2552 &callback,
2553 pool_.get(),
2554 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2556 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102557 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132558 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2559 params_,
2560 kDefaultPriority,
2561 &callback2,
2562 pool_.get(),
2563 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022564 ASSERT_TRUE(pool_->HasGroup("bar"));
2565 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2566
2567 // Cancel request 1 and then complete request 2. With the requests finished,
2568 // the backup timer should be cancelled.
2569 handle.Reset();
2570 EXPECT_EQ(OK, callback2.WaitForResult());
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]3f00be82010-09-27 19:50:022574 MessageLoop::current()->RunAllPending();
2575}
2576
[email protected]eb5a99382010-07-11 03:18:262577// Test delayed socket binding for the case where we have two connects,
2578// and while one is waiting on a connect, the other frees up.
2579// The socket waiting on a connect should switch immediately to the freed
2580// up socket.
2581TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2582 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2583 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2584
2585 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102586 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132587 EXPECT_EQ(ERR_IO_PENDING,
2588 handle1.Init("a",
2589 params_,
2590 kDefaultPriority,
2591 &callback,
2592 pool_.get(),
2593 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262594 EXPECT_EQ(OK, callback.WaitForResult());
2595
2596 // No idle sockets, no pending jobs.
2597 EXPECT_EQ(0, pool_->IdleSocketCount());
2598 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2599
2600 // Create a second socket to the same host, but this one will wait.
2601 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2602 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132603 EXPECT_EQ(ERR_IO_PENDING,
2604 handle2.Init("a",
2605 params_,
2606 kDefaultPriority,
2607 &callback,
2608 pool_.get(),
2609 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262610 // No idle sockets, and one connecting job.
2611 EXPECT_EQ(0, pool_->IdleSocketCount());
2612 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2613
2614 // Return the first handle to the pool. This will initiate the delayed
2615 // binding.
2616 handle1.Reset();
2617
2618 MessageLoop::current()->RunAllPending();
2619
2620 // Still no idle sockets, still one pending connect job.
2621 EXPECT_EQ(0, pool_->IdleSocketCount());
2622 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2623
2624 // The second socket connected, even though it was a Waiting Job.
2625 EXPECT_EQ(OK, callback.WaitForResult());
2626
2627 // And we can see there is still one job waiting.
2628 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2629
2630 // Finally, signal the waiting Connect.
2631 client_socket_factory_.SignalJobs();
2632 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2633
2634 MessageLoop::current()->RunAllPending();
2635}
2636
2637// Test delayed socket binding when a group is at capacity and one
2638// of the group's sockets frees up.
2639TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2640 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2641 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2642
2643 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102644 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132645 EXPECT_EQ(ERR_IO_PENDING,
2646 handle1.Init("a",
2647 params_,
2648 kDefaultPriority,
2649 &callback,
2650 pool_.get(),
2651 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262652 EXPECT_EQ(OK, callback.WaitForResult());
2653
2654 // No idle sockets, no pending jobs.
2655 EXPECT_EQ(0, pool_->IdleSocketCount());
2656 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2657
2658 // Create a second socket to the same host, but this one will wait.
2659 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2660 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132661 EXPECT_EQ(ERR_IO_PENDING,
2662 handle2.Init("a",
2663 params_,
2664 kDefaultPriority,
2665 &callback,
2666 pool_.get(),
2667 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262668 // No idle sockets, and one connecting job.
2669 EXPECT_EQ(0, pool_->IdleSocketCount());
2670 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2671
2672 // Return the first handle to the pool. This will initiate the delayed
2673 // binding.
2674 handle1.Reset();
2675
2676 MessageLoop::current()->RunAllPending();
2677
2678 // Still no idle sockets, still one pending connect job.
2679 EXPECT_EQ(0, pool_->IdleSocketCount());
2680 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2681
2682 // The second socket connected, even though it was a Waiting Job.
2683 EXPECT_EQ(OK, callback.WaitForResult());
2684
2685 // And we can see there is still one job waiting.
2686 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2687
2688 // Finally, signal the waiting Connect.
2689 client_socket_factory_.SignalJobs();
2690 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2691
2692 MessageLoop::current()->RunAllPending();
2693}
2694
2695// Test out the case where we have one socket connected, one
2696// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512697// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262698// should complete, by taking the first socket's idle socket.
2699TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2700 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2701 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2702
2703 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102704 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132705 EXPECT_EQ(ERR_IO_PENDING,
2706 handle1.Init("a",
2707 params_,
2708 kDefaultPriority,
2709 &callback,
2710 pool_.get(),
2711 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262712 EXPECT_EQ(OK, callback.WaitForResult());
2713
2714 // No idle sockets, no pending jobs.
2715 EXPECT_EQ(0, pool_->IdleSocketCount());
2716 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2717
2718 // Create a second socket to the same host, but this one will wait.
2719 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2720 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132721 EXPECT_EQ(ERR_IO_PENDING,
2722 handle2.Init("a",
2723 params_,
2724 kDefaultPriority,
2725 &callback,
2726 pool_.get(),
2727 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262728 // No idle sockets, and one connecting job.
2729 EXPECT_EQ(0, pool_->IdleSocketCount());
2730 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2731
2732 // Return the first handle to the pool. This will initiate the delayed
2733 // binding.
2734 handle1.Reset();
2735
2736 MessageLoop::current()->RunAllPending();
2737
2738 // Still no idle sockets, still one pending connect job.
2739 EXPECT_EQ(0, pool_->IdleSocketCount());
2740 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2741
2742 // The second socket connected, even though it was a Waiting Job.
2743 EXPECT_EQ(OK, callback.WaitForResult());
2744
2745 // And we can see there is still one job waiting.
2746 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2747
2748 // Finally, signal the waiting Connect.
2749 client_socket_factory_.SignalJobs();
2750 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2751
2752 MessageLoop::current()->RunAllPending();
2753}
2754
[email protected]2abfe90a2010-08-25 17:49:512755// Cover the case where on an available socket slot, we have one pending
2756// request that completes synchronously, thereby making the Group empty.
2757TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2758 const int kUnlimitedSockets = 100;
2759 const int kOneSocketPerGroup = 1;
2760 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2761
2762 // Make the first request asynchronous fail.
2763 // This will free up a socket slot later.
2764 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2765
2766 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102767 TestOldCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132768 EXPECT_EQ(ERR_IO_PENDING,
2769 handle1.Init("a",
2770 params_,
2771 kDefaultPriority,
2772 &callback1,
2773 pool_.get(),
2774 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512775 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2776
2777 // Make the second request synchronously fail. This should make the Group
2778 // empty.
2779 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2780 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102781 TestOldCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512782 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2783 // when created.
[email protected]2431756e2010-09-29 20:26:132784 EXPECT_EQ(ERR_IO_PENDING,
2785 handle2.Init("a",
2786 params_,
2787 kDefaultPriority,
2788 &callback2,
2789 pool_.get(),
2790 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512791
2792 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2793
2794 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2795 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2796 EXPECT_FALSE(pool_->HasGroup("a"));
2797}
2798
[email protected]e1b54dc2010-10-06 21:27:222799TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2800 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2801
2802 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2803
2804 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102805 TestOldCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222806 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2807 params_,
2808 kDefaultPriority,
2809 &callback1,
2810 pool_.get(),
2811 BoundNetLog()));
2812
2813 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102814 TestOldCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222815 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2816 params_,
2817 kDefaultPriority,
2818 &callback2,
2819 pool_.get(),
2820 BoundNetLog()));
2821 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102822 TestOldCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222823 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2824 params_,
2825 kDefaultPriority,
2826 &callback3,
2827 pool_.get(),
2828 BoundNetLog()));
2829
2830 EXPECT_EQ(OK, callback1.WaitForResult());
2831 EXPECT_EQ(OK, callback2.WaitForResult());
2832 EXPECT_EQ(OK, callback3.WaitForResult());
2833
2834 // Use the socket.
2835 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2836 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2837
2838 handle1.Reset();
2839 handle2.Reset();
2840 handle3.Reset();
2841
2842 EXPECT_EQ(OK, handle1.Init("a",
2843 params_,
2844 kDefaultPriority,
2845 &callback1,
2846 pool_.get(),
2847 BoundNetLog()));
2848 EXPECT_EQ(OK, handle2.Init("a",
2849 params_,
2850 kDefaultPriority,
2851 &callback2,
2852 pool_.get(),
2853 BoundNetLog()));
2854 EXPECT_EQ(OK, handle3.Init("a",
2855 params_,
2856 kDefaultPriority,
2857 &callback3,
2858 pool_.get(),
2859 BoundNetLog()));
2860
2861 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2862 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2863 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2864}
2865
[email protected]2c2bef152010-10-13 00:55:032866TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2867 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2868 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2869
2870 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2871
2872 ASSERT_TRUE(pool_->HasGroup("a"));
2873 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2874 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2875
2876 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102877 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032878 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2879 params_,
2880 kDefaultPriority,
2881 &callback1,
2882 pool_.get(),
2883 BoundNetLog()));
2884
2885 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102886 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032887 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2888 params_,
2889 kDefaultPriority,
2890 &callback2,
2891 pool_.get(),
2892 BoundNetLog()));
2893
2894 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2895 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2896
2897 EXPECT_EQ(OK, callback1.WaitForResult());
2898 EXPECT_EQ(OK, callback2.WaitForResult());
2899 handle1.Reset();
2900 handle2.Reset();
2901
2902 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2903 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2904}
2905
2906TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2907 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2908 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2909
2910 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102911 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032912 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2913 params_,
2914 kDefaultPriority,
2915 &callback1,
2916 pool_.get(),
2917 BoundNetLog()));
2918
2919 ASSERT_TRUE(pool_->HasGroup("a"));
2920 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2921 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2922
2923 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2924
2925 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2926 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2927
2928 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102929 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032930 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2931 params_,
2932 kDefaultPriority,
2933 &callback2,
2934 pool_.get(),
2935 BoundNetLog()));
2936
2937 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2938 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2939
2940 EXPECT_EQ(OK, callback1.WaitForResult());
2941 EXPECT_EQ(OK, callback2.WaitForResult());
2942 handle1.Reset();
2943 handle2.Reset();
2944
2945 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2946 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2947}
2948
2949TEST_F(ClientSocketPoolBaseTest,
2950 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2951 CreatePool(4, 4);
2952 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2953
2954 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102955 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032956 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2957 params_,
2958 kDefaultPriority,
2959 &callback1,
2960 pool_.get(),
2961 BoundNetLog()));
2962
2963 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102964 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032965 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2966 params_,
2967 kDefaultPriority,
2968 &callback2,
2969 pool_.get(),
2970 BoundNetLog()));
2971
2972 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102973 TestOldCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:032974 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2975 params_,
2976 kDefaultPriority,
2977 &callback3,
2978 pool_.get(),
2979 BoundNetLog()));
2980
2981 ASSERT_TRUE(pool_->HasGroup("a"));
2982 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2983 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2984
2985 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2986
2987 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2988 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2989
2990 EXPECT_EQ(OK, callback1.WaitForResult());
2991 EXPECT_EQ(OK, callback2.WaitForResult());
2992 EXPECT_EQ(OK, callback3.WaitForResult());
2993 handle1.Reset();
2994 handle2.Reset();
2995 handle3.Reset();
2996
2997 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2998 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2999}
3000
3001TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3002 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3003 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3004
3005 ASSERT_FALSE(pool_->HasGroup("a"));
3006
3007 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3008 BoundNetLog());
3009
3010 ASSERT_TRUE(pool_->HasGroup("a"));
3011 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3012
3013 ASSERT_FALSE(pool_->HasGroup("b"));
3014
3015 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3016 BoundNetLog());
3017
3018 ASSERT_FALSE(pool_->HasGroup("b"));
3019}
3020
3021TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3022 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3023 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3024
3025 ASSERT_FALSE(pool_->HasGroup("a"));
3026
3027 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3028 BoundNetLog());
3029
3030 ASSERT_TRUE(pool_->HasGroup("a"));
3031 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3032
3033 ASSERT_FALSE(pool_->HasGroup("b"));
3034
3035 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3036 BoundNetLog());
3037
3038 ASSERT_TRUE(pool_->HasGroup("b"));
3039 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3040}
3041
3042TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3043 CreatePool(4, 4);
3044 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3045
3046 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103047 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033048 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3049 params_,
3050 kDefaultPriority,
3051 &callback1,
3052 pool_.get(),
3053 BoundNetLog()));
3054 ASSERT_EQ(OK, callback1.WaitForResult());
3055 handle1.Reset();
3056
3057 ASSERT_TRUE(pool_->HasGroup("a"));
3058 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3059 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3060
3061 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3062
3063 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3064 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3065}
3066
3067TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3068 CreatePool(4, 4);
3069 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3070
3071 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103072 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033073 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3074 params_,
3075 kDefaultPriority,
3076 &callback1,
3077 pool_.get(),
3078 BoundNetLog()));
3079 ASSERT_EQ(OK, callback1.WaitForResult());
3080
3081 ASSERT_TRUE(pool_->HasGroup("a"));
3082 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3083 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3084 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3085
3086 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3087
3088 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3089 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3090 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3091}
3092
3093TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3094 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3095 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3096
3097 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3098 BoundNetLog());
3099
3100 ASSERT_TRUE(pool_->HasGroup("a"));
3101 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3102 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3103
3104 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3105 BoundNetLog());
3106
3107 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3108 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3109}
3110
[email protected]3c819f522010-12-02 02:03:123111TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3112 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3113 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3114
3115 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3116 BoundNetLog());
3117
3118 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523119
3120 connect_job_factory_->set_job_type(
3121 TestConnectJob::kMockAdditionalErrorStateJob);
3122 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3123 BoundNetLog());
3124
3125 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123126}
3127
[email protected]2c2bef152010-10-13 00:55:033128TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3129 CreatePool(4, 4);
3130 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3131
3132 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3133
3134 ASSERT_TRUE(pool_->HasGroup("a"));
3135 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3136 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3137
3138 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3139 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3140 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3141
3142 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103143 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033144 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3145 params_,
3146 kDefaultPriority,
3147 &callback1,
3148 pool_.get(),
3149 BoundNetLog()));
3150 ASSERT_EQ(OK, callback1.WaitForResult());
3151
3152 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103153 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033154 int rv = handle2.Init("a",
3155 params_,
3156 kDefaultPriority,
3157 &callback2,
3158 pool_.get(),
3159 BoundNetLog());
3160 if (rv != OK) {
3161 EXPECT_EQ(ERR_IO_PENDING, rv);
3162 EXPECT_EQ(OK, callback2.WaitForResult());
3163 }
3164
3165 handle1.Reset();
3166 handle2.Reset();
3167
3168 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3169
3170 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3171 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3172 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3173}
3174
3175TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3176 CreatePool(4, 4);
3177 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3178
3179 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3180
3181 ASSERT_TRUE(pool_->HasGroup("a"));
3182 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3183 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3184
3185 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3186 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3187 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3188
3189 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3190 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3191 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3192
3193 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3194 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3195 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3196}
3197
3198TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3200 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3201
3202 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3203
3204 ASSERT_TRUE(pool_->HasGroup("a"));
3205 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3206 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3207
3208 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103209 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033210 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3211 params_,
3212 kDefaultPriority,
3213 &callback1,
3214 pool_.get(),
3215 BoundNetLog()));
3216
3217 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3218 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3219
3220 ASSERT_EQ(OK, callback1.WaitForResult());
3221
3222 handle1.Reset();
3223
3224 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3225}
3226
[email protected]dcbe168a2010-12-02 03:14:463227// http://crbug.com/64940 regression test.
3228TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3229 const int kMaxTotalSockets = 3;
3230 const int kMaxSocketsPerGroup = 2;
3231 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3232 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3233
3234 // Note that group name ordering matters here. "a" comes before "b", so
3235 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3236
3237 // Set up one idle socket in "a".
3238 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103239 TestOldCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463240 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3241 params_,
3242 kDefaultPriority,
3243 &callback1,
3244 pool_.get(),
3245 BoundNetLog()));
3246
3247 ASSERT_EQ(OK, callback1.WaitForResult());
3248 handle1.Reset();
3249 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3250
3251 // Set up two active sockets in "b".
3252 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103253 TestOldCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463254 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3255 params_,
3256 kDefaultPriority,
3257 &callback1,
3258 pool_.get(),
3259 BoundNetLog()));
3260 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3261 params_,
3262 kDefaultPriority,
3263 &callback2,
3264 pool_.get(),
3265 BoundNetLog()));
3266
3267 ASSERT_EQ(OK, callback1.WaitForResult());
3268 ASSERT_EQ(OK, callback2.WaitForResult());
3269 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3270 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3271
3272 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3273 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3274 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3275 // sockets for "a", and "b" should still have 2 active sockets.
3276
3277 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3278 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3279 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3280 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3281 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3282 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3283 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3284
3285 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3286 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3287 // "a" should result in closing 1 for "b".
3288 handle1.Reset();
3289 handle2.Reset();
3290 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3291 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3292
3293 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3294 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3295 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3296 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3297 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3298 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3299 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3300}
3301
[email protected]b7b8be42011-07-12 12:46:413302TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073303 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3304 pool_->EnableConnectBackupJobs();
3305
3306 // Make the ConnectJob hang until it times out, shorten the timeout.
3307 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3308 connect_job_factory_->set_timeout_duration(
3309 base::TimeDelta::FromMilliseconds(500));
3310 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3311 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3312 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073313
[email protected]b7b8be42011-07-12 12:46:413314 // Verify the backup timer doesn't create a backup job, by making
3315 // the backup job a pending job instead of a waiting job, so it
3316 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073317 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413318 MessageLoop::current()->PostDelayedTask(FROM_HERE,
3319 new MessageLoop::QuitTask(), 1000);
3320 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073321 EXPECT_FALSE(pool_->HasGroup("a"));
3322}
3323
[email protected]b7b8be42011-07-12 12:46:413324TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3326 pool_->EnableConnectBackupJobs();
3327
3328 // Make the ConnectJob hang forever.
3329 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3330 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3331 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3332 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3333 MessageLoop::current()->RunAllPending();
3334
3335 // Make the backup job be a pending job, so it completes normally.
3336 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3337 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:103338 TestOldCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073339 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3340 params_,
3341 kDefaultPriority,
3342 &callback,
3343 pool_.get(),
3344 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413345 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073346 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3347 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3348 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3349 ASSERT_EQ(OK, callback.WaitForResult());
3350
3351 // The hung connect job should still be there, but everything else should be
3352 // complete.
3353 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3354 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3355 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3356}
3357
[email protected]f6d1d6eb2009-06-24 20:16:093358} // namespace
3359
3360} // namespace net