blob: 23360f52d7712339eca4195d44ccd69bd63e3135 [file] [log] [blame]
[email protected]e34400c32012-01-24 02:49:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]6ecf2b92011-12-15 01:14:527#include "base/bind.h"
8#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:599#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:0910#include "base/compiler_specific.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_vector.h"
[email protected]6ea7b152011-12-21 21:21:1313#include "base/memory/weak_ptr.h"
[email protected]f6d1d6eb2009-06-24 20:16:0914#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4015#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2516#include "base/string_number_conversions.h"
[email protected]f214f8792011-01-01 02:17:0817#include "base/threading/platform_thread.h"
[email protected]f3a1c642011-07-12 19:15:0318#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0619#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5320#include "net/base/net_log.h"
21#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3122#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0923#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3524#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0925#include "net/socket/client_socket_factory.h"
26#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0027#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1728#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1929#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1030#include "net/socket/stream_socket.h"
[email protected]f6d1d6eb2009-06-24 20:16:0931#include "testing/gtest/include/gtest/gtest.h"
32
33namespace net {
34
35namespace {
36
[email protected]211d21722009-07-22 15:48:5337const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2038const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5239const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0140
[email protected]df4b4ef2010-07-12 18:25:2141class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2042 public:
[email protected]e34400c32012-01-24 02:49:3343 bool ignore_limits() { return false; }
[email protected]df4b4ef2010-07-12 18:25:2144 private:
45 friend class base::RefCounted<TestSocketParams>;
46 ~TestSocketParams() {}
47};
[email protected]7fc5b09a2010-02-27 00:07:3848typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4949
[email protected]3268023f2011-05-05 00:08:1050class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0951 public:
[email protected]5e6efa52011-06-27 17:26:4152 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
53 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0954
[email protected]3f55aa12011-12-07 02:03:3355 // Socket implementation.
[email protected]ab838892009-06-30 18:49:0556 virtual int Read(
[email protected]83039bb2011-12-09 18:43:5557 IOBuffer* /* buf */, int len,
58 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]3f55aa12011-12-07 02:03:3359 num_bytes_read_ += len;
60 return len;
61 }
[email protected]ab838892009-06-30 18:49:0562
63 virtual int Write(
[email protected]83039bb2011-12-09 18:43:5564 IOBuffer* /* buf */, int len,
65 const CompletionCallback& /* callback */) OVERRIDE {
[email protected]0f873e82010-09-02 16:09:0166 was_used_to_convey_data_ = true;
67 return len;
[email protected]ab838892009-06-30 18:49:0568 }
[email protected]06650c52010-06-03 00:49:1769 virtual bool SetReceiveBufferSize(int32 size) { return true; }
70 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0571
[email protected]dbf036f2011-12-06 23:33:2472 // StreamSocket implementation.
[email protected]83039bb2011-12-09 18:43:5573 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
[email protected]dbf036f2011-12-06 23:33:2474 connected_ = true;
75 return OK;
76 }
[email protected]f6d1d6eb2009-06-24 20:16:0977
[email protected]ab838892009-06-30 18:49:0578 virtual void Disconnect() { connected_ = false; }
79 virtual bool IsConnected() const { return connected_; }
80 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0181
[email protected]ac9eec62010-02-20 18:50:3882 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1683 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0984 }
[email protected]f6d1d6eb2009-06-24 20:16:0985
[email protected]e7f74da2011-04-19 23:49:3586 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
87 return ERR_UNEXPECTED;
88 }
89
[email protected]a2006ece2010-04-23 16:44:0290 virtual const BoundNetLog& NetLog() const {
91 return net_log_;
92 }
93
[email protected]9b5614a2010-08-25 20:29:4594 virtual void SetSubresourceSpeculation() {}
95 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:4196 virtual bool WasEverUsed() const {
97 return was_used_to_convey_data_ || num_bytes_read_ > 0;
98 }
[email protected]7f7e92392010-10-26 18:29:2999 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:41100 virtual int64 NumBytesRead() const { return num_bytes_read_; }
101 virtual base::TimeDelta GetConnectTimeMicros() const {
102 static const base::TimeDelta kDummyConnectTimeMicros =
103 base::TimeDelta::FromMicroseconds(10);
104 return kDummyConnectTimeMicros; // Dummy value.
105 }
[email protected]9b5614a2010-08-25 20:29:45106
[email protected]f6d1d6eb2009-06-24 20:16:09107 private:
108 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02109 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01110 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41111 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09112
[email protected]ab838892009-06-30 18:49:05113 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09114};
115
[email protected]5fc08e32009-07-15 17:09:57116class TestConnectJob;
117
[email protected]f6d1d6eb2009-06-24 20:16:09118class MockClientSocketFactory : public ClientSocketFactory {
119 public:
[email protected]ab838892009-06-30 18:49:05120 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09121
[email protected]98b0e582011-06-22 14:31:41122 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04123 DatagramSocket::BindType bind_type,
124 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41125 NetLog* net_log,
126 const NetLog::Source& source) {
127 NOTREACHED();
128 return NULL;
129 }
130
[email protected]3268023f2011-05-05 00:08:10131 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07132 const AddressList& addresses,
133 NetLog* /* net_log */,
134 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09135 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05136 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09137 }
138
139 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18140 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27141 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21142 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12143 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17144 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09145 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21146 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09147 return NULL;
148 }
149
[email protected]25f47352011-02-25 16:31:59150 virtual void ClearSSLSessionCache() {
151 NOTIMPLEMENTED();
152 }
153
[email protected]5fc08e32009-07-15 17:09:57154 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
155 void SignalJobs();
156
[email protected]f6d1d6eb2009-06-24 20:16:09157 int allocation_count() const { return allocation_count_; }
158
[email protected]f6d1d6eb2009-06-24 20:16:09159 private:
160 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57161 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09162};
163
[email protected]ab838892009-06-30 18:49:05164class TestConnectJob : public ConnectJob {
165 public:
166 enum JobType {
167 kMockJob,
168 kMockFailingJob,
169 kMockPendingJob,
170 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57171 kMockWaitingJob,
172 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13173 kMockRecoverableJob,
174 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18175 kMockAdditionalErrorStateJob,
176 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05177 };
178
[email protected]994d4932010-07-12 17:55:13179 // The kMockPendingJob uses a slight delay before allowing the connect
180 // to complete.
181 static const int kPendingConnectDelay = 2;
182
[email protected]ab838892009-06-30 18:49:05183 TestConnectJob(JobType job_type,
184 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49185 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34186 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05187 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30188 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17189 NetLog* net_log)
190 : ConnectJob(group_name, timeout_duration, delegate,
191 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58192 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05193 client_socket_factory_(client_socket_factory),
[email protected]6ea7b152011-12-21 21:21:13194 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
[email protected]e60e47a2010-07-14 03:37:18195 load_state_(LOAD_STATE_IDLE),
196 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05197
[email protected]974ebd62009-08-03 23:14:34198 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13199 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34200 }
201
[email protected]46451352009-09-01 14:54:21202 virtual LoadState GetLoadState() const { return load_state_; }
203
[email protected]e60e47a2010-07-14 03:37:18204 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
205 if (store_additional_error_state_) {
206 // Set all of the additional error state fields in some way.
207 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43208 HttpResponseInfo info;
209 info.headers = new HttpResponseHeaders("");
210 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18211 }
212 }
213
[email protected]974ebd62009-08-03 23:14:34214 private:
[email protected]3f55aa12011-12-07 02:03:33215 // ConnectJob implementation.
[email protected]ab838892009-06-30 18:49:05216
[email protected]974ebd62009-08-03 23:14:34217 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05218 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28219 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07220 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40221 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05222 switch (job_type_) {
223 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13224 return DoConnect(true /* successful */, false /* sync */,
225 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05226 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13227 return DoConnect(false /* error */, false /* sync */,
228 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05229 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57230 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47231
232 // Depending on execution timings, posting a delayed task can result
233 // in the task getting executed the at the earliest possible
234 // opportunity or only after returning once from the message loop and
235 // then a second call into the message loop. In order to make behavior
236 // more deterministic, we change the default delay to 2ms. This should
237 // always require us to wait for the second call into the message loop.
238 //
239 // N.B. The correct fix for this and similar timing problems is to
240 // abstract time for the purpose of unittests. Unfortunately, we have
241 // a lot of third-party components that directly call the various
242 // time functions, so this change would be rather invasive.
243 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05244 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13245 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
246 weak_factory_.GetWeakPtr(),
247 true /* successful */,
248 true /* async */,
249 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13250 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05251 return ERR_IO_PENDING;
252 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57253 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47254 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05255 FROM_HERE,
[email protected]6ea7b152011-12-21 21:21:13256 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
257 weak_factory_.GetWeakPtr(),
258 false /* error */,
259 true /* async */,
260 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47261 2);
[email protected]ab838892009-06-30 18:49:05262 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57263 case kMockWaitingJob:
264 client_socket_factory_->WaitForSignal(this);
265 waiting_success_ = true;
266 return ERR_IO_PENDING;
267 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46268 MessageLoop::current()->PostTask(
[email protected]6ea7b152011-12-21 21:21:13269 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
270 weak_factory_.GetWeakPtr(), 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,
[email protected]6ea7b152011-12-21 21:21:13279 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
280 weak_factory_.GetWeakPtr(),
281 false /* error */,
282 true /* async */,
283 true /* recoverable */),
[email protected]e772db3f2010-07-12 18:11:13284 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,
[email protected]6ea7b152011-12-21 21:21:13295 base::Bind(base::IgnoreResult(&TestConnectJob::DoConnect),
296 weak_factory_.GetWeakPtr(),
297 false /* error */,
298 true /* async */,
299 false /* recoverable */),
[email protected]e60e47a2010-07-14 03:37:18300 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]83039bb2011-12-09 18:43:55314 socket()->Connect(CompletionCallback());
[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(
[email protected]6ea7b152011-12-21 21:21:13338 FROM_HERE, base::Bind(&TestConnectJob::AdvanceLoadState,
339 weak_factory_.GetWeakPtr(), state));
[email protected]cfa8228c2010-06-17 01:07:56340 }
[email protected]5fc08e32009-07-15 17:09:57341 }
342
343 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05344 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57345 MockClientSocketFactory* const client_socket_factory_;
[email protected]6ea7b152011-12-21 21:21:13346 base::WeakPtrFactory<TestConnectJob> weak_factory_;
[email protected]46451352009-09-01 14:54:21347 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18348 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05349
350 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
351};
352
[email protected]d80a4322009-08-14 07:07:49353class TestConnectJobFactory
354 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05355 public:
[email protected]5fc08e32009-07-15 17:09:57356 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05357 : job_type_(TestConnectJob::kMockJob),
358 client_socket_factory_(client_socket_factory) {}
359
360 virtual ~TestConnectJobFactory() {}
361
362 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
363
[email protected]974ebd62009-08-03 23:14:34364 void set_timeout_duration(base::TimeDelta timeout_duration) {
365 timeout_duration_ = timeout_duration;
366 }
367
[email protected]3f55aa12011-12-07 02:03:33368 // ConnectJobFactory implementation.
[email protected]83039bb2011-12-09 18:43:55369
[email protected]ab838892009-06-30 18:49:05370 virtual ConnectJob* NewConnectJob(
371 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49372 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17373 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05374 return new TestConnectJob(job_type_,
375 group_name,
376 request,
[email protected]974ebd62009-08-03 23:14:34377 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05378 delegate,
[email protected]fd7b7c92009-08-20 19:38:30379 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17380 NULL);
[email protected]ab838892009-06-30 18:49:05381 }
382
[email protected]a796bcec2010-03-22 17:17:26383 virtual base::TimeDelta ConnectionTimeout() const {
384 return timeout_duration_;
385 }
386
[email protected]ab838892009-06-30 18:49:05387 private:
388 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34389 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57390 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05391
392 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
393};
394
395class TestClientSocketPool : public ClientSocketPool {
396 public:
397 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53398 int max_sockets,
[email protected]ab838892009-06-30 18:49:05399 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13400 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16401 base::TimeDelta unused_idle_socket_timeout,
402 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49403 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00404 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16405 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38406 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05407
[email protected]2431756e2010-09-29 20:26:13408 virtual ~TestClientSocketPool() {}
409
[email protected]ab838892009-06-30 18:49:05410 virtual int RequestSocket(
411 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49412 const void* params,
[email protected]ac790b42009-12-02 04:31:31413 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05414 ClientSocketHandle* handle,
[email protected]49639fa2011-12-20 23:22:41415 const CompletionCallback& callback,
[email protected]d4dfdab2011-12-07 16:56:59416 const BoundNetLog& net_log) OVERRIDE {
[email protected]df4b4ef2010-07-12 18:25:21417 const scoped_refptr<TestSocketParams>* casted_socket_params =
418 static_cast<const scoped_refptr<TestSocketParams>*>(params);
419 return base_.RequestSocket(group_name, *casted_socket_params, priority,
420 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05421 }
422
[email protected]2c2bef152010-10-13 00:55:03423 virtual void RequestSockets(const std::string& group_name,
424 const void* params,
425 int num_sockets,
[email protected]d4dfdab2011-12-07 16:56:59426 const BoundNetLog& net_log) OVERRIDE {
[email protected]2c2bef152010-10-13 00:55:03427 const scoped_refptr<TestSocketParams>* casted_params =
428 static_cast<const scoped_refptr<TestSocketParams>*>(params);
429
430 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
431 }
432
[email protected]ab838892009-06-30 18:49:05433 virtual void CancelRequest(
434 const std::string& group_name,
[email protected]d4dfdab2011-12-07 16:56:59435 ClientSocketHandle* handle) OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49436 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05437 }
438
439 virtual void ReleaseSocket(
440 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10441 StreamSocket* socket,
[email protected]d4dfdab2011-12-07 16:56:59442 int id) OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24443 base_.ReleaseSocket(group_name, socket, id);
444 }
445
[email protected]d4dfdab2011-12-07 16:56:59446 virtual void Flush() OVERRIDE {
[email protected]a7e38572010-06-07 18:22:24447 base_.Flush();
[email protected]ab838892009-06-30 18:49:05448 }
449
[email protected]d4dfdab2011-12-07 16:56:59450 virtual void CloseIdleSockets() OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49451 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05452 }
453
[email protected]d4dfdab2011-12-07 16:56:59454 virtual int IdleSocketCount() const OVERRIDE {
455 return base_.idle_socket_count();
456 }
[email protected]ab838892009-06-30 18:49:05457
[email protected]d4dfdab2011-12-07 16:56:59458 virtual int IdleSocketCountInGroup(
459 const std::string& group_name) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49460 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05461 }
462
[email protected]d4dfdab2011-12-07 16:56:59463 virtual LoadState GetLoadState(
464 const std::string& group_name,
465 const ClientSocketHandle* handle) const OVERRIDE {
[email protected]d80a4322009-08-14 07:07:49466 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05467 }
468
[email protected]d4dfdab2011-12-07 16:56:59469 virtual DictionaryValue* GetInfoAsValue(
470 const std::string& name,
471 const std::string& type,
472 bool include_nested_pools) const OVERRIDE {
[email protected]59d7a5a2010-08-30 16:44:27473 return base_.GetInfoAsValue(name, type);
474 }
475
[email protected]d4dfdab2011-12-07 16:56:59476 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
[email protected]a796bcec2010-03-22 17:17:26477 return base_.ConnectionTimeout();
478 }
479
[email protected]d4dfdab2011-12-07 16:56:59480 virtual ClientSocketPoolHistograms* histograms() const OVERRIDE {
[email protected]b89f7e42010-05-20 20:37:00481 return base_.histograms();
482 }
[email protected]a796bcec2010-03-22 17:17:26483
[email protected]d80a4322009-08-14 07:07:49484 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20485
[email protected]974ebd62009-08-03 23:14:34486 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49487 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34488 }
489
[email protected]2c2bef152010-10-13 00:55:03490 int NumActiveSocketsInGroup(const std::string& group_name) const {
491 return base_.NumActiveSocketsInGroup(group_name);
492 }
493
[email protected]2abfe90a2010-08-25 17:49:51494 bool HasGroup(const std::string& group_name) const {
495 return base_.HasGroup(group_name);
496 }
497
[email protected]9bf28db2009-08-29 01:35:16498 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
499
[email protected]06d94042010-08-25 01:45:22500 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54501
[email protected]ab838892009-06-30 18:49:05502 private:
[email protected]d80a4322009-08-14 07:07:49503 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05504
505 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
506};
507
[email protected]a937a06d2009-08-19 21:19:24508} // namespace
509
[email protected]7fc5b09a2010-02-27 00:07:38510REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24511
512namespace {
513
[email protected]5fc08e32009-07-15 17:09:57514void MockClientSocketFactory::SignalJobs() {
515 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
516 it != waiting_jobs_.end(); ++it) {
517 (*it)->Signal();
518 }
519 waiting_jobs_.clear();
520}
521
[email protected]974ebd62009-08-03 23:14:34522class TestConnectJobDelegate : public ConnectJob::Delegate {
523 public:
524 TestConnectJobDelegate()
525 : have_result_(false), waiting_for_result_(false), result_(OK) {}
526 virtual ~TestConnectJobDelegate() {}
527
528 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
529 result_ = result;
[email protected]3268023f2011-05-05 00:08:10530 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07531 // socket.get() should be NULL iff result != OK
532 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34533 delete job;
534 have_result_ = true;
535 if (waiting_for_result_)
536 MessageLoop::current()->Quit();
537 }
538
539 int WaitForResult() {
540 DCHECK(!waiting_for_result_);
541 while (!have_result_) {
542 waiting_for_result_ = true;
543 MessageLoop::current()->Run();
544 waiting_for_result_ = false;
545 }
546 have_result_ = false; // auto-reset for next callback
547 return result_;
548 }
549
550 private:
551 bool have_result_;
552 bool waiting_for_result_;
553 int result_;
554};
555
[email protected]2431756e2010-09-29 20:26:13556class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09557 protected:
[email protected]b89f7e42010-05-20 20:37:00558 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21559 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54560 histograms_("ClientSocketPoolTest") {
561 connect_backup_jobs_enabled_ =
562 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
563 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41564 cleanup_timer_enabled_ =
565 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54566 }
[email protected]2431756e2010-09-29 20:26:13567
[email protected]636b8252011-04-08 19:56:54568 virtual ~ClientSocketPoolBaseTest() {
569 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
570 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41571 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
572 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54573 }
[email protected]c9d6a1d2009-07-14 16:15:20574
[email protected]211d21722009-07-22 15:48:53575 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16576 CreatePoolWithIdleTimeouts(
577 max_sockets,
578 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30579 ClientSocketPool::unused_idle_socket_timeout(),
580 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16581 }
582
583 void CreatePoolWithIdleTimeouts(
584 int max_sockets, int max_sockets_per_group,
585 base::TimeDelta unused_idle_socket_timeout,
586 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20587 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04588 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13589 pool_.reset(new TestClientSocketPool(max_sockets,
590 max_sockets_per_group,
591 &histograms_,
592 unused_idle_socket_timeout,
593 used_idle_socket_timeout,
594 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20595 }
[email protected]f6d1d6eb2009-06-24 20:16:09596
[email protected]ac790b42009-12-02 04:31:31597 int StartRequest(const std::string& group_name,
598 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13599 return test_base_.StartRequestUsingPool<
600 TestClientSocketPool, TestSocketParams>(
601 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09602 }
603
[email protected]2431756e2010-09-29 20:26:13604 int GetOrderOfRequest(size_t index) const {
605 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09606 }
607
[email protected]2431756e2010-09-29 20:26:13608 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
609 return test_base_.ReleaseOneConnection(keep_alive);
610 }
611
612 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
613 test_base_.ReleaseAllConnections(keep_alive);
614 }
615
616 TestSocketRequest* request(int i) { return test_base_.request(i); }
617 size_t requests_size() const { return test_base_.requests_size(); }
618 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
619 size_t completion_count() const { return test_base_.completion_count(); }
620
[email protected]636b8252011-04-08 19:56:54621 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41622 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09623 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04624 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21625 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13626 ClientSocketPoolHistograms histograms_;
627 scoped_ptr<TestClientSocketPool> pool_;
628 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09629};
630
[email protected]5e6efa52011-06-27 17:26:41631TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
632 CreatePool(4, 4);
633 net::SetSocketReusePolicy(0);
634
635 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
636 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
637 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
638 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
639
640 std::map<int, StreamSocket*> sockets_;
641 for (size_t i = 0; i < test_base_.requests_size(); i++) {
642 TestSocketRequest* req = test_base_.request(i);
643 StreamSocket* s = req->handle()->socket();
644 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
645 CHECK(sock);
646 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55647 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41648 }
649
650 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
651
652 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
653 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
654
655 // First socket is warmest.
656 EXPECT_EQ(sockets_[0], req->handle()->socket());
657
658 // Test that NumBytes are as expected.
659 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
660 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
661 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
662 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
663
664 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
665}
666
667TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
668 CreatePool(4, 4);
669 net::SetSocketReusePolicy(2);
670
671 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
672 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
673 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
674 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
675
676 std::map<int, StreamSocket*> sockets_;
677 for (size_t i = 0; i < test_base_.requests_size(); i++) {
678 TestSocketRequest* req = test_base_.request(i);
679 StreamSocket* s = req->handle()->socket();
680 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
681 CHECK(sock);
682 sockets_[i] = sock;
[email protected]83039bb2011-12-09 18:43:55683 sock->Read(NULL, 1024 - i, CompletionCallback());
[email protected]5e6efa52011-06-27 17:26:41684 }
685
686 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
687
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
690
691 // Last socket is most recently accessed.
692 EXPECT_EQ(sockets_[3], req->handle()->socket());
693 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
694}
695
[email protected]974ebd62009-08-03 23:14:34696// Even though a timeout is specified, it doesn't time out on a synchronous
697// completion.
698TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
699 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06700 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49701 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41702 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03703 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20704 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34705 scoped_ptr<TestConnectJob> job(
706 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12707 "a",
[email protected]974ebd62009-08-03 23:14:34708 request,
709 base::TimeDelta::FromMicroseconds(1),
710 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30711 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17712 NULL));
[email protected]974ebd62009-08-03 23:14:34713 EXPECT_EQ(OK, job->Connect());
714}
715
716TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
717 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06718 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17719 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53720
[email protected]d80a4322009-08-14 07:07:49721 TestClientSocketPoolBase::Request request(
[email protected]49639fa2011-12-20 23:22:41722 &ignored, CompletionCallback(), kDefaultPriority,
[email protected]2c2bef152010-10-13 00:55:03723 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20724 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34725 // Deleted by TestConnectJobDelegate.
726 TestConnectJob* job =
727 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12728 "a",
[email protected]974ebd62009-08-03 23:14:34729 request,
730 base::TimeDelta::FromMicroseconds(1),
731 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30732 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17733 &log);
[email protected]974ebd62009-08-03 23:14:34734 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08735 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34736 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30737
[email protected]b2fcd0e2010-12-01 15:19:40738 net::CapturingNetLog::EntryList entries;
739 log.GetEntries(&entries);
740
741 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46742 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40743 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17744 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40745 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46746 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40747 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17748 NetLog::PHASE_NONE));
749 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40750 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53751 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46752 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40753 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17754 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40755 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34756}
757
[email protected]5fc08e32009-07-15 17:09:57758TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53759 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20760
[email protected]6ecf2b92011-12-15 01:14:52761 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06762 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53763 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
764
[email protected]2431756e2010-09-29 20:26:13765 EXPECT_EQ(OK,
766 handle.Init("a",
767 params_,
768 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52769 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13770 pool_.get(),
771 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09772 EXPECT_TRUE(handle.is_initialized());
773 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09774 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30775
[email protected]b2fcd0e2010-12-01 15:19:40776 net::CapturingNetLog::EntryList entries;
777 log.GetEntries(&entries);
778
779 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46780 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40781 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53782 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40783 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17784 NetLog::PHASE_NONE));
785 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40786 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53787 NetLog::PHASE_NONE));
788 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40789 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09790}
791
[email protected]ab838892009-06-30 18:49:05792TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53793 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20794
[email protected]ab838892009-06-30 18:49:05795 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53796 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
797
[email protected]2431756e2010-09-29 20:26:13798 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:52799 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18800 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13801 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43802 HttpResponseInfo info;
803 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13804 handle.set_ssl_error_response_info(info);
805 EXPECT_EQ(ERR_CONNECTION_FAILED,
806 handle.Init("a",
807 params_,
808 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:52809 callback.callback(),
[email protected]2431756e2010-09-29 20:26:13810 pool_.get(),
811 log.bound()));
812 EXPECT_FALSE(handle.socket());
813 EXPECT_FALSE(handle.is_ssl_error());
814 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30815
[email protected]b2fcd0e2010-12-01 15:19:40816 net::CapturingNetLog::EntryList entries;
817 log.GetEntries(&entries);
818
819 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27820 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40821 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17822 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40823 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17824 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02825 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40826 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09827}
828
[email protected]211d21722009-07-22 15:48:53829TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
830 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
831
[email protected]9e743cd2010-03-16 07:03:53832 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30833
[email protected]211d21722009-07-22 15:48:53834 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
835 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
836 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
837 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
838
[email protected]2431756e2010-09-29 20:26:13839 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53840 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13841 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53842
843 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
844 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
845 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
846
[email protected]2431756e2010-09-29 20:26:13847 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53848
[email protected]2431756e2010-09-29 20:26:13849 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53850 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13851 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53852
853 EXPECT_EQ(1, GetOrderOfRequest(1));
854 EXPECT_EQ(2, GetOrderOfRequest(2));
855 EXPECT_EQ(3, GetOrderOfRequest(3));
856 EXPECT_EQ(4, GetOrderOfRequest(4));
857 EXPECT_EQ(5, GetOrderOfRequest(5));
858 EXPECT_EQ(6, GetOrderOfRequest(6));
859 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17860
861 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13862 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53863}
864
865TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
866 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
867
[email protected]9e743cd2010-03-16 07:03:53868 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30869
[email protected]211d21722009-07-22 15:48:53870 // Reach all limits: max total sockets, and max sockets per group.
871 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
872 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
873 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
874 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
875
[email protected]2431756e2010-09-29 20:26:13876 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53877 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13878 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53879
880 // Now create a new group and verify that we don't starve it.
881 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
882
[email protected]2431756e2010-09-29 20:26:13883 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53884
[email protected]2431756e2010-09-29 20:26:13885 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53886 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13887 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53888
889 EXPECT_EQ(1, GetOrderOfRequest(1));
890 EXPECT_EQ(2, GetOrderOfRequest(2));
891 EXPECT_EQ(3, GetOrderOfRequest(3));
892 EXPECT_EQ(4, GetOrderOfRequest(4));
893 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17894
895 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13896 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53897}
898
899TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
900 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
901
[email protected]ac790b42009-12-02 04:31:31902 EXPECT_EQ(OK, StartRequest("b", LOWEST));
903 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
904 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
905 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53906
[email protected]2431756e2010-09-29 20:26:13907 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53908 client_socket_factory_.allocation_count());
909
[email protected]ac790b42009-12-02 04:31:31910 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
911 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
912 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53913
[email protected]2431756e2010-09-29 20:26:13914 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53915
[email protected]2431756e2010-09-29 20:26:13916 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53917
918 // First 4 requests don't have to wait, and finish in order.
919 EXPECT_EQ(1, GetOrderOfRequest(1));
920 EXPECT_EQ(2, GetOrderOfRequest(2));
921 EXPECT_EQ(3, GetOrderOfRequest(3));
922 EXPECT_EQ(4, GetOrderOfRequest(4));
923
[email protected]ac790b42009-12-02 04:31:31924 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
925 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53926 EXPECT_EQ(7, GetOrderOfRequest(5));
927 EXPECT_EQ(6, GetOrderOfRequest(6));
928 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17929
930 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13931 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53932}
933
934TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
935 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
936
[email protected]ac790b42009-12-02 04:31:31937 EXPECT_EQ(OK, StartRequest("a", LOWEST));
938 EXPECT_EQ(OK, StartRequest("a", LOW));
939 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
940 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53941
[email protected]2431756e2010-09-29 20:26:13942 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53943 client_socket_factory_.allocation_count());
944
[email protected]ac790b42009-12-02 04:31:31945 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
946 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
947 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53948
[email protected]2431756e2010-09-29 20:26:13949 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53950
[email protected]2431756e2010-09-29 20:26:13951 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53952 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13953 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53954
955 // First 4 requests don't have to wait, and finish in order.
956 EXPECT_EQ(1, GetOrderOfRequest(1));
957 EXPECT_EQ(2, GetOrderOfRequest(2));
958 EXPECT_EQ(3, GetOrderOfRequest(3));
959 EXPECT_EQ(4, GetOrderOfRequest(4));
960
961 // Request ("b", 7) has the highest priority, but we can't make new socket for
962 // group "b", because it has reached the per-group limit. Then we make
963 // socket for ("c", 6), because it has higher priority than ("a", 4),
964 // and we still can't make a socket for group "b".
965 EXPECT_EQ(5, GetOrderOfRequest(5));
966 EXPECT_EQ(6, GetOrderOfRequest(6));
967 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17968
969 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13970 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53971}
972
973// Make sure that we count connecting sockets against the total limit.
974TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
976
977 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
978 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
979 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
980
981 // Create one asynchronous request.
982 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
983 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
984
[email protected]6b175382009-10-13 06:47:47985 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
986 // actually become pending until 2ms after they have been created. In order
987 // to flush all tasks, we need to wait so that we know there are no
988 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08989 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47990 MessageLoop::current()->RunAllPending();
991
[email protected]211d21722009-07-22 15:48:53992 // The next synchronous request should wait for its turn.
993 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
994 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
995
[email protected]2431756e2010-09-29 20:26:13996 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53997
[email protected]2431756e2010-09-29 20:26:13998 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53999 client_socket_factory_.allocation_count());
1000
1001 EXPECT_EQ(1, GetOrderOfRequest(1));
1002 EXPECT_EQ(2, GetOrderOfRequest(2));
1003 EXPECT_EQ(3, GetOrderOfRequest(3));
1004 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:171005 EXPECT_EQ(5, GetOrderOfRequest(5));
1006
1007 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131008 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531009}
1010
[email protected]6427fe22010-04-16 22:27:411011TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1012 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1013 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1014
1015 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1016 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1017 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1018 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1019
1020 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1021
1022 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1023
1024 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1025 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1026
1027 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1028
[email protected]2431756e2010-09-29 20:26:131029 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411030 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131031 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411032 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131033 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1034 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411035 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1036}
1037
[email protected]d7027bb2010-05-10 18:58:541038TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1039 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1041
1042 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521043 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131044 EXPECT_EQ(ERR_IO_PENDING,
1045 handle.Init("a",
1046 params_,
1047 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521048 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131049 pool_.get(),
1050 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541051
1052 ClientSocketHandle handles[4];
1053 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]6ecf2b92011-12-15 01:14:521054 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131055 EXPECT_EQ(ERR_IO_PENDING,
1056 handles[i].Init("b",
1057 params_,
1058 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521059 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131060 pool_.get(),
1061 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541062 }
1063
1064 // One will be stalled, cancel all the handles now.
1065 // This should hit the OnAvailableSocketSlot() code where we previously had
1066 // stalled groups, but no longer have any.
1067 for (size_t i = 0; i < arraysize(handles); ++i)
1068 handles[i].Reset();
1069}
1070
[email protected]eb5a99382010-07-11 03:18:261071TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541072 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1073 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1074
[email protected]eb5a99382010-07-11 03:18:261075 {
1076 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]6ecf2b92011-12-15 01:14:521077 TestCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261078 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131079 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1080 params_,
[email protected]e83326f2010-07-31 17:29:251081 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521082 callbacks[i].callback(),
[email protected]2431756e2010-09-29 20:26:131083 pool_.get(),
1084 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261085 }
1086
1087 // Force a stalled group.
1088 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521089 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131090 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1091 params_,
1092 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521093 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131094 pool_.get(),
1095 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261096
1097 // Cancel the stalled request.
1098 stalled_handle.Reset();
1099
1100 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1101 EXPECT_EQ(0, pool_->IdleSocketCount());
1102
1103 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541104 }
1105
[email protected]43a21b82010-06-10 21:30:541106 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1107 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261108}
[email protected]43a21b82010-06-10 21:30:541109
[email protected]eb5a99382010-07-11 03:18:261110TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1112 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1113
1114 {
1115 ClientSocketHandle handles[kDefaultMaxSockets];
1116 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521117 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131118 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1119 params_,
1120 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521121 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131122 pool_.get(),
1123 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261124 }
1125
1126 // Force a stalled group.
1127 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1128 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521129 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131130 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1131 params_,
1132 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521133 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131134 pool_.get(),
1135 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261136
1137 // Since it is stalled, it should have no connect jobs.
1138 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1139
1140 // Cancel the stalled request.
1141 handles[0].Reset();
1142
[email protected]eb5a99382010-07-11 03:18:261143 // Now we should have a connect job.
1144 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1145
1146 // The stalled socket should connect.
1147 EXPECT_EQ(OK, callback.WaitForResult());
1148
1149 EXPECT_EQ(kDefaultMaxSockets + 1,
1150 client_socket_factory_.allocation_count());
1151 EXPECT_EQ(0, pool_->IdleSocketCount());
1152 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1153
1154 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541155 }
1156
[email protected]eb5a99382010-07-11 03:18:261157 EXPECT_EQ(1, pool_->IdleSocketCount());
1158}
[email protected]43a21b82010-06-10 21:30:541159
[email protected]eb5a99382010-07-11 03:18:261160TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1162 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541163
[email protected]eb5a99382010-07-11 03:18:261164 ClientSocketHandle stalled_handle;
[email protected]6ecf2b92011-12-15 01:14:521165 TestCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261166 {
1167 ClientSocketHandle handles[kDefaultMaxSockets];
1168 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:521169 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401170 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1171 "Take 2: %d", i),
1172 params_,
1173 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521174 callback.callback(),
[email protected]1870d5cf2011-05-12 01:55:401175 pool_.get(),
1176 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261177 }
1178
1179 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1180 EXPECT_EQ(0, pool_->IdleSocketCount());
1181
1182 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131183 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1184 params_,
1185 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521186 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131187 pool_.get(),
1188 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261189
1190 // Dropping out of scope will close all handles and return them to idle.
1191 }
[email protected]43a21b82010-06-10 21:30:541192
1193 // But if we wait for it, the released idle sockets will be closed in
1194 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101195 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261196
1197 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1198 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541199}
1200
1201// Regression test for http://crbug.com/40952.
1202TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1203 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221204 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541205 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1206
1207 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1208 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521209 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131210 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1211 params_,
1212 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521213 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131214 pool_.get(),
1215 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541216 }
1217
1218 // Flush all the DoReleaseSocket tasks.
1219 MessageLoop::current()->RunAllPending();
1220
1221 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1222 // reuse a socket.
1223 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1224 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521225 TestCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541226
1227 // "0" is special here, since it should be the first entry in the sorted map,
1228 // which is the one which we would close an idle socket for. We shouldn't
1229 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131230 EXPECT_EQ(OK, handle.Init("0",
1231 params_,
1232 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521233 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131234 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211235 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541236
1237 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1238 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1239}
1240
[email protected]ab838892009-06-30 18:49:051241TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531242 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091243
[email protected]c9d6a1d2009-07-14 16:15:201244 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1245 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031246 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311247 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1248 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1249 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1250 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1251 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091252
[email protected]2431756e2010-09-29 20:26:131253 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091254
[email protected]c9d6a1d2009-07-14 16:15:201255 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1256 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131257 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1258 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091259
[email protected]c9d6a1d2009-07-14 16:15:201260 EXPECT_EQ(1, GetOrderOfRequest(1));
1261 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031262 EXPECT_EQ(8, GetOrderOfRequest(3));
1263 EXPECT_EQ(6, GetOrderOfRequest(4));
1264 EXPECT_EQ(4, GetOrderOfRequest(5));
1265 EXPECT_EQ(3, GetOrderOfRequest(6));
1266 EXPECT_EQ(5, GetOrderOfRequest(7));
1267 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171268
1269 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131270 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091271}
1272
[email protected]ab838892009-06-30 18:49:051273TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531274 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091275
[email protected]c9d6a1d2009-07-14 16:15:201276 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1277 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311278 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1279 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1280 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1281 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1282 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091283
[email protected]2431756e2010-09-29 20:26:131284 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091285
[email protected]2431756e2010-09-29 20:26:131286 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1287 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201288
[email protected]2431756e2010-09-29 20:26:131289 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201290 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131291 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1292 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091293}
1294
1295// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051296// The pending connect job will be cancelled and should not call back into
1297// ClientSocketPoolBase.
1298TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531299 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201300
[email protected]ab838892009-06-30 18:49:051301 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131302 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521303 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131304 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1305 params_,
1306 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521307 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131308 pool_.get(),
1309 BoundNetLog()));
1310 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091311}
1312
[email protected]ab838892009-06-30 18:49:051313TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531314 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201315
[email protected]ab838892009-06-30 18:49:051316 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061317 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521318 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091319
[email protected]2431756e2010-09-29 20:26:131320 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1321 params_,
1322 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521323 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131324 pool_.get(),
1325 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091326
1327 handle.Reset();
1328
[email protected]6ecf2b92011-12-15 01:14:521329 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131330 EXPECT_EQ(ERR_IO_PENDING,
1331 handle.Init("a",
1332 params_,
1333 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521334 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131335 pool_.get(),
1336 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091337
1338 EXPECT_EQ(OK, callback2.WaitForResult());
1339 EXPECT_FALSE(callback.have_result());
1340
1341 handle.Reset();
1342}
1343
[email protected]ab838892009-06-30 18:49:051344TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531345 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091346
[email protected]c9d6a1d2009-07-14 16:15:201347 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1348 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311349 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1350 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1351 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1352 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1353 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091354
1355 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201356 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131357 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1358 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091359
[email protected]2431756e2010-09-29 20:26:131360 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091361
[email protected]c9d6a1d2009-07-14 16:15:201362 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1363 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131364 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1365 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091366
[email protected]c9d6a1d2009-07-14 16:15:201367 EXPECT_EQ(1, GetOrderOfRequest(1));
1368 EXPECT_EQ(2, GetOrderOfRequest(2));
1369 EXPECT_EQ(5, GetOrderOfRequest(3));
1370 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131371 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1372 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201373 EXPECT_EQ(4, GetOrderOfRequest(6));
1374 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171375
1376 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131377 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091378}
1379
[email protected]6ecf2b92011-12-15 01:14:521380class RequestSocketCallback : public TestCompletionCallbackBase {
[email protected]f6d1d6eb2009-06-24 20:16:091381 public:
[email protected]2ab05b52009-07-01 23:57:581382 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241383 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581384 TestConnectJobFactory* test_connect_job_factory,
1385 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091386 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061387 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581388 within_callback_(false),
1389 test_connect_job_factory_(test_connect_job_factory),
[email protected]6ecf2b92011-12-15 01:14:521390 next_job_type_(next_job_type),
1391 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
1392 base::Bind(&RequestSocketCallback::OnComplete,
1393 base::Unretained(this)))) {
1394 }
[email protected]f6d1d6eb2009-06-24 20:16:091395
[email protected]6ecf2b92011-12-15 01:14:521396 virtual ~RequestSocketCallback() {}
1397
1398 const CompletionCallback& callback() const { return callback_; }
1399
1400 private:
1401 void OnComplete(int result) {
1402 SetResult(result);
1403 ASSERT_EQ(OK, result);
[email protected]f6d1d6eb2009-06-24 20:16:091404
1405 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581406 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111407
1408 // Don't allow reuse of the socket. Disconnect it and then release it and
1409 // run through the MessageLoop once to get it completely released.
1410 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091411 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111412 {
1413 MessageLoop::ScopedNestableTaskAllower nestable(
1414 MessageLoop::current());
1415 MessageLoop::current()->RunAllPending();
1416 }
[email protected]f6d1d6eb2009-06-24 20:16:091417 within_callback_ = true;
[email protected]6ecf2b92011-12-15 01:14:521418 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271419 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131420 int rv = handle_->Init("a",
1421 params,
1422 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521423 next_job_callback.callback(),
[email protected]2431756e2010-09-29 20:26:131424 pool_,
1425 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581426 switch (next_job_type_) {
1427 case TestConnectJob::kMockJob:
1428 EXPECT_EQ(OK, rv);
1429 break;
1430 case TestConnectJob::kMockPendingJob:
1431 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471432
1433 // For pending jobs, wait for new socket to be created. This makes
1434 // sure there are no more pending operations nor any unclosed sockets
1435 // when the test finishes.
1436 // We need to give it a little bit of time to run, so that all the
1437 // operations that happen on timers (e.g. cleanup of idle
1438 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111439 {
1440 MessageLoop::ScopedNestableTaskAllower nestable(
1441 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081442 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111443 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1444 }
[email protected]2ab05b52009-07-01 23:57:581445 break;
1446 default:
1447 FAIL() << "Unexpected job type: " << next_job_type_;
1448 break;
1449 }
[email protected]f6d1d6eb2009-06-24 20:16:091450 }
1451 }
1452
[email protected]f6d1d6eb2009-06-24 20:16:091453 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131454 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091455 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581456 TestConnectJobFactory* const test_connect_job_factory_;
1457 TestConnectJob::JobType next_job_type_;
[email protected]6ecf2b92011-12-15 01:14:521458 CompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091459};
1460
[email protected]2ab05b52009-07-01 23:57:581461TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531462 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201463
[email protected]0b7648c2009-07-06 20:14:011464 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061465 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581466 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061467 &handle, pool_.get(), connect_job_factory_,
1468 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131469 int rv = handle.Init("a",
1470 params_,
1471 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521472 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131473 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211474 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091475 ASSERT_EQ(ERR_IO_PENDING, rv);
1476
1477 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581478}
[email protected]f6d1d6eb2009-06-24 20:16:091479
[email protected]2ab05b52009-07-01 23:57:581480TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531481 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201482
[email protected]0b7648c2009-07-06 20:14:011483 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061484 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581485 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061486 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131487 int rv = handle.Init("a",
1488 params_,
1489 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521490 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131491 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211492 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581493 ASSERT_EQ(ERR_IO_PENDING, rv);
1494
1495 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091496}
1497
1498// Make sure that pending requests get serviced after active requests get
1499// cancelled.
[email protected]ab838892009-06-30 18:49:051500TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531501 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201502
[email protected]0b7648c2009-07-06 20:14:011503 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091504
[email protected]c9d6a1d2009-07-14 16:15:201505 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1506 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1507 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1508 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1509 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1510 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1511 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091512
[email protected]c9d6a1d2009-07-14 16:15:201513 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1514 // Let's cancel them.
1515 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131516 ASSERT_FALSE(request(i)->handle()->is_initialized());
1517 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091518 }
1519
[email protected]f6d1d6eb2009-06-24 20:16:091520 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131521 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1522 EXPECT_EQ(OK, request(i)->WaitForResult());
1523 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091524 }
1525
[email protected]2431756e2010-09-29 20:26:131526 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1527 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091528}
1529
1530// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051531TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531532 const size_t kMaxSockets = 5;
1533 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201534
[email protected]0b7648c2009-07-06 20:14:011535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091536
[email protected]211d21722009-07-22 15:48:531537 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1538 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091539
1540 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531541 for (size_t i = 0; i < kNumberOfRequests; ++i)
1542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091543
[email protected]211d21722009-07-22 15:48:531544 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131545 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091546}
1547
[email protected]5fc08e32009-07-15 17:09:571548TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531549 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571550
1551 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1552
[email protected]2431756e2010-09-29 20:26:131553 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521554 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131555 int rv = handle.Init("a",
1556 params_,
1557 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521558 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131559 pool_.get(),
1560 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571561 EXPECT_EQ(ERR_IO_PENDING, rv);
1562
1563 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131564 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571565
[email protected]2431756e2010-09-29 20:26:131566 rv = handle.Init("a",
1567 params_,
1568 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521569 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131570 pool_.get(),
1571 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571572 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131573 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571574
[email protected]2431756e2010-09-29 20:26:131575 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571576 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1577}
1578
[email protected]2b7523d2009-07-29 20:29:231579// Regression test for http://crbug.com/17985.
1580TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1581 const int kMaxSockets = 3;
1582 const int kMaxSocketsPerGroup = 2;
1583 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1584
[email protected]ac790b42009-12-02 04:31:311585 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231586
1587 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1588 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1589
1590 // This is going to be a pending request in an otherwise empty group.
1591 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1592
1593 // Reach the maximum socket limit.
1594 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1595
1596 // Create a stalled group with high priorities.
1597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231599
[email protected]eb5a99382010-07-11 03:18:261600 // Release the first two sockets from "a". Because this is a keepalive,
1601 // the first release will unblock the pending request for "a". The
1602 // second release will unblock a request for "c", becaue it is the next
1603 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131604 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1605 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231606
1607 // Closing idle sockets should not get us into trouble, but in the bug
1608 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411609 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541610 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261611
1612 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231613}
1614
[email protected]4d3b05d2010-01-27 21:27:291615TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571617
1618 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131619 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521620 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531621 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131622 int rv = handle.Init("a",
1623 params_,
1624 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521625 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131626 pool_.get(),
1627 log.bound());
[email protected]5fc08e32009-07-15 17:09:571628 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131629 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1630 EXPECT_EQ(OK, callback.WaitForResult());
1631 EXPECT_TRUE(handle.is_initialized());
1632 EXPECT_TRUE(handle.socket());
1633 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301634
[email protected]b2fcd0e2010-12-01 15:19:401635 net::CapturingNetLog::EntryList entries;
1636 log.GetEntries(&entries);
1637
1638 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461639 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401640 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171641 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401642 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171643 NetLog::PHASE_NONE));
1644 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401645 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171646 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461647 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401648 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571649}
1650
[email protected]4d3b05d2010-01-27 21:27:291651TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571652 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531653 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571654
1655 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131656 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521657 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531658 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181659 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131660 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431661 HttpResponseInfo info;
1662 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131663 handle.set_ssl_error_response_info(info);
1664 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1665 params_,
1666 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521667 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131668 pool_.get(),
1669 log.bound()));
1670 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1671 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1672 EXPECT_FALSE(handle.is_ssl_error());
1673 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301674
[email protected]b2fcd0e2010-12-01 15:19:401675 net::CapturingNetLog::EntryList entries;
1676 log.GetEntries(&entries);
1677
1678 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461679 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401680 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171681 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401682 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171683 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321684 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401685 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571686}
1687
[email protected]4d3b05d2010-01-27 21:27:291688TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101689 // TODO(eroman): Add back the log expectations! Removed them because the
1690 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531691 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571692
1693 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131694 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521695 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131696 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521697 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571698
[email protected]2431756e2010-09-29 20:26:131699 EXPECT_EQ(ERR_IO_PENDING,
1700 handle.Init("a",
1701 params_,
1702 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521703 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131704 pool_.get(),
1705 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531706 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131707 EXPECT_EQ(ERR_IO_PENDING,
1708 handle2.Init("a",
1709 params_,
1710 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521711 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:131712 pool_.get(),
1713 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571714
[email protected]2431756e2010-09-29 20:26:131715 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571716
[email protected]fd7b7c92009-08-20 19:38:301717
1718 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301719
[email protected]2431756e2010-09-29 20:26:131720 EXPECT_EQ(OK, callback2.WaitForResult());
1721 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301722
1723 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531724 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571725}
1726
[email protected]4d3b05d2010-01-27 21:27:291727TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341728 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1729
[email protected]17a0c6c2009-08-04 00:07:041730 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1731
[email protected]ac790b42009-12-02 04:31:311732 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1733 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1734 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1735 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341736
1737 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131738 (*requests())[2]->handle()->Reset();
1739 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341740 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1741
[email protected]2431756e2010-09-29 20:26:131742 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341743 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1744
[email protected]2431756e2010-09-29 20:26:131745 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261746 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341747}
1748
[email protected]5fc08e32009-07-15 17:09:571749// When requests and ConnectJobs are not coupled, the request will get serviced
1750// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291751TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571753
1754 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321755 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571756
[email protected]2431756e2010-09-29 20:26:131757 std::vector<TestSocketRequest*> request_order;
1758 size_t completion_count; // unused
1759 TestSocketRequest req1(&request_order, &completion_count);
1760 int rv = req1.handle()->Init("a",
1761 params_,
1762 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521763 req1.callback(), pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211764 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571765 EXPECT_EQ(ERR_IO_PENDING, rv);
1766 EXPECT_EQ(OK, req1.WaitForResult());
1767
1768 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1769 // without a job.
1770 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1771
[email protected]2431756e2010-09-29 20:26:131772 TestSocketRequest req2(&request_order, &completion_count);
1773 rv = req2.handle()->Init("a",
1774 params_,
1775 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521776 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131777 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);
[email protected]2431756e2010-09-29 20:26:131780 TestSocketRequest req3(&request_order, &completion_count);
1781 rv = req3.handle()->Init("a",
1782 params_,
1783 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521784 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131785 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211786 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571787 EXPECT_EQ(ERR_IO_PENDING, rv);
1788
1789 // Both Requests 2 and 3 are pending. We release socket 1 which should
1790 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331791 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261792 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331793 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571794 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331795 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571796
1797 // Signal job 2, which should service request 3.
1798
1799 client_socket_factory_.SignalJobs();
1800 EXPECT_EQ(OK, req3.WaitForResult());
1801
[email protected]2431756e2010-09-29 20:26:131802 ASSERT_EQ(3U, request_order.size());
1803 EXPECT_EQ(&req1, request_order[0]);
1804 EXPECT_EQ(&req2, request_order[1]);
1805 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571806 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1807}
1808
1809// The requests are not coupled to the jobs. So, the requests should finish in
1810// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291811TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531812 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571813 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321814 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571815
[email protected]2431756e2010-09-29 20:26:131816 std::vector<TestSocketRequest*> request_order;
1817 size_t completion_count; // unused
1818 TestSocketRequest req1(&request_order, &completion_count);
1819 int rv = req1.handle()->Init("a",
1820 params_,
1821 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521822 req1.callback(),
[email protected]2431756e2010-09-29 20:26:131823 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211824 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571825 EXPECT_EQ(ERR_IO_PENDING, rv);
1826
[email protected]2431756e2010-09-29 20:26:131827 TestSocketRequest req2(&request_order, &completion_count);
1828 rv = req2.handle()->Init("a",
1829 params_,
1830 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521831 req2.callback(),
[email protected]2431756e2010-09-29 20:26:131832 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211833 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571834 EXPECT_EQ(ERR_IO_PENDING, rv);
1835
1836 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321837 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571838
[email protected]2431756e2010-09-29 20:26:131839 TestSocketRequest req3(&request_order, &completion_count);
1840 rv = req3.handle()->Init("a",
1841 params_,
1842 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521843 req3.callback(),
[email protected]2431756e2010-09-29 20:26:131844 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211845 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571846 EXPECT_EQ(ERR_IO_PENDING, rv);
1847
1848 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1849 EXPECT_EQ(OK, req2.WaitForResult());
1850 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1851
[email protected]2431756e2010-09-29 20:26:131852 ASSERT_EQ(3U, request_order.size());
1853 EXPECT_EQ(&req1, request_order[0]);
1854 EXPECT_EQ(&req2, request_order[1]);
1855 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571856}
1857
[email protected]e6ec67b2010-06-16 00:12:461858TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531859 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571860 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321861 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571862
[email protected]2431756e2010-09-29 20:26:131863 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521864 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131865 int rv = handle.Init("a",
1866 params_,
1867 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521868 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131869 pool_.get(),
1870 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571871 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131872 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571873
1874 MessageLoop::current()->RunAllPending();
1875
[email protected]2431756e2010-09-29 20:26:131876 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521877 TestCompletionCallback callback2;
1878 rv = handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
1879 pool_.get(), BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571880 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131881 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1882 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571883}
1884
[email protected]e772db3f2010-07-12 18:11:131885TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1887 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1888
[email protected]2431756e2010-09-29 20:26:131889 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521890 TestCompletionCallback callback;
1891 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED,
1892 handle.Init("a", params_, kDefaultPriority, callback.callback(),
1893 pool_.get(), BoundNetLog()));
[email protected]2431756e2010-09-29 20:26:131894 EXPECT_TRUE(handle.is_initialized());
1895 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131896}
1897
1898TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1899 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1900
1901 connect_job_factory_->set_job_type(
1902 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131903 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521904 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131905 EXPECT_EQ(ERR_IO_PENDING,
1906 handle.Init("a",
1907 params_,
1908 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521909 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131910 pool_.get(),
1911 BoundNetLog()));
1912 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1913 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1914 EXPECT_TRUE(handle.is_initialized());
1915 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131916}
1917
[email protected]e60e47a2010-07-14 03:37:181918TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1920 connect_job_factory_->set_job_type(
1921 TestConnectJob::kMockAdditionalErrorStateJob);
1922
[email protected]2431756e2010-09-29 20:26:131923 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521924 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131925 EXPECT_EQ(ERR_CONNECTION_FAILED,
1926 handle.Init("a",
1927 params_,
1928 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521929 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131930 pool_.get(),
1931 BoundNetLog()));
1932 EXPECT_FALSE(handle.is_initialized());
1933 EXPECT_FALSE(handle.socket());
1934 EXPECT_TRUE(handle.is_ssl_error());
1935 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181936}
1937
1938TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1939 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1940
1941 connect_job_factory_->set_job_type(
1942 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131943 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521944 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131945 EXPECT_EQ(ERR_IO_PENDING,
1946 handle.Init("a",
1947 params_,
1948 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:521949 callback.callback(),
[email protected]2431756e2010-09-29 20:26:131950 pool_.get(),
1951 BoundNetLog()));
1952 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1953 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1954 EXPECT_FALSE(handle.is_initialized());
1955 EXPECT_FALSE(handle.socket());
1956 EXPECT_TRUE(handle.is_ssl_error());
1957 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181958}
1959
[email protected]64770b7d2011-11-16 04:30:411960TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1961 // Disable cleanup timer.
1962 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1963
1964 CreatePoolWithIdleTimeouts(
1965 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1966 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
1967 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
1968
1969 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1970
1971 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1972
1973 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:521974 TestCompletionCallback callback;
[email protected]64770b7d2011-11-16 04:30:411975 int rv = handle.Init("a",
1976 params_,
1977 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521978 callback.callback(),
[email protected]64770b7d2011-11-16 04:30:411979 pool_.get(),
1980 BoundNetLog());
1981 EXPECT_EQ(ERR_IO_PENDING, rv);
1982 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1983
1984 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:521985 TestCompletionCallback callback2;
[email protected]64770b7d2011-11-16 04:30:411986 rv = handle2.Init("a",
1987 params_,
1988 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:521989 callback2.callback(),
[email protected]64770b7d2011-11-16 04:30:411990 pool_.get(),
1991 BoundNetLog());
1992 EXPECT_EQ(ERR_IO_PENDING, rv);
1993 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1994
1995 // Cancel one of the requests. Wait for the other, which will get the first
1996 // job. Release the socket. Run the loop again to make sure the second
1997 // socket is sitting idle and the first one is released (since ReleaseSocket()
1998 // just posts a DoReleaseSocket() task).
1999
2000 handle.Reset();
2001 EXPECT_EQ(OK, callback2.WaitForResult());
2002 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552003 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]64770b7d2011-11-16 04:30:412004 handle2.Reset();
2005
[email protected]e34400c32012-01-24 02:49:332006 // The idle socket timeout value was set to 10 milliseconds. Wait 20
[email protected]64770b7d2011-11-16 04:30:412007 // milliseconds so the sockets timeout.
[email protected]e34400c32012-01-24 02:49:332008 base::PlatformThread::Sleep(20);
[email protected]64770b7d2011-11-16 04:30:412009 MessageLoop::current()->RunAllPending();
2010
2011 ASSERT_EQ(2, pool_->IdleSocketCount());
2012
2013 // Request a new socket. This should cleanup the unused and timed out ones.
2014 // A new socket will be created rather than reusing the idle one.
2015 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]6ecf2b92011-12-15 01:14:522016 TestCompletionCallback callback3;
[email protected]64770b7d2011-11-16 04:30:412017 rv = handle.Init("a",
2018 params_,
2019 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522020 callback3.callback(),
[email protected]64770b7d2011-11-16 04:30:412021 pool_.get(),
2022 log.bound());
2023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6ecf2b92011-12-15 01:14:522024 EXPECT_EQ(OK, callback3.WaitForResult());
[email protected]64770b7d2011-11-16 04:30:412025 EXPECT_FALSE(handle.is_reused());
2026
2027 // Make sure the idle socket is closed
2028 ASSERT_TRUE(pool_->HasGroup("a"));
2029 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2030 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2031
2032 net::CapturingNetLog::EntryList entries;
2033 log.GetEntries(&entries);
2034 EXPECT_FALSE(LogContainsEntryWithType(
2035 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2036}
2037
[email protected]4d3b05d2010-01-27 21:27:292038TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162039 CreatePoolWithIdleTimeouts(
2040 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2041 base::TimeDelta(), // Time out unused sockets immediately.
2042 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2043
2044 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2045
2046 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2047
[email protected]2431756e2010-09-29 20:26:132048 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522049 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132050 int rv = handle.Init("a",
2051 params_,
2052 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522053 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132054 pool_.get(),
2055 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132057 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162058
[email protected]2431756e2010-09-29 20:26:132059 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522060 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132061 rv = handle2.Init("a",
2062 params_,
2063 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522064 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132065 pool_.get(),
2066 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162067 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132068 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162069
2070 // Cancel one of the requests. Wait for the other, which will get the first
2071 // job. Release the socket. Run the loop again to make sure the second
2072 // socket is sitting idle and the first one is released (since ReleaseSocket()
2073 // just posts a DoReleaseSocket() task).
2074
[email protected]2431756e2010-09-29 20:26:132075 handle.Reset();
2076 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012077 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552078 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]2431756e2010-09-29 20:26:132079 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472080
2081 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2082 // actually become pending until 2ms after they have been created. In order
2083 // to flush all tasks, we need to wait so that we know there are no
2084 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:082085 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:162086 MessageLoop::current()->RunAllPending();
2087
2088 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042089
[email protected]9bf28db2009-08-29 01:35:162090 // Invoke the idle socket cleanup check. Only one socket should be left, the
2091 // used socket. Request it to make sure that it's used.
2092
2093 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532094 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132095 rv = handle.Init("a",
2096 params_,
2097 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522098 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132099 pool_.get(),
2100 log.bound());
[email protected]9bf28db2009-08-29 01:35:162101 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132102 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402103
2104 net::CapturingNetLog::EntryList entries;
2105 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152106 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402107 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162108}
2109
[email protected]2041cf342010-02-19 03:15:592110// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162111// because of multiple releasing disconnected sockets.
2112TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2113 CreatePoolWithIdleTimeouts(
2114 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2115 base::TimeDelta(), // Time out unused sockets immediately.
2116 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2117
2118 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2119
2120 // Startup 4 connect jobs. Two of them will be pending.
2121
[email protected]2431756e2010-09-29 20:26:132122 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522123 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132124 int rv = handle.Init("a",
2125 params_,
2126 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522127 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132128 pool_.get(),
2129 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162130 EXPECT_EQ(OK, rv);
2131
[email protected]2431756e2010-09-29 20:26:132132 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522133 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132134 rv = handle2.Init("a",
2135 params_,
2136 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522137 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132138 pool_.get(),
2139 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162140 EXPECT_EQ(OK, rv);
2141
[email protected]2431756e2010-09-29 20:26:132142 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522143 TestCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132144 rv = handle3.Init("a",
2145 params_,
2146 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522147 callback3.callback(),
[email protected]2431756e2010-09-29 20:26:132148 pool_.get(),
2149 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162150 EXPECT_EQ(ERR_IO_PENDING, rv);
2151
[email protected]2431756e2010-09-29 20:26:132152 ClientSocketHandle handle4;
[email protected]6ecf2b92011-12-15 01:14:522153 TestCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132154 rv = handle4.Init("a",
2155 params_,
2156 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522157 callback4.callback(),
[email protected]2431756e2010-09-29 20:26:132158 pool_.get(),
2159 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162160 EXPECT_EQ(ERR_IO_PENDING, rv);
2161
2162 // Release two disconnected sockets.
2163
[email protected]2431756e2010-09-29 20:26:132164 handle.socket()->Disconnect();
2165 handle.Reset();
2166 handle2.socket()->Disconnect();
2167 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162168
[email protected]2431756e2010-09-29 20:26:132169 EXPECT_EQ(OK, callback3.WaitForResult());
2170 EXPECT_FALSE(handle3.is_reused());
2171 EXPECT_EQ(OK, callback4.WaitForResult());
2172 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162173}
2174
[email protected]d7027bb2010-05-10 18:58:542175// Regression test for http://crbug.com/42267.
2176// When DoReleaseSocket() is processed for one socket, it is blocked because the
2177// other stalled groups all have releasing sockets, so no progress can be made.
2178TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2179 CreatePoolWithIdleTimeouts(
2180 4 /* socket limit */, 4 /* socket limit per group */,
2181 base::TimeDelta(), // Time out unused sockets immediately.
2182 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2183
2184 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2185
2186 // Max out the socket limit with 2 per group.
2187
[email protected]2431756e2010-09-29 20:26:132188 ClientSocketHandle handle_a[4];
[email protected]6ecf2b92011-12-15 01:14:522189 TestCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132190 ClientSocketHandle handle_b[4];
[email protected]6ecf2b92011-12-15 01:14:522191 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542192
2193 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132194 EXPECT_EQ(OK, handle_a[i].Init("a",
2195 params_,
2196 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522197 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132198 pool_.get(),
2199 BoundNetLog()));
2200 EXPECT_EQ(OK, handle_b[i].Init("b",
2201 params_,
2202 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522203 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132204 pool_.get(),
2205 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542206 }
[email protected]b89f7e42010-05-20 20:37:002207
[email protected]d7027bb2010-05-10 18:58:542208 // Make 4 pending requests, 2 per group.
2209
2210 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132211 EXPECT_EQ(ERR_IO_PENDING,
2212 handle_a[i].Init("a",
2213 params_,
2214 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522215 callback_a[i].callback(),
[email protected]2431756e2010-09-29 20:26:132216 pool_.get(),
2217 BoundNetLog()));
2218 EXPECT_EQ(ERR_IO_PENDING,
2219 handle_b[i].Init("b",
2220 params_,
2221 LOWEST,
[email protected]6ecf2b92011-12-15 01:14:522222 callback_b[i].callback(),
[email protected]2431756e2010-09-29 20:26:132223 pool_.get(),
2224 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542225 }
2226
2227 // Release b's socket first. The order is important, because in
2228 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2229 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2230 // first, which has a releasing socket, so it refuses to start up another
2231 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132232 handle_b[0].socket()->Disconnect();
2233 handle_b[0].Reset();
2234 handle_a[0].socket()->Disconnect();
2235 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542236
2237 // Used to get stuck here.
2238 MessageLoop::current()->RunAllPending();
2239
[email protected]2431756e2010-09-29 20:26:132240 handle_b[1].socket()->Disconnect();
2241 handle_b[1].Reset();
2242 handle_a[1].socket()->Disconnect();
2243 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542244
2245 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132246 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2247 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542248 }
2249}
2250
[email protected]fd4fe0b2010-02-08 23:02:152251TEST_F(ClientSocketPoolBaseTest,
2252 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2253 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2254
2255 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2256
2257 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2258 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2259 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2260 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2261
[email protected]2431756e2010-09-29 20:26:132262 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2263 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2264 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152265
2266 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132267 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2268 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152269
[email protected]2431756e2010-09-29 20:26:132270 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2271 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2272 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152273
2274 EXPECT_EQ(1, GetOrderOfRequest(1));
2275 EXPECT_EQ(2, GetOrderOfRequest(2));
2276 EXPECT_EQ(3, GetOrderOfRequest(3));
2277 EXPECT_EQ(4, GetOrderOfRequest(4));
2278
2279 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132280 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152281}
2282
[email protected]6ecf2b92011-12-15 01:14:522283class TestReleasingSocketRequest : public TestCompletionCallbackBase {
[email protected]4f1e4982010-03-02 18:31:042284 public:
[email protected]2431756e2010-09-29 20:26:132285 TestReleasingSocketRequest(TestClientSocketPool* pool,
2286 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182287 bool reset_releasing_handle)
2288 : pool_(pool),
2289 expected_result_(expected_result),
[email protected]6ecf2b92011-12-15 01:14:522290 reset_releasing_handle_(reset_releasing_handle),
2291 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2292 base::Bind(&TestReleasingSocketRequest::OnComplete,
2293 base::Unretained(this)))) {
2294 }
2295
2296 virtual ~TestReleasingSocketRequest() {}
[email protected]4f1e4982010-03-02 18:31:042297
2298 ClientSocketHandle* handle() { return &handle_; }
2299
[email protected]6ecf2b92011-12-15 01:14:522300 const CompletionCallback& callback() const { return callback_; }
[email protected]4f1e4982010-03-02 18:31:042301
2302 private:
[email protected]6ecf2b92011-12-15 01:14:522303 void OnComplete(int result) {
2304 SetResult(result);
2305 if (reset_releasing_handle_)
2306 handle_.Reset();
2307
2308 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
2309 EXPECT_EQ(expected_result_,
2310 handle2_.Init("a", con_params, kDefaultPriority,
2311 callback2_.callback(), pool_, BoundNetLog()));
2312 }
2313
[email protected]2431756e2010-09-29 20:26:132314 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182315 int expected_result_;
2316 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042317 ClientSocketHandle handle_;
2318 ClientSocketHandle handle2_;
[email protected]6ecf2b92011-12-15 01:14:522319 CompletionCallback callback_;
2320 TestCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042321};
2322
[email protected]e60e47a2010-07-14 03:37:182323
2324TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2326
2327 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2328 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2329 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2330
[email protected]2431756e2010-09-29 20:26:132331 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182332 client_socket_factory_.allocation_count());
2333
2334 connect_job_factory_->set_job_type(
2335 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2336 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132337 EXPECT_EQ(ERR_IO_PENDING,
[email protected]6ecf2b92011-12-15 01:14:522338 req.handle()->Init("a", params_, kDefaultPriority, req.callback(),
2339 pool_.get(), BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182340 // The next job should complete synchronously
2341 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2342
2343 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2344 EXPECT_FALSE(req.handle()->is_initialized());
2345 EXPECT_FALSE(req.handle()->socket());
2346 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432347 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182348}
2349
[email protected]b6501d3d2010-06-03 23:53:342350// http://crbug.com/44724 regression test.
2351// We start releasing the pool when we flush on network change. When that
2352// happens, the only active references are in the ClientSocketHandles. When a
2353// ConnectJob completes and calls back into the last ClientSocketHandle, that
2354// callback can release the last reference and delete the pool. After the
2355// callback finishes, we go back to the stack frame within the now-deleted pool.
2356// Executing any code that refers to members of the now-deleted pool can cause
2357// crashes.
2358TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2359 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2360 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2361
2362 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522363 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132364 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2365 params_,
2366 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522367 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132368 pool_.get(),
2369 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342370
[email protected]2431756e2010-09-29 20:26:132371 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342372
2373 // We'll call back into this now.
2374 callback.WaitForResult();
2375}
2376
[email protected]a7e38572010-06-07 18:22:242377TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2378 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2379 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2380
2381 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522382 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132383 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2384 params_,
2385 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522386 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132387 pool_.get(),
2388 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242389 EXPECT_EQ(OK, callback.WaitForResult());
2390 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2391
2392 pool_->Flush();
2393
2394 handle.Reset();
2395 MessageLoop::current()->RunAllPending();
2396
[email protected]2431756e2010-09-29 20:26:132397 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2398 params_,
2399 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522400 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132401 pool_.get(),
2402 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242403 EXPECT_EQ(OK, callback.WaitForResult());
2404 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2405}
2406
[email protected]6ecf2b92011-12-15 01:14:522407class ConnectWithinCallback : public TestCompletionCallbackBase {
[email protected]06f92462010-08-31 19:24:142408 public:
2409 ConnectWithinCallback(
2410 const std::string& group_name,
2411 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132412 TestClientSocketPool* pool)
[email protected]6ecf2b92011-12-15 01:14:522413 : group_name_(group_name),
2414 params_(params),
2415 pool_(pool),
2416 ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
2417 base::Bind(&ConnectWithinCallback::OnComplete,
2418 base::Unretained(this)))) {
[email protected]06f92462010-08-31 19:24:142419 }
2420
[email protected]6ecf2b92011-12-15 01:14:522421 virtual ~ConnectWithinCallback() {}
[email protected]06f92462010-08-31 19:24:142422
2423 int WaitForNestedResult() {
2424 return nested_callback_.WaitForResult();
2425 }
2426
[email protected]6ecf2b92011-12-15 01:14:522427 const CompletionCallback& callback() const { return callback_; }
2428
[email protected]06f92462010-08-31 19:24:142429 private:
[email protected]6ecf2b92011-12-15 01:14:522430 void OnComplete(int result) {
2431 SetResult(result);
2432 EXPECT_EQ(ERR_IO_PENDING,
2433 handle_.Init(group_name_,
2434 params_,
2435 kDefaultPriority,
2436 nested_callback_.callback(),
2437 pool_,
2438 BoundNetLog()));
2439 }
2440
[email protected]06f92462010-08-31 19:24:142441 const std::string group_name_;
2442 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132443 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142444 ClientSocketHandle handle_;
[email protected]6ecf2b92011-12-15 01:14:522445 CompletionCallback callback_;
2446 TestCompletionCallback nested_callback_;
2447
2448 DISALLOW_COPY_AND_ASSIGN(ConnectWithinCallback);
[email protected]06f92462010-08-31 19:24:142449};
2450
2451TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2452 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2453
2454 // First job will be waiting until it gets aborted.
2455 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2456
2457 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132458 ConnectWithinCallback callback("a", params_, pool_.get());
2459 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2460 params_,
2461 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522462 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132463 pool_.get(),
2464 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142465
2466 // Second job will be started during the first callback, and will
2467 // asynchronously complete with OK.
2468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2469 pool_->Flush();
2470 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2471 EXPECT_EQ(OK, callback.WaitForNestedResult());
2472}
2473
[email protected]25eea382010-07-10 23:55:262474// Cancel a pending socket request while we're at max sockets,
2475// and verify that the backup socket firing doesn't cause a crash.
2476TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2477 // Max 4 sockets globally, max 4 sockets per group.
2478 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222479 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262480
[email protected]4baaf9d2010-08-31 15:15:442481 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2482 // timer.
[email protected]25eea382010-07-10 23:55:262483 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2484 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522485 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132486 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2487 params_,
2488 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522489 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132490 pool_.get(),
2491 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262492
2493 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2494 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2495 ClientSocketHandle handles[kDefaultMaxSockets];
2496 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]6ecf2b92011-12-15 01:14:522497 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132498 EXPECT_EQ(OK, handles[i].Init("bar",
2499 params_,
2500 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522501 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132502 pool_.get(),
2503 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262504 }
2505
2506 MessageLoop::current()->RunAllPending();
2507
2508 // Cancel the pending request.
2509 handle.Reset();
2510
2511 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082512 base::PlatformThread::Sleep(
2513 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262514
2515 MessageLoop::current()->RunAllPending();
2516 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2517}
2518
[email protected]3f00be82010-09-27 19:50:022519TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442520 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2521 pool_->EnableConnectBackupJobs();
2522
2523 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2524 // timer.
2525 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2526 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522527 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132528 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2529 params_,
2530 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522531 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132532 pool_.get(),
2533 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442534 ASSERT_TRUE(pool_->HasGroup("bar"));
2535 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2536
2537 // Cancel the socket request. This should cancel the backup timer. Wait for
2538 // the backup time to see if it indeed got canceled.
2539 handle.Reset();
2540 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082541 base::PlatformThread::Sleep(
2542 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442543 MessageLoop::current()->RunAllPending();
2544 ASSERT_TRUE(pool_->HasGroup("bar"));
2545 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2546}
2547
[email protected]3f00be82010-09-27 19:50:022548TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2549 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2550 pool_->EnableConnectBackupJobs();
2551
2552 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2553 // timer.
2554 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2555 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:522556 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132557 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2558 params_,
2559 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522560 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132561 pool_.get(),
2562 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022563 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2564 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522565 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132566 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2567 params_,
2568 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522569 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132570 pool_.get(),
2571 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022572 ASSERT_TRUE(pool_->HasGroup("bar"));
2573 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2574
2575 // Cancel request 1 and then complete request 2. With the requests finished,
2576 // the backup timer should be cancelled.
2577 handle.Reset();
2578 EXPECT_EQ(OK, callback2.WaitForResult());
2579 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082580 base::PlatformThread::Sleep(
2581 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022582 MessageLoop::current()->RunAllPending();
2583}
2584
[email protected]eb5a99382010-07-11 03:18:262585// Test delayed socket binding for the case where we have two connects,
2586// and while one is waiting on a connect, the other frees up.
2587// The socket waiting on a connect should switch immediately to the freed
2588// up socket.
2589TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2590 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2591 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2592
2593 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522594 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132595 EXPECT_EQ(ERR_IO_PENDING,
2596 handle1.Init("a",
2597 params_,
2598 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522599 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132600 pool_.get(),
2601 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262602 EXPECT_EQ(OK, callback.WaitForResult());
2603
2604 // No idle sockets, no pending jobs.
2605 EXPECT_EQ(0, pool_->IdleSocketCount());
2606 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2607
2608 // Create a second socket to the same host, but this one will wait.
2609 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2610 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132611 EXPECT_EQ(ERR_IO_PENDING,
2612 handle2.Init("a",
2613 params_,
2614 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522615 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132616 pool_.get(),
2617 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262618 // No idle sockets, and one connecting job.
2619 EXPECT_EQ(0, pool_->IdleSocketCount());
2620 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2621
2622 // Return the first handle to the pool. This will initiate the delayed
2623 // binding.
2624 handle1.Reset();
2625
2626 MessageLoop::current()->RunAllPending();
2627
2628 // Still no idle sockets, still one pending connect job.
2629 EXPECT_EQ(0, pool_->IdleSocketCount());
2630 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2631
2632 // The second socket connected, even though it was a Waiting Job.
2633 EXPECT_EQ(OK, callback.WaitForResult());
2634
2635 // And we can see there is still one job waiting.
2636 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2637
2638 // Finally, signal the waiting Connect.
2639 client_socket_factory_.SignalJobs();
2640 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2641
2642 MessageLoop::current()->RunAllPending();
2643}
2644
2645// Test delayed socket binding when a group is at capacity and one
2646// of the group's sockets frees up.
2647TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2649 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2650
2651 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522652 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132653 EXPECT_EQ(ERR_IO_PENDING,
2654 handle1.Init("a",
2655 params_,
2656 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522657 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132658 pool_.get(),
2659 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262660 EXPECT_EQ(OK, callback.WaitForResult());
2661
2662 // No idle sockets, no pending jobs.
2663 EXPECT_EQ(0, pool_->IdleSocketCount());
2664 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2665
2666 // Create a second socket to the same host, but this one will wait.
2667 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2668 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132669 EXPECT_EQ(ERR_IO_PENDING,
2670 handle2.Init("a",
2671 params_,
2672 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522673 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132674 pool_.get(),
2675 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262676 // No idle sockets, and one connecting job.
2677 EXPECT_EQ(0, pool_->IdleSocketCount());
2678 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2679
2680 // Return the first handle to the pool. This will initiate the delayed
2681 // binding.
2682 handle1.Reset();
2683
2684 MessageLoop::current()->RunAllPending();
2685
2686 // Still no idle sockets, still one pending connect job.
2687 EXPECT_EQ(0, pool_->IdleSocketCount());
2688 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2689
2690 // The second socket connected, even though it was a Waiting Job.
2691 EXPECT_EQ(OK, callback.WaitForResult());
2692
2693 // And we can see there is still one job waiting.
2694 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2695
2696 // Finally, signal the waiting Connect.
2697 client_socket_factory_.SignalJobs();
2698 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2699
2700 MessageLoop::current()->RunAllPending();
2701}
2702
2703// Test out the case where we have one socket connected, one
2704// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512705// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262706// should complete, by taking the first socket's idle socket.
2707TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2708 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2709 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2710
2711 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522712 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132713 EXPECT_EQ(ERR_IO_PENDING,
2714 handle1.Init("a",
2715 params_,
2716 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522717 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132718 pool_.get(),
2719 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262720 EXPECT_EQ(OK, callback.WaitForResult());
2721
2722 // No idle sockets, no pending jobs.
2723 EXPECT_EQ(0, pool_->IdleSocketCount());
2724 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2725
2726 // Create a second socket to the same host, but this one will wait.
2727 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2728 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132729 EXPECT_EQ(ERR_IO_PENDING,
2730 handle2.Init("a",
2731 params_,
2732 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522733 callback.callback(),
[email protected]2431756e2010-09-29 20:26:132734 pool_.get(),
2735 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262736 // No idle sockets, and one connecting job.
2737 EXPECT_EQ(0, pool_->IdleSocketCount());
2738 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2739
2740 // Return the first handle to the pool. This will initiate the delayed
2741 // binding.
2742 handle1.Reset();
2743
2744 MessageLoop::current()->RunAllPending();
2745
2746 // Still no idle sockets, still one pending connect job.
2747 EXPECT_EQ(0, pool_->IdleSocketCount());
2748 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2749
2750 // The second socket connected, even though it was a Waiting Job.
2751 EXPECT_EQ(OK, callback.WaitForResult());
2752
2753 // And we can see there is still one job waiting.
2754 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2755
2756 // Finally, signal the waiting Connect.
2757 client_socket_factory_.SignalJobs();
2758 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2759
2760 MessageLoop::current()->RunAllPending();
2761}
2762
[email protected]2abfe90a2010-08-25 17:49:512763// Cover the case where on an available socket slot, we have one pending
2764// request that completes synchronously, thereby making the Group empty.
2765TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2766 const int kUnlimitedSockets = 100;
2767 const int kOneSocketPerGroup = 1;
2768 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2769
2770 // Make the first request asynchronous fail.
2771 // This will free up a socket slot later.
2772 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2773
2774 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522775 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132776 EXPECT_EQ(ERR_IO_PENDING,
2777 handle1.Init("a",
2778 params_,
2779 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522780 callback1.callback(),
[email protected]2431756e2010-09-29 20:26:132781 pool_.get(),
2782 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512783 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2784
2785 // Make the second request synchronously fail. This should make the Group
2786 // empty.
2787 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2788 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522789 TestCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512790 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2791 // when created.
[email protected]2431756e2010-09-29 20:26:132792 EXPECT_EQ(ERR_IO_PENDING,
2793 handle2.Init("a",
2794 params_,
2795 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522796 callback2.callback(),
[email protected]2431756e2010-09-29 20:26:132797 pool_.get(),
2798 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512799
2800 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2801
2802 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2803 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2804 EXPECT_FALSE(pool_->HasGroup("a"));
2805}
2806
[email protected]e1b54dc2010-10-06 21:27:222807TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2808 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2809
2810 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2811
2812 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522813 TestCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222814 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2815 params_,
2816 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522817 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222818 pool_.get(),
2819 BoundNetLog()));
2820
2821 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522822 TestCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222823 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2824 params_,
2825 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522826 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222827 pool_.get(),
2828 BoundNetLog()));
2829 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522830 TestCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222831 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2832 params_,
2833 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522834 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222835 pool_.get(),
2836 BoundNetLog()));
2837
2838 EXPECT_EQ(OK, callback1.WaitForResult());
2839 EXPECT_EQ(OK, callback2.WaitForResult());
2840 EXPECT_EQ(OK, callback3.WaitForResult());
2841
2842 // Use the socket.
[email protected]83039bb2011-12-09 18:43:552843 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, CompletionCallback()));
2844 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, CompletionCallback()));
[email protected]e1b54dc2010-10-06 21:27:222845
2846 handle1.Reset();
2847 handle2.Reset();
2848 handle3.Reset();
2849
2850 EXPECT_EQ(OK, handle1.Init("a",
2851 params_,
2852 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522853 callback1.callback(),
[email protected]e1b54dc2010-10-06 21:27:222854 pool_.get(),
2855 BoundNetLog()));
2856 EXPECT_EQ(OK, handle2.Init("a",
2857 params_,
2858 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522859 callback2.callback(),
[email protected]e1b54dc2010-10-06 21:27:222860 pool_.get(),
2861 BoundNetLog()));
2862 EXPECT_EQ(OK, handle3.Init("a",
2863 params_,
2864 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522865 callback3.callback(),
[email protected]e1b54dc2010-10-06 21:27:222866 pool_.get(),
2867 BoundNetLog()));
2868
2869 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2870 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2871 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2872}
2873
[email protected]2c2bef152010-10-13 00:55:032874TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2875 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2876 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2877
2878 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2879
2880 ASSERT_TRUE(pool_->HasGroup("a"));
2881 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2882 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2883
2884 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522885 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032886 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2887 params_,
2888 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522889 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032890 pool_.get(),
2891 BoundNetLog()));
2892
2893 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522894 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032895 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2896 params_,
2897 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522898 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:032899 pool_.get(),
2900 BoundNetLog()));
2901
2902 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2903 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2904
2905 EXPECT_EQ(OK, callback1.WaitForResult());
2906 EXPECT_EQ(OK, callback2.WaitForResult());
2907 handle1.Reset();
2908 handle2.Reset();
2909
2910 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2911 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2912}
2913
2914TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2916 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2917
2918 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522919 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032920 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2921 params_,
2922 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522923 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032924 pool_.get(),
2925 BoundNetLog()));
2926
2927 ASSERT_TRUE(pool_->HasGroup("a"));
2928 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2929 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2930
2931 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2932
2933 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2934 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2935
2936 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522937 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032938 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2939 params_,
2940 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522941 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:032942 pool_.get(),
2943 BoundNetLog()));
2944
2945 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2946 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2947
2948 EXPECT_EQ(OK, callback1.WaitForResult());
2949 EXPECT_EQ(OK, callback2.WaitForResult());
2950 handle1.Reset();
2951 handle2.Reset();
2952
2953 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2954 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2955}
2956
2957TEST_F(ClientSocketPoolBaseTest,
2958 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2959 CreatePool(4, 4);
2960 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2961
2962 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:522963 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032964 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2965 params_,
2966 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522967 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:032968 pool_.get(),
2969 BoundNetLog()));
2970
2971 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:522972 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032973 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2974 params_,
2975 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522976 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:032977 pool_.get(),
2978 BoundNetLog()));
2979
2980 ClientSocketHandle handle3;
[email protected]6ecf2b92011-12-15 01:14:522981 TestCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:032982 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2983 params_,
2984 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:522985 callback3.callback(),
[email protected]2c2bef152010-10-13 00:55:032986 pool_.get(),
2987 BoundNetLog()));
2988
2989 ASSERT_TRUE(pool_->HasGroup("a"));
2990 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2991 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2992
2993 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2994
2995 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2996 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2997
2998 EXPECT_EQ(OK, callback1.WaitForResult());
2999 EXPECT_EQ(OK, callback2.WaitForResult());
3000 EXPECT_EQ(OK, callback3.WaitForResult());
3001 handle1.Reset();
3002 handle2.Reset();
3003 handle3.Reset();
3004
3005 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3006 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
3007}
3008
3009TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
3010 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3011 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3012
3013 ASSERT_FALSE(pool_->HasGroup("a"));
3014
3015 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3016 BoundNetLog());
3017
3018 ASSERT_TRUE(pool_->HasGroup("a"));
3019 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3020
3021 ASSERT_FALSE(pool_->HasGroup("b"));
3022
3023 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3024 BoundNetLog());
3025
3026 ASSERT_FALSE(pool_->HasGroup("b"));
3027}
3028
3029TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3030 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3032
3033 ASSERT_FALSE(pool_->HasGroup("a"));
3034
3035 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3036 BoundNetLog());
3037
3038 ASSERT_TRUE(pool_->HasGroup("a"));
3039 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3040
3041 ASSERT_FALSE(pool_->HasGroup("b"));
3042
3043 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3044 BoundNetLog());
3045
3046 ASSERT_TRUE(pool_->HasGroup("b"));
3047 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3048}
3049
3050TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3051 CreatePool(4, 4);
3052 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3053
3054 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523055 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033056 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3057 params_,
3058 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523059 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033060 pool_.get(),
3061 BoundNetLog()));
3062 ASSERT_EQ(OK, callback1.WaitForResult());
3063 handle1.Reset();
3064
3065 ASSERT_TRUE(pool_->HasGroup("a"));
3066 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3067 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3068
3069 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3070
3071 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3072 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3073}
3074
3075TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3076 CreatePool(4, 4);
3077 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3078
3079 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523080 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033081 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3082 params_,
3083 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523084 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033085 pool_.get(),
3086 BoundNetLog()));
3087 ASSERT_EQ(OK, callback1.WaitForResult());
3088
3089 ASSERT_TRUE(pool_->HasGroup("a"));
3090 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3091 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3092 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3093
3094 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3095
3096 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3097 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3098 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3099}
3100
3101TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3102 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3103 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3104
3105 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3106 BoundNetLog());
3107
3108 ASSERT_TRUE(pool_->HasGroup("a"));
3109 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3110 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3111
3112 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3113 BoundNetLog());
3114
3115 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3116 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3117}
3118
[email protected]3c819f522010-12-02 02:03:123119TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3120 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3121 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3122
3123 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3124 BoundNetLog());
3125
3126 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523127
3128 connect_job_factory_->set_job_type(
3129 TestConnectJob::kMockAdditionalErrorStateJob);
3130 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3131 BoundNetLog());
3132
3133 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123134}
3135
[email protected]2c2bef152010-10-13 00:55:033136TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3137 CreatePool(4, 4);
3138 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3139
3140 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3141
3142 ASSERT_TRUE(pool_->HasGroup("a"));
3143 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3144 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3145
3146 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3147 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3148 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3149
3150 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523151 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033152 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3153 params_,
3154 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523155 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033156 pool_.get(),
3157 BoundNetLog()));
3158 ASSERT_EQ(OK, callback1.WaitForResult());
3159
3160 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523161 TestCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033162 int rv = handle2.Init("a",
3163 params_,
3164 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523165 callback2.callback(),
[email protected]2c2bef152010-10-13 00:55:033166 pool_.get(),
3167 BoundNetLog());
3168 if (rv != OK) {
3169 EXPECT_EQ(ERR_IO_PENDING, rv);
3170 EXPECT_EQ(OK, callback2.WaitForResult());
3171 }
3172
3173 handle1.Reset();
3174 handle2.Reset();
3175
3176 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3177
3178 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3179 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3180 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3181}
3182
3183TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3184 CreatePool(4, 4);
3185 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3186
3187 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3188
3189 ASSERT_TRUE(pool_->HasGroup("a"));
3190 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3191 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3192
3193 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3194 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3195 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3196
3197 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3198 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3199 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3200
3201 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3202 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3203 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3204}
3205
3206TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3207 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3208 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3209
3210 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3211
3212 ASSERT_TRUE(pool_->HasGroup("a"));
3213 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3214 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3215
3216 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523217 TestCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033218 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3219 params_,
3220 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523221 callback1.callback(),
[email protected]2c2bef152010-10-13 00:55:033222 pool_.get(),
3223 BoundNetLog()));
3224
3225 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3226 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3227
3228 ASSERT_EQ(OK, callback1.WaitForResult());
3229
3230 handle1.Reset();
3231
3232 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3233}
3234
[email protected]dcbe168a2010-12-02 03:14:463235// http://crbug.com/64940 regression test.
3236TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3237 const int kMaxTotalSockets = 3;
3238 const int kMaxSocketsPerGroup = 2;
3239 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3240 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3241
3242 // Note that group name ordering matters here. "a" comes before "b", so
3243 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3244
3245 // Set up one idle socket in "a".
3246 ClientSocketHandle handle1;
[email protected]6ecf2b92011-12-15 01:14:523247 TestCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463248 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3249 params_,
3250 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523251 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463252 pool_.get(),
3253 BoundNetLog()));
3254
3255 ASSERT_EQ(OK, callback1.WaitForResult());
3256 handle1.Reset();
3257 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3258
3259 // Set up two active sockets in "b".
3260 ClientSocketHandle handle2;
[email protected]6ecf2b92011-12-15 01:14:523261 TestCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463262 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3263 params_,
3264 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523265 callback1.callback(),
[email protected]dcbe168a2010-12-02 03:14:463266 pool_.get(),
3267 BoundNetLog()));
3268 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3269 params_,
3270 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523271 callback2.callback(),
[email protected]dcbe168a2010-12-02 03:14:463272 pool_.get(),
3273 BoundNetLog()));
3274
3275 ASSERT_EQ(OK, callback1.WaitForResult());
3276 ASSERT_EQ(OK, callback2.WaitForResult());
3277 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3278 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3279
3280 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3281 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3282 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3283 // sockets for "a", and "b" should still have 2 active sockets.
3284
3285 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3286 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3287 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3288 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3289 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3290 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3291 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3292
3293 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3294 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3295 // "a" should result in closing 1 for "b".
3296 handle1.Reset();
3297 handle2.Reset();
3298 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3299 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3300
3301 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3302 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3303 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3304 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3305 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3306 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3307 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3308}
3309
[email protected]b7b8be42011-07-12 12:46:413310TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073311 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3312 pool_->EnableConnectBackupJobs();
3313
3314 // Make the ConnectJob hang until it times out, shorten the timeout.
3315 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3316 connect_job_factory_->set_timeout_duration(
3317 base::TimeDelta::FromMilliseconds(500));
3318 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3319 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3320 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073321
[email protected]b7b8be42011-07-12 12:46:413322 // Verify the backup timer doesn't create a backup job, by making
3323 // the backup job a pending job instead of a waiting job, so it
3324 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073325 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413326 MessageLoop::current()->PostDelayedTask(FROM_HERE,
[email protected]72d27ce2011-12-09 00:41:123327 MessageLoop::QuitClosure(), 1000);
[email protected]b7b8be42011-07-12 12:46:413328 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073329 EXPECT_FALSE(pool_->HasGroup("a"));
3330}
3331
[email protected]b7b8be42011-07-12 12:46:413332TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073333 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3334 pool_->EnableConnectBackupJobs();
3335
3336 // Make the ConnectJob hang forever.
3337 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3338 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3339 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3340 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3341 MessageLoop::current()->RunAllPending();
3342
3343 // Make the backup job be a pending job, so it completes normally.
3344 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3345 ClientSocketHandle handle;
[email protected]6ecf2b92011-12-15 01:14:523346 TestCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073347 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3348 params_,
3349 kDefaultPriority,
[email protected]6ecf2b92011-12-15 01:14:523350 callback.callback(),
[email protected]a9fc8fc2011-05-10 02:41:073351 pool_.get(),
3352 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413353 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073354 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3355 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3356 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3357 ASSERT_EQ(OK, callback.WaitForResult());
3358
3359 // The hung connect job should still be there, but everything else should be
3360 // complete.
3361 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3362 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3363 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3364}
3365
[email protected]f6d1d6eb2009-06-24 20:16:093366} // namespace
3367
3368} // namespace net