blob: 820b0308eb01e873c8e2682c0caa12428b1fe3f4 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]43a21b82010-06-10 21:30:5414#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0615#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5316#include "net/base/net_log.h"
17#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "testing/gtest/include/gtest/gtest.h"
28
29namespace net {
30
31namespace {
32
[email protected]211d21722009-07-22 15:48:5333const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2034const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5235const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0136
[email protected]df4b4ef2010-07-12 18:25:2137class TestSocketParams : public base::RefCounted<TestSocketParams> {
38 private:
39 friend class base::RefCounted<TestSocketParams>;
40 ~TestSocketParams() {}
41};
[email protected]7fc5b09a2010-02-27 00:07:3842typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4943
[email protected]f6d1d6eb2009-06-24 20:16:0944class MockClientSocket : public ClientSocket {
45 public:
[email protected]0f873e82010-09-02 16:09:0146 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0947
[email protected]ab838892009-06-30 18:49:0548 // Socket methods:
49 virtual int Read(
50 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
51 return ERR_UNEXPECTED;
52 }
53
54 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0155 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
56 was_used_to_convey_data_ = true;
57 return len;
[email protected]ab838892009-06-30 18:49:0558 }
[email protected]06650c52010-06-03 00:49:1759 virtual bool SetReceiveBufferSize(int32 size) { return true; }
60 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0561
[email protected]f6d1d6eb2009-06-24 20:16:0962 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0563
[email protected]a2006ece2010-04-23 16:44:0264 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0965 connected_ = true;
66 return OK;
67 }
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]ab838892009-06-30 18:49:0569 virtual void Disconnect() { connected_ = false; }
70 virtual bool IsConnected() const { return connected_; }
71 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0172
[email protected]ac9eec62010-02-20 18:50:3873 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1674 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0975 }
[email protected]f6d1d6eb2009-06-24 20:16:0976
[email protected]a2006ece2010-04-23 16:44:0277 virtual const BoundNetLog& NetLog() const {
78 return net_log_;
79 }
80
[email protected]9b5614a2010-08-25 20:29:4581 virtual void SetSubresourceSpeculation() {}
82 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0183 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]9b5614a2010-08-25 20:29:4584
[email protected]f6d1d6eb2009-06-24 20:16:0985 private:
86 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0287 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0188 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0989
[email protected]ab838892009-06-30 18:49:0590 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0991};
92
[email protected]5fc08e32009-07-15 17:09:5793class TestConnectJob;
94
[email protected]f6d1d6eb2009-06-24 20:16:0995class MockClientSocketFactory : public ClientSocketFactory {
96 public:
[email protected]ab838892009-06-30 18:49:0597 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0998
[email protected]0a0b7682010-08-25 17:08:0799 virtual ClientSocket* CreateTCPClientSocket(
100 const AddressList& addresses,
101 NetLog* /* net_log */,
102 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09103 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05104 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09105 }
106
107 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18108 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:09109 const std::string& hostname,
[email protected]7ab5bbd12010-10-19 13:33:21110 const SSLConfig& ssl_config,
111 SSLHostInfo* ssl_host_info) {
[email protected]f6d1d6eb2009-06-24 20:16:09112 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21113 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09114 return NULL;
115 }
116
[email protected]5fc08e32009-07-15 17:09:57117 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
118 void SignalJobs();
119
[email protected]f6d1d6eb2009-06-24 20:16:09120 int allocation_count() const { return allocation_count_; }
121
[email protected]f6d1d6eb2009-06-24 20:16:09122 private:
123 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57124 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09125};
126
[email protected]ab838892009-06-30 18:49:05127class TestConnectJob : public ConnectJob {
128 public:
129 enum JobType {
130 kMockJob,
131 kMockFailingJob,
132 kMockPendingJob,
133 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57134 kMockWaitingJob,
135 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13136 kMockRecoverableJob,
137 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18138 kMockAdditionalErrorStateJob,
139 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05140 };
141
[email protected]994d4932010-07-12 17:55:13142 // The kMockPendingJob uses a slight delay before allowing the connect
143 // to complete.
144 static const int kPendingConnectDelay = 2;
145
[email protected]ab838892009-06-30 18:49:05146 TestConnectJob(JobType job_type,
147 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49148 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34149 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05150 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30151 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17152 NetLog* net_log)
153 : ConnectJob(group_name, timeout_duration, delegate,
154 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58155 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05156 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21157 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18158 load_state_(LOAD_STATE_IDLE),
159 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05160
[email protected]974ebd62009-08-03 23:14:34161 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13162 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34163 }
164
[email protected]46451352009-09-01 14:54:21165 virtual LoadState GetLoadState() const { return load_state_; }
166
[email protected]e60e47a2010-07-14 03:37:18167 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
168 if (store_additional_error_state_) {
169 // Set all of the additional error state fields in some way.
170 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43171 HttpResponseInfo info;
172 info.headers = new HttpResponseHeaders("");
173 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18174 }
175 }
176
[email protected]974ebd62009-08-03 23:14:34177 private:
[email protected]ab838892009-06-30 18:49:05178 // ConnectJob methods:
179
[email protected]974ebd62009-08-03 23:14:34180 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05181 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07182 client_socket_factory_->CreateTCPClientSocket(
183 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40184 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05185 switch (job_type_) {
186 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13187 return DoConnect(true /* successful */, false /* sync */,
188 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05189 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13190 return DoConnect(false /* error */, false /* sync */,
191 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05192 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57193 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47194
195 // Depending on execution timings, posting a delayed task can result
196 // in the task getting executed the at the earliest possible
197 // opportunity or only after returning once from the message loop and
198 // then a second call into the message loop. In order to make behavior
199 // more deterministic, we change the default delay to 2ms. This should
200 // always require us to wait for the second call into the message loop.
201 //
202 // N.B. The correct fix for this and similar timing problems is to
203 // abstract time for the purpose of unittests. Unfortunately, we have
204 // a lot of third-party components that directly call the various
205 // time functions, so this change would be rather invasive.
206 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05207 FROM_HERE,
208 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47209 &TestConnectJob::DoConnect,
210 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13211 true /* async */,
212 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13213 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05214 return ERR_IO_PENDING;
215 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57216 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47217 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05218 FROM_HERE,
219 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47220 &TestConnectJob::DoConnect,
221 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13222 true /* async */,
223 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47224 2);
[email protected]ab838892009-06-30 18:49:05225 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57226 case kMockWaitingJob:
227 client_socket_factory_->WaitForSignal(this);
228 waiting_success_ = true;
229 return ERR_IO_PENDING;
230 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46231 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57232 FROM_HERE,
233 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46234 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57235 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13236 case kMockRecoverableJob:
237 return DoConnect(false /* error */, false /* sync */,
238 true /* recoverable */);
239 case kMockPendingRecoverableJob:
240 set_load_state(LOAD_STATE_CONNECTING);
241 MessageLoop::current()->PostDelayedTask(
242 FROM_HERE,
243 method_factory_.NewRunnableMethod(
244 &TestConnectJob::DoConnect,
245 false /* error */,
246 true /* async */,
247 true /* recoverable */),
248 2);
249 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18250 case kMockAdditionalErrorStateJob:
251 store_additional_error_state_ = true;
252 return DoConnect(false /* error */, false /* sync */,
253 false /* recoverable */);
254 case kMockPendingAdditionalErrorStateJob:
255 set_load_state(LOAD_STATE_CONNECTING);
256 store_additional_error_state_ = true;
257 MessageLoop::current()->PostDelayedTask(
258 FROM_HERE,
259 method_factory_.NewRunnableMethod(
260 &TestConnectJob::DoConnect,
261 false /* error */,
262 true /* async */,
263 false /* recoverable */),
264 2);
265 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05266 default:
267 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40268 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05269 return ERR_FAILED;
270 }
271 }
272
[email protected]46451352009-09-01 14:54:21273 void set_load_state(LoadState load_state) { load_state_ = load_state; }
274
[email protected]e772db3f2010-07-12 18:11:13275 int DoConnect(bool succeed, bool was_async, bool recoverable) {
276 int result = OK;
[email protected]ab838892009-06-30 18:49:05277 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02278 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13279 } else if (recoverable) {
280 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40281 } else {
[email protected]e772db3f2010-07-12 18:11:13282 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40283 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05284 }
[email protected]2ab05b52009-07-01 23:57:58285
286 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30287 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05288 return result;
289 }
290
[email protected]cfa8228c2010-06-17 01:07:56291 // This function helps simulate the progress of load states on a ConnectJob.
292 // Each time it is called it advances the load state and posts a task to be
293 // called again. It stops at the last connecting load state (the one
294 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57295 void AdvanceLoadState(LoadState state) {
296 int tmp = state;
297 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56298 if (tmp < LOAD_STATE_SENDING_REQUEST) {
299 state = static_cast<LoadState>(tmp);
300 set_load_state(state);
301 MessageLoop::current()->PostTask(
302 FROM_HERE,
303 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
304 state));
305 }
[email protected]5fc08e32009-07-15 17:09:57306 }
307
308 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05309 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57310 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05311 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21312 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18313 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05314
315 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
316};
317
[email protected]d80a4322009-08-14 07:07:49318class TestConnectJobFactory
319 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05320 public:
[email protected]5fc08e32009-07-15 17:09:57321 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05322 : job_type_(TestConnectJob::kMockJob),
323 client_socket_factory_(client_socket_factory) {}
324
325 virtual ~TestConnectJobFactory() {}
326
327 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
328
[email protected]974ebd62009-08-03 23:14:34329 void set_timeout_duration(base::TimeDelta timeout_duration) {
330 timeout_duration_ = timeout_duration;
331 }
332
[email protected]ab838892009-06-30 18:49:05333 // ConnectJobFactory methods:
334
335 virtual ConnectJob* NewConnectJob(
336 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49337 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17338 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05339 return new TestConnectJob(job_type_,
340 group_name,
341 request,
[email protected]974ebd62009-08-03 23:14:34342 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05343 delegate,
[email protected]fd7b7c92009-08-20 19:38:30344 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17345 NULL);
[email protected]ab838892009-06-30 18:49:05346 }
347
[email protected]a796bcec2010-03-22 17:17:26348 virtual base::TimeDelta ConnectionTimeout() const {
349 return timeout_duration_;
350 }
351
[email protected]ab838892009-06-30 18:49:05352 private:
353 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34354 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57355 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05356
357 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
358};
359
360class TestClientSocketPool : public ClientSocketPool {
361 public:
362 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53363 int max_sockets,
[email protected]ab838892009-06-30 18:49:05364 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13365 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16366 base::TimeDelta unused_idle_socket_timeout,
367 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49368 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00369 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16370 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38371 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05372
[email protected]2431756e2010-09-29 20:26:13373 virtual ~TestClientSocketPool() {}
374
[email protected]ab838892009-06-30 18:49:05375 virtual int RequestSocket(
376 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49377 const void* params,
[email protected]ac790b42009-12-02 04:31:31378 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05379 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46380 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53381 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21382 const scoped_refptr<TestSocketParams>* casted_socket_params =
383 static_cast<const scoped_refptr<TestSocketParams>*>(params);
384 return base_.RequestSocket(group_name, *casted_socket_params, priority,
385 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05386 }
387
[email protected]2c2bef152010-10-13 00:55:03388 virtual void RequestSockets(const std::string& group_name,
389 const void* params,
390 int num_sockets,
391 const BoundNetLog& net_log) {
392 const scoped_refptr<TestSocketParams>* casted_params =
393 static_cast<const scoped_refptr<TestSocketParams>*>(params);
394
395 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
396 }
397
[email protected]ab838892009-06-30 18:49:05398 virtual void CancelRequest(
399 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21400 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49401 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05402 }
403
404 virtual void ReleaseSocket(
405 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24406 ClientSocket* socket,
407 int id) {
408 base_.ReleaseSocket(group_name, socket, id);
409 }
410
411 virtual void Flush() {
412 base_.Flush();
[email protected]ab838892009-06-30 18:49:05413 }
414
415 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49416 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05417 }
418
[email protected]d80a4322009-08-14 07:07:49419 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05420
421 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49422 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05423 }
424
425 virtual LoadState GetLoadState(const std::string& group_name,
426 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49427 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05428 }
429
[email protected]ba00b492010-09-08 14:53:38430 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
431 const std::string& type,
432 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27433 return base_.GetInfoAsValue(name, type);
434 }
435
[email protected]a796bcec2010-03-22 17:17:26436 virtual base::TimeDelta ConnectionTimeout() const {
437 return base_.ConnectionTimeout();
438 }
439
[email protected]2431756e2010-09-29 20:26:13440 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00441 return base_.histograms();
442 }
[email protected]a796bcec2010-03-22 17:17:26443
[email protected]d80a4322009-08-14 07:07:49444 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20445
[email protected]974ebd62009-08-03 23:14:34446 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49447 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34448 }
449
[email protected]2c2bef152010-10-13 00:55:03450 int NumActiveSocketsInGroup(const std::string& group_name) const {
451 return base_.NumActiveSocketsInGroup(group_name);
452 }
453
[email protected]2abfe90a2010-08-25 17:49:51454 bool HasGroup(const std::string& group_name) const {
455 return base_.HasGroup(group_name);
456 }
457
[email protected]9bf28db2009-08-29 01:35:16458 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
459
[email protected]06d94042010-08-25 01:45:22460 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54461
[email protected]ab838892009-06-30 18:49:05462 private:
[email protected]d80a4322009-08-14 07:07:49463 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05464
465 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
466};
467
[email protected]a937a06d2009-08-19 21:19:24468} // namespace
469
[email protected]7fc5b09a2010-02-27 00:07:38470REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24471
472namespace {
473
[email protected]5fc08e32009-07-15 17:09:57474void MockClientSocketFactory::SignalJobs() {
475 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
476 it != waiting_jobs_.end(); ++it) {
477 (*it)->Signal();
478 }
479 waiting_jobs_.clear();
480}
481
[email protected]974ebd62009-08-03 23:14:34482class TestConnectJobDelegate : public ConnectJob::Delegate {
483 public:
484 TestConnectJobDelegate()
485 : have_result_(false), waiting_for_result_(false), result_(OK) {}
486 virtual ~TestConnectJobDelegate() {}
487
488 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
489 result_ = result;
[email protected]6e713f02009-08-06 02:56:40490 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07491 // socket.get() should be NULL iff result != OK
492 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34493 delete job;
494 have_result_ = true;
495 if (waiting_for_result_)
496 MessageLoop::current()->Quit();
497 }
498
499 int WaitForResult() {
500 DCHECK(!waiting_for_result_);
501 while (!have_result_) {
502 waiting_for_result_ = true;
503 MessageLoop::current()->Run();
504 waiting_for_result_ = false;
505 }
506 have_result_ = false; // auto-reset for next callback
507 return result_;
508 }
509
510 private:
511 bool have_result_;
512 bool waiting_for_result_;
513 int result_;
514};
515
[email protected]2431756e2010-09-29 20:26:13516class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09517 protected:
[email protected]b89f7e42010-05-20 20:37:00518 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21519 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13520 histograms_("ClientSocketPoolTest") {}
521
522 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20523
[email protected]211d21722009-07-22 15:48:53524 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16525 CreatePoolWithIdleTimeouts(
526 max_sockets,
527 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00528 base::TimeDelta::FromSeconds(
529 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16530 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
531 }
532
533 void CreatePoolWithIdleTimeouts(
534 int max_sockets, int max_sockets_per_group,
535 base::TimeDelta unused_idle_socket_timeout,
536 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20537 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04538 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13539 pool_.reset(new TestClientSocketPool(max_sockets,
540 max_sockets_per_group,
541 &histograms_,
542 unused_idle_socket_timeout,
543 used_idle_socket_timeout,
544 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20545 }
[email protected]f6d1d6eb2009-06-24 20:16:09546
[email protected]ac790b42009-12-02 04:31:31547 int StartRequest(const std::string& group_name,
548 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13549 return test_base_.StartRequestUsingPool<
550 TestClientSocketPool, TestSocketParams>(
551 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09552 }
553
[email protected]2431756e2010-09-29 20:26:13554 int GetOrderOfRequest(size_t index) const {
555 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09556 }
557
[email protected]2431756e2010-09-29 20:26:13558 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
559 return test_base_.ReleaseOneConnection(keep_alive);
560 }
561
562 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
563 test_base_.ReleaseAllConnections(keep_alive);
564 }
565
566 TestSocketRequest* request(int i) { return test_base_.request(i); }
567 size_t requests_size() const { return test_base_.requests_size(); }
568 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
569 size_t completion_count() const { return test_base_.completion_count(); }
570
[email protected]f6d1d6eb2009-06-24 20:16:09571 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04572 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21573 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13574 ClientSocketPoolHistograms histograms_;
575 scoped_ptr<TestClientSocketPool> pool_;
576 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09577};
578
[email protected]974ebd62009-08-03 23:14:34579// Even though a timeout is specified, it doesn't time out on a synchronous
580// completion.
581TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
582 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06583 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49584 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03585 &ignored, NULL, kDefaultPriority,
586 internal::ClientSocketPoolBaseHelper::NORMAL,
587 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34588 scoped_ptr<TestConnectJob> job(
589 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12590 "a",
[email protected]974ebd62009-08-03 23:14:34591 request,
592 base::TimeDelta::FromMicroseconds(1),
593 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30594 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17595 NULL));
[email protected]974ebd62009-08-03 23:14:34596 EXPECT_EQ(OK, job->Connect());
597}
598
599TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
600 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06601 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17602 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53603
[email protected]d80a4322009-08-14 07:07:49604 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03605 &ignored, NULL, kDefaultPriority,
606 internal::ClientSocketPoolBaseHelper::NORMAL,
607 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34608 // Deleted by TestConnectJobDelegate.
609 TestConnectJob* job =
610 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12611 "a",
[email protected]974ebd62009-08-03 23:14:34612 request,
613 base::TimeDelta::FromMicroseconds(1),
614 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30615 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17616 &log);
[email protected]974ebd62009-08-03 23:14:34617 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
618 PlatformThread::Sleep(1);
619 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30620
[email protected]06650c52010-06-03 00:49:17621 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46622 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53623 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17624 EXPECT_TRUE(LogContainsBeginEvent(
625 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46626 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17627 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
628 NetLog::PHASE_NONE));
629 EXPECT_TRUE(LogContainsEvent(
630 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53631 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46632 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17633 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
634 EXPECT_TRUE(LogContainsEndEvent(
635 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34636}
637
[email protected]5fc08e32009-07-15 17:09:57638TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53639 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20640
[email protected]f6d1d6eb2009-06-24 20:16:09641 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06642 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53643 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
644
[email protected]2431756e2010-09-29 20:26:13645 EXPECT_EQ(OK,
646 handle.Init("a",
647 params_,
648 kDefaultPriority,
649 &callback,
650 pool_.get(),
651 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09652 EXPECT_TRUE(handle.is_initialized());
653 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09654 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30655
[email protected]06650c52010-06-03 00:49:17656 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46657 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53658 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53659 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17660 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
661 NetLog::PHASE_NONE));
662 EXPECT_TRUE(LogContainsEvent(
663 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53664 NetLog::PHASE_NONE));
665 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17666 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09667}
668
[email protected]ab838892009-06-30 18:49:05669TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53670 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20671
[email protected]ab838892009-06-30 18:49:05672 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53673 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
674
[email protected]2431756e2010-09-29 20:26:13675 ClientSocketHandle handle;
676 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18677 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13678 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43679 HttpResponseInfo info;
680 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13681 handle.set_ssl_error_response_info(info);
682 EXPECT_EQ(ERR_CONNECTION_FAILED,
683 handle.Init("a",
684 params_,
685 kDefaultPriority,
686 &callback,
687 pool_.get(),
688 log.bound()));
689 EXPECT_FALSE(handle.socket());
690 EXPECT_FALSE(handle.is_ssl_error());
691 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30692
[email protected]06650c52010-06-03 00:49:17693 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27694 EXPECT_TRUE(LogContainsBeginEvent(
695 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17696 EXPECT_TRUE(LogContainsEvent(
697 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
698 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02699 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17700 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09701}
702
[email protected]211d21722009-07-22 15:48:53703TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
704 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
705
[email protected]9e743cd2010-03-16 07:03:53706 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30707
[email protected]211d21722009-07-22 15:48:53708 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
709 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
710 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
711 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
712
[email protected]2431756e2010-09-29 20:26:13713 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53714 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13715 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53716
717 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
719 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
720
[email protected]2431756e2010-09-29 20:26:13721 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53722
[email protected]2431756e2010-09-29 20:26:13723 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53724 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13725 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53726
727 EXPECT_EQ(1, GetOrderOfRequest(1));
728 EXPECT_EQ(2, GetOrderOfRequest(2));
729 EXPECT_EQ(3, GetOrderOfRequest(3));
730 EXPECT_EQ(4, GetOrderOfRequest(4));
731 EXPECT_EQ(5, GetOrderOfRequest(5));
732 EXPECT_EQ(6, GetOrderOfRequest(6));
733 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17734
735 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13736 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53737}
738
739TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
741
[email protected]9e743cd2010-03-16 07:03:53742 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30743
[email protected]211d21722009-07-22 15:48:53744 // Reach all limits: max total sockets, and max sockets per group.
745 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
746 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
747 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
748 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
749
[email protected]2431756e2010-09-29 20:26:13750 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53751 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13752 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53753
754 // Now create a new group and verify that we don't starve it.
755 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
756
[email protected]2431756e2010-09-29 20:26:13757 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53758
[email protected]2431756e2010-09-29 20:26:13759 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53760 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13761 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53762
763 EXPECT_EQ(1, GetOrderOfRequest(1));
764 EXPECT_EQ(2, GetOrderOfRequest(2));
765 EXPECT_EQ(3, GetOrderOfRequest(3));
766 EXPECT_EQ(4, GetOrderOfRequest(4));
767 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17768
769 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13770 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53771}
772
773TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
774 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
775
[email protected]ac790b42009-12-02 04:31:31776 EXPECT_EQ(OK, StartRequest("b", LOWEST));
777 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
778 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
779 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53780
[email protected]2431756e2010-09-29 20:26:13781 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53782 client_socket_factory_.allocation_count());
783
[email protected]ac790b42009-12-02 04:31:31784 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53787
[email protected]2431756e2010-09-29 20:26:13788 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53789
[email protected]2431756e2010-09-29 20:26:13790 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53791
792 // First 4 requests don't have to wait, and finish in order.
793 EXPECT_EQ(1, GetOrderOfRequest(1));
794 EXPECT_EQ(2, GetOrderOfRequest(2));
795 EXPECT_EQ(3, GetOrderOfRequest(3));
796 EXPECT_EQ(4, GetOrderOfRequest(4));
797
[email protected]ac790b42009-12-02 04:31:31798 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
799 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53800 EXPECT_EQ(7, GetOrderOfRequest(5));
801 EXPECT_EQ(6, GetOrderOfRequest(6));
802 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17803
804 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13805 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53806}
807
808TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
810
[email protected]ac790b42009-12-02 04:31:31811 EXPECT_EQ(OK, StartRequest("a", LOWEST));
812 EXPECT_EQ(OK, StartRequest("a", LOW));
813 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
814 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53815
[email protected]2431756e2010-09-29 20:26:13816 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53817 client_socket_factory_.allocation_count());
818
[email protected]ac790b42009-12-02 04:31:31819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53822
[email protected]2431756e2010-09-29 20:26:13823 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53824
[email protected]2431756e2010-09-29 20:26:13825 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53826 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13827 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53828
829 // First 4 requests don't have to wait, and finish in order.
830 EXPECT_EQ(1, GetOrderOfRequest(1));
831 EXPECT_EQ(2, GetOrderOfRequest(2));
832 EXPECT_EQ(3, GetOrderOfRequest(3));
833 EXPECT_EQ(4, GetOrderOfRequest(4));
834
835 // Request ("b", 7) has the highest priority, but we can't make new socket for
836 // group "b", because it has reached the per-group limit. Then we make
837 // socket for ("c", 6), because it has higher priority than ("a", 4),
838 // and we still can't make a socket for group "b".
839 EXPECT_EQ(5, GetOrderOfRequest(5));
840 EXPECT_EQ(6, GetOrderOfRequest(6));
841 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17842
843 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13844 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53845}
846
847// Make sure that we count connecting sockets against the total limit.
848TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
849 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
850
851 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
852 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
853 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
854
855 // Create one asynchronous request.
856 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
857 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
858
[email protected]6b175382009-10-13 06:47:47859 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
860 // actually become pending until 2ms after they have been created. In order
861 // to flush all tasks, we need to wait so that we know there are no
862 // soon-to-be-pending tasks waiting.
863 PlatformThread::Sleep(10);
864 MessageLoop::current()->RunAllPending();
865
[email protected]211d21722009-07-22 15:48:53866 // The next synchronous request should wait for its turn.
867 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
869
[email protected]2431756e2010-09-29 20:26:13870 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53871
[email protected]2431756e2010-09-29 20:26:13872 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53873 client_socket_factory_.allocation_count());
874
875 EXPECT_EQ(1, GetOrderOfRequest(1));
876 EXPECT_EQ(2, GetOrderOfRequest(2));
877 EXPECT_EQ(3, GetOrderOfRequest(3));
878 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17879 EXPECT_EQ(5, GetOrderOfRequest(5));
880
881 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13882 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53883}
884
[email protected]6427fe22010-04-16 22:27:41885TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
886 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
887 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
888
889 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
890 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
891 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
892 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
893
894 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
895
896 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
897
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
900
901 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
902
[email protected]2431756e2010-09-29 20:26:13903 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41904 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13905 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41906 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13907 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
908 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41909 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
910}
911
[email protected]d7027bb2010-05-10 18:58:54912TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
913 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
914 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
915
916 ClientSocketHandle handle;
917 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13918 EXPECT_EQ(ERR_IO_PENDING,
919 handle.Init("a",
920 params_,
921 kDefaultPriority,
922 &callback,
923 pool_.get(),
924 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54925
926 ClientSocketHandle handles[4];
927 for (size_t i = 0; i < arraysize(handles); ++i) {
928 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13929 EXPECT_EQ(ERR_IO_PENDING,
930 handles[i].Init("b",
931 params_,
932 kDefaultPriority,
933 &callback,
934 pool_.get(),
935 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54936 }
937
938 // One will be stalled, cancel all the handles now.
939 // This should hit the OnAvailableSocketSlot() code where we previously had
940 // stalled groups, but no longer have any.
941 for (size_t i = 0; i < arraysize(handles); ++i)
942 handles[i].Reset();
943}
944
[email protected]eb5a99382010-07-11 03:18:26945TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54946 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
947 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
948
[email protected]eb5a99382010-07-11 03:18:26949 {
950 ClientSocketHandle handles[kDefaultMaxSockets];
951 TestCompletionCallback callbacks[kDefaultMaxSockets];
952 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13953 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
954 params_,
[email protected]e83326f2010-07-31 17:29:25955 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13956 &callbacks[i],
957 pool_.get(),
958 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26959 }
960
961 // Force a stalled group.
962 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54963 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13964 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
965 params_,
966 kDefaultPriority,
967 &callback,
968 pool_.get(),
969 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26970
971 // Cancel the stalled request.
972 stalled_handle.Reset();
973
974 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
975 EXPECT_EQ(0, pool_->IdleSocketCount());
976
977 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54978 }
979
[email protected]43a21b82010-06-10 21:30:54980 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
981 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26982}
[email protected]43a21b82010-06-10 21:30:54983
[email protected]eb5a99382010-07-11 03:18:26984TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
985 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
986 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
987
988 {
989 ClientSocketHandle handles[kDefaultMaxSockets];
990 for (int i = 0; i < kDefaultMaxSockets; ++i) {
991 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13992 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
993 params_,
994 kDefaultPriority,
995 &callback,
996 pool_.get(),
997 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26998 }
999
1000 // Force a stalled group.
1001 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1002 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541003 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131004 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1005 params_,
1006 kDefaultPriority,
1007 &callback,
1008 pool_.get(),
1009 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261010
1011 // Since it is stalled, it should have no connect jobs.
1012 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1013
1014 // Cancel the stalled request.
1015 handles[0].Reset();
1016
[email protected]eb5a99382010-07-11 03:18:261017 // Now we should have a connect job.
1018 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1019
1020 // The stalled socket should connect.
1021 EXPECT_EQ(OK, callback.WaitForResult());
1022
1023 EXPECT_EQ(kDefaultMaxSockets + 1,
1024 client_socket_factory_.allocation_count());
1025 EXPECT_EQ(0, pool_->IdleSocketCount());
1026 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1027
1028 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541029 }
1030
[email protected]eb5a99382010-07-11 03:18:261031 EXPECT_EQ(1, pool_->IdleSocketCount());
1032}
[email protected]43a21b82010-06-10 21:30:541033
[email protected]eb5a99382010-07-11 03:18:261034TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1035 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1036 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541037
[email protected]eb5a99382010-07-11 03:18:261038 ClientSocketHandle stalled_handle;
1039 TestCompletionCallback callback;
1040 {
1041 ClientSocketHandle handles[kDefaultMaxSockets];
1042 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1043 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061044 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131045 params_,
1046 kDefaultPriority,
1047 &callback,
1048 pool_.get(),
1049 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261050 }
1051
1052 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1053 EXPECT_EQ(0, pool_->IdleSocketCount());
1054
1055 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131056 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1057 params_,
1058 kDefaultPriority,
1059 &callback,
1060 pool_.get(),
1061 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261062
1063 // Dropping out of scope will close all handles and return them to idle.
1064 }
[email protected]43a21b82010-06-10 21:30:541065
1066 // But if we wait for it, the released idle sockets will be closed in
1067 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101068 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261069
1070 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1071 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541072}
1073
1074// Regression test for http://crbug.com/40952.
1075TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1076 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221077 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541078 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1079
1080 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1081 ClientSocketHandle handle;
1082 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1084 params_,
1085 kDefaultPriority,
1086 &callback,
1087 pool_.get(),
1088 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541089 }
1090
1091 // Flush all the DoReleaseSocket tasks.
1092 MessageLoop::current()->RunAllPending();
1093
1094 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1095 // reuse a socket.
1096 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1097 ClientSocketHandle handle;
1098 TestCompletionCallback callback;
1099
1100 // "0" is special here, since it should be the first entry in the sorted map,
1101 // which is the one which we would close an idle socket for. We shouldn't
1102 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131103 EXPECT_EQ(OK, handle.Init("0",
1104 params_,
1105 kDefaultPriority,
1106 &callback,
1107 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211108 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541109
1110 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1111 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1112}
1113
[email protected]ab838892009-06-30 18:49:051114TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531115 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091116
[email protected]c9d6a1d2009-07-14 16:15:201117 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1118 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311120 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1121 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1122 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1123 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1124 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091125
[email protected]2431756e2010-09-29 20:26:131126 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]c9d6a1d2009-07-14 16:15:201128 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1129 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131130 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1131 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091132
[email protected]c9d6a1d2009-07-14 16:15:201133 EXPECT_EQ(1, GetOrderOfRequest(1));
1134 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031135 EXPECT_EQ(8, GetOrderOfRequest(3));
1136 EXPECT_EQ(6, GetOrderOfRequest(4));
1137 EXPECT_EQ(4, GetOrderOfRequest(5));
1138 EXPECT_EQ(3, GetOrderOfRequest(6));
1139 EXPECT_EQ(5, GetOrderOfRequest(7));
1140 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171141
1142 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131143 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091144}
1145
[email protected]ab838892009-06-30 18:49:051146TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531147 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091148
[email protected]c9d6a1d2009-07-14 16:15:201149 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1150 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311151 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1152 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1155 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091156
[email protected]2431756e2010-09-29 20:26:131157 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091158
[email protected]2431756e2010-09-29 20:26:131159 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1160 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201161
[email protected]2431756e2010-09-29 20:26:131162 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201163 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131164 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1165 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091166}
1167
1168// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051169// The pending connect job will be cancelled and should not call back into
1170// ClientSocketPoolBase.
1171TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531172 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201173
[email protected]ab838892009-06-30 18:49:051174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131175 ClientSocketHandle handle;
1176 TestCompletionCallback callback;
1177 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1178 params_,
1179 kDefaultPriority,
1180 &callback,
1181 pool_.get(),
1182 BoundNetLog()));
1183 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091184}
1185
[email protected]ab838892009-06-30 18:49:051186TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531187 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201188
[email protected]ab838892009-06-30 18:49:051189 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061190 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091191 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091192
[email protected]2431756e2010-09-29 20:26:131193 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1194 params_,
1195 kDefaultPriority,
1196 &callback,
1197 pool_.get(),
1198 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091199
1200 handle.Reset();
1201
1202 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131203 EXPECT_EQ(ERR_IO_PENDING,
1204 handle.Init("a",
1205 params_,
1206 kDefaultPriority,
1207 &callback2,
1208 pool_.get(),
1209 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091210
1211 EXPECT_EQ(OK, callback2.WaitForResult());
1212 EXPECT_FALSE(callback.have_result());
1213
1214 handle.Reset();
1215}
1216
[email protected]ab838892009-06-30 18:49:051217TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531218 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091219
[email protected]c9d6a1d2009-07-14 16:15:201220 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1221 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311222 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091227
1228 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201229 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131230 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1231 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091232
[email protected]2431756e2010-09-29 20:26:131233 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091234
[email protected]c9d6a1d2009-07-14 16:15:201235 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1236 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131237 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1238 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091239
[email protected]c9d6a1d2009-07-14 16:15:201240 EXPECT_EQ(1, GetOrderOfRequest(1));
1241 EXPECT_EQ(2, GetOrderOfRequest(2));
1242 EXPECT_EQ(5, GetOrderOfRequest(3));
1243 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131244 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1245 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201246 EXPECT_EQ(4, GetOrderOfRequest(6));
1247 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171248
1249 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131250 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091251}
1252
1253class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1254 public:
[email protected]2ab05b52009-07-01 23:57:581255 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241256 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581257 TestConnectJobFactory* test_connect_job_factory,
1258 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091259 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061260 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581261 within_callback_(false),
1262 test_connect_job_factory_(test_connect_job_factory),
1263 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091264
1265 virtual void RunWithParams(const Tuple1<int>& params) {
1266 callback_.RunWithParams(params);
1267 ASSERT_EQ(OK, params.a);
1268
1269 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581270 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111271
1272 // Don't allow reuse of the socket. Disconnect it and then release it and
1273 // run through the MessageLoop once to get it completely released.
1274 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091275 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111276 {
1277 MessageLoop::ScopedNestableTaskAllower nestable(
1278 MessageLoop::current());
1279 MessageLoop::current()->RunAllPending();
1280 }
[email protected]f6d1d6eb2009-06-24 20:16:091281 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471282 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211283 scoped_refptr<TestSocketParams> params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:131284 int rv = handle_->Init("a",
1285 params,
1286 kDefaultPriority,
1287 &next_job_callback,
1288 pool_,
1289 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581290 switch (next_job_type_) {
1291 case TestConnectJob::kMockJob:
1292 EXPECT_EQ(OK, rv);
1293 break;
1294 case TestConnectJob::kMockPendingJob:
1295 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471296
1297 // For pending jobs, wait for new socket to be created. This makes
1298 // sure there are no more pending operations nor any unclosed sockets
1299 // when the test finishes.
1300 // We need to give it a little bit of time to run, so that all the
1301 // operations that happen on timers (e.g. cleanup of idle
1302 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111303 {
1304 MessageLoop::ScopedNestableTaskAllower nestable(
1305 MessageLoop::current());
1306 PlatformThread::Sleep(10);
1307 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1308 }
[email protected]2ab05b52009-07-01 23:57:581309 break;
1310 default:
1311 FAIL() << "Unexpected job type: " << next_job_type_;
1312 break;
1313 }
[email protected]f6d1d6eb2009-06-24 20:16:091314 }
1315 }
1316
1317 int WaitForResult() {
1318 return callback_.WaitForResult();
1319 }
1320
1321 private:
1322 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131323 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091324 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581325 TestConnectJobFactory* const test_connect_job_factory_;
1326 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091327 TestCompletionCallback callback_;
1328};
1329
[email protected]2ab05b52009-07-01 23:57:581330TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531331 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201332
[email protected]0b7648c2009-07-06 20:14:011333 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061334 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581335 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061336 &handle, pool_.get(), connect_job_factory_,
1337 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131338 int rv = handle.Init("a",
1339 params_,
1340 kDefaultPriority,
1341 &callback,
1342 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211343 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091344 ASSERT_EQ(ERR_IO_PENDING, rv);
1345
1346 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581347}
[email protected]f6d1d6eb2009-06-24 20:16:091348
[email protected]2ab05b52009-07-01 23:57:581349TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201351
[email protected]0b7648c2009-07-06 20:14:011352 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061353 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581354 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061355 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131356 int rv = handle.Init("a",
1357 params_,
1358 kDefaultPriority,
1359 &callback,
1360 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211361 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581362 ASSERT_EQ(ERR_IO_PENDING, rv);
1363
1364 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091365}
1366
1367// Make sure that pending requests get serviced after active requests get
1368// cancelled.
[email protected]ab838892009-06-30 18:49:051369TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531370 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201371
[email protected]0b7648c2009-07-06 20:14:011372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091373
[email protected]c9d6a1d2009-07-14 16:15:201374 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1375 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1376 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1377 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1378 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1379 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1380 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091381
[email protected]c9d6a1d2009-07-14 16:15:201382 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1383 // Let's cancel them.
1384 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131385 ASSERT_FALSE(request(i)->handle()->is_initialized());
1386 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091387 }
1388
[email protected]f6d1d6eb2009-06-24 20:16:091389 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131390 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1391 EXPECT_EQ(OK, request(i)->WaitForResult());
1392 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091393 }
1394
[email protected]2431756e2010-09-29 20:26:131395 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1396 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091397}
1398
1399// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051400TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531401 const size_t kMaxSockets = 5;
1402 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201403
[email protected]0b7648c2009-07-06 20:14:011404 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091405
[email protected]211d21722009-07-22 15:48:531406 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1407 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091408
1409 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531410 for (size_t i = 0; i < kNumberOfRequests; ++i)
1411 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091412
[email protected]211d21722009-07-22 15:48:531413 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131414 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091415}
1416
[email protected]5fc08e32009-07-15 17:09:571417TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531418 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571419
1420 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1421
[email protected]2431756e2010-09-29 20:26:131422 ClientSocketHandle handle;
1423 TestCompletionCallback callback;
1424 int rv = handle.Init("a",
1425 params_,
1426 kDefaultPriority,
1427 &callback,
1428 pool_.get(),
1429 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571430 EXPECT_EQ(ERR_IO_PENDING, rv);
1431
1432 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131433 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571434
[email protected]2431756e2010-09-29 20:26:131435 rv = handle.Init("a",
1436 params_,
1437 kDefaultPriority,
1438 &callback,
1439 pool_.get(),
1440 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571441 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131442 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571443
[email protected]2431756e2010-09-29 20:26:131444 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571445 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1446}
1447
[email protected]2b7523d2009-07-29 20:29:231448// Regression test for http://crbug.com/17985.
1449TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1450 const int kMaxSockets = 3;
1451 const int kMaxSocketsPerGroup = 2;
1452 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1453
[email protected]ac790b42009-12-02 04:31:311454 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231455
1456 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1457 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1458
1459 // This is going to be a pending request in an otherwise empty group.
1460 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1461
1462 // Reach the maximum socket limit.
1463 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1464
1465 // Create a stalled group with high priorities.
1466 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1467 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231468
[email protected]eb5a99382010-07-11 03:18:261469 // Release the first two sockets from "a". Because this is a keepalive,
1470 // the first release will unblock the pending request for "a". The
1471 // second release will unblock a request for "c", becaue it is the next
1472 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131473 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1474 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231475
1476 // Closing idle sockets should not get us into trouble, but in the bug
1477 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411478 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541479 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261480
1481 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231482}
1483
[email protected]4d3b05d2010-01-27 21:27:291484TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531485 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571486
1487 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131488 ClientSocketHandle handle;
1489 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531490 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131491 int rv = handle.Init("a",
1492 params_,
1493 LOWEST,
1494 &callback,
1495 pool_.get(),
1496 log.bound());
[email protected]5fc08e32009-07-15 17:09:571497 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131498 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1499 EXPECT_EQ(OK, callback.WaitForResult());
1500 EXPECT_TRUE(handle.is_initialized());
1501 EXPECT_TRUE(handle.socket());
1502 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301503
[email protected]06650c52010-06-03 00:49:171504 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461505 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531506 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171507 EXPECT_TRUE(LogContainsEvent(
1508 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1509 NetLog::PHASE_NONE));
1510 EXPECT_TRUE(LogContainsEvent(
1511 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1512 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461513 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171514 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571515}
1516
[email protected]4d3b05d2010-01-27 21:27:291517TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571518 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531519 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571520
1521 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131522 ClientSocketHandle handle;
1523 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531524 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181525 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131526 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431527 HttpResponseInfo info;
1528 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131529 handle.set_ssl_error_response_info(info);
1530 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1531 params_,
1532 kDefaultPriority,
1533 &callback,
1534 pool_.get(),
1535 log.bound()));
1536 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1537 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1538 EXPECT_FALSE(handle.is_ssl_error());
1539 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301540
[email protected]06650c52010-06-03 00:49:171541 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461542 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531543 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171544 EXPECT_TRUE(LogContainsEvent(
1545 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1546 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321547 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171548 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571549}
1550
[email protected]4d3b05d2010-01-27 21:27:291551TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101552 // TODO(eroman): Add back the log expectations! Removed them because the
1553 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531554 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571555
1556 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131557 ClientSocketHandle handle;
1558 TestCompletionCallback callback;
1559 ClientSocketHandle handle2;
1560 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571561
[email protected]2431756e2010-09-29 20:26:131562 EXPECT_EQ(ERR_IO_PENDING,
1563 handle.Init("a",
1564 params_,
1565 kDefaultPriority,
1566 &callback,
1567 pool_.get(),
1568 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531569 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131570 EXPECT_EQ(ERR_IO_PENDING,
1571 handle2.Init("a",
1572 params_,
1573 kDefaultPriority,
1574 &callback2,
1575 pool_.get(),
1576 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571577
[email protected]2431756e2010-09-29 20:26:131578 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571579
[email protected]fd7b7c92009-08-20 19:38:301580
1581 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301582
[email protected]2431756e2010-09-29 20:26:131583 EXPECT_EQ(OK, callback2.WaitForResult());
1584 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301585
1586 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531587 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571588}
1589
[email protected]4d3b05d2010-01-27 21:27:291590TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341591 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1592
[email protected]17a0c6c2009-08-04 00:07:041593 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1594
[email protected]ac790b42009-12-02 04:31:311595 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1596 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341599
1600 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131601 (*requests())[2]->handle()->Reset();
1602 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341603 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1604
[email protected]2431756e2010-09-29 20:26:131605 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341606 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1607
[email protected]2431756e2010-09-29 20:26:131608 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261609 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341610}
1611
[email protected]5fc08e32009-07-15 17:09:571612// When requests and ConnectJobs are not coupled, the request will get serviced
1613// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291614TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531615 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571616
1617 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321618 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571619
[email protected]2431756e2010-09-29 20:26:131620 std::vector<TestSocketRequest*> request_order;
1621 size_t completion_count; // unused
1622 TestSocketRequest req1(&request_order, &completion_count);
1623 int rv = req1.handle()->Init("a",
1624 params_,
1625 kDefaultPriority,
1626 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211627 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571628 EXPECT_EQ(ERR_IO_PENDING, rv);
1629 EXPECT_EQ(OK, req1.WaitForResult());
1630
1631 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1632 // without a job.
1633 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1634
[email protected]2431756e2010-09-29 20:26:131635 TestSocketRequest req2(&request_order, &completion_count);
1636 rv = req2.handle()->Init("a",
1637 params_,
1638 kDefaultPriority,
1639 &req2,
1640 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211641 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571642 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131643 TestSocketRequest req3(&request_order, &completion_count);
1644 rv = req3.handle()->Init("a",
1645 params_,
1646 kDefaultPriority,
1647 &req3,
1648 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211649 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571650 EXPECT_EQ(ERR_IO_PENDING, rv);
1651
1652 // Both Requests 2 and 3 are pending. We release socket 1 which should
1653 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331654 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261655 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331656 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571657 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331658 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571659
1660 // Signal job 2, which should service request 3.
1661
1662 client_socket_factory_.SignalJobs();
1663 EXPECT_EQ(OK, req3.WaitForResult());
1664
[email protected]2431756e2010-09-29 20:26:131665 ASSERT_EQ(3U, request_order.size());
1666 EXPECT_EQ(&req1, request_order[0]);
1667 EXPECT_EQ(&req2, request_order[1]);
1668 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571669 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1670}
1671
1672// The requests are not coupled to the jobs. So, the requests should finish in
1673// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291674TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531675 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571676 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321677 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571678
[email protected]2431756e2010-09-29 20:26:131679 std::vector<TestSocketRequest*> request_order;
1680 size_t completion_count; // unused
1681 TestSocketRequest req1(&request_order, &completion_count);
1682 int rv = req1.handle()->Init("a",
1683 params_,
1684 kDefaultPriority,
1685 &req1,
1686 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211687 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(ERR_IO_PENDING, rv);
1689
[email protected]2431756e2010-09-29 20:26:131690 TestSocketRequest req2(&request_order, &completion_count);
1691 rv = req2.handle()->Init("a",
1692 params_,
1693 kDefaultPriority,
1694 &req2,
1695 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211696 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571697 EXPECT_EQ(ERR_IO_PENDING, rv);
1698
1699 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321700 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571701
[email protected]2431756e2010-09-29 20:26:131702 TestSocketRequest req3(&request_order, &completion_count);
1703 rv = req3.handle()->Init("a",
1704 params_,
1705 kDefaultPriority,
1706 &req3,
1707 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211708 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571709 EXPECT_EQ(ERR_IO_PENDING, rv);
1710
1711 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1712 EXPECT_EQ(OK, req2.WaitForResult());
1713 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1714
[email protected]2431756e2010-09-29 20:26:131715 ASSERT_EQ(3U, request_order.size());
1716 EXPECT_EQ(&req1, request_order[0]);
1717 EXPECT_EQ(&req2, request_order[1]);
1718 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571719}
1720
[email protected]e6ec67b2010-06-16 00:12:461721TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531722 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571723 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321724 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571725
[email protected]2431756e2010-09-29 20:26:131726 ClientSocketHandle handle;
1727 TestCompletionCallback callback;
1728 int rv = handle.Init("a",
1729 params_,
1730 kDefaultPriority,
1731 &callback,
1732 pool_.get(),
1733 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571734 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131735 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571736
1737 MessageLoop::current()->RunAllPending();
1738
[email protected]2431756e2010-09-29 20:26:131739 ClientSocketHandle handle2;
1740 TestCompletionCallback callback2;
1741 rv = handle2.Init("a",
1742 params_,
1743 kDefaultPriority,
1744 &callback2, pool_.get(),
1745 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571746 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131747 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1748 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571749}
1750
[email protected]e772db3f2010-07-12 18:11:131751TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1753 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1754
[email protected]2431756e2010-09-29 20:26:131755 ClientSocketHandle handle;
1756 TestCompletionCallback callback;
1757 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1758 params_,
1759 kDefaultPriority,
1760 &callback, pool_.get(),
1761 BoundNetLog()));
1762 EXPECT_TRUE(handle.is_initialized());
1763 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131764}
1765
1766TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1768
1769 connect_job_factory_->set_job_type(
1770 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131771 ClientSocketHandle handle;
1772 TestCompletionCallback callback;
1773 EXPECT_EQ(ERR_IO_PENDING,
1774 handle.Init("a",
1775 params_,
1776 kDefaultPriority,
1777 &callback,
1778 pool_.get(),
1779 BoundNetLog()));
1780 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1781 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1782 EXPECT_TRUE(handle.is_initialized());
1783 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131784}
1785
[email protected]e60e47a2010-07-14 03:37:181786TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1787 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1788 connect_job_factory_->set_job_type(
1789 TestConnectJob::kMockAdditionalErrorStateJob);
1790
[email protected]2431756e2010-09-29 20:26:131791 ClientSocketHandle handle;
1792 TestCompletionCallback callback;
1793 EXPECT_EQ(ERR_CONNECTION_FAILED,
1794 handle.Init("a",
1795 params_,
1796 kDefaultPriority,
1797 &callback,
1798 pool_.get(),
1799 BoundNetLog()));
1800 EXPECT_FALSE(handle.is_initialized());
1801 EXPECT_FALSE(handle.socket());
1802 EXPECT_TRUE(handle.is_ssl_error());
1803 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181804}
1805
1806TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1807 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1808
1809 connect_job_factory_->set_job_type(
1810 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131811 ClientSocketHandle handle;
1812 TestCompletionCallback callback;
1813 EXPECT_EQ(ERR_IO_PENDING,
1814 handle.Init("a",
1815 params_,
1816 kDefaultPriority,
1817 &callback,
1818 pool_.get(),
1819 BoundNetLog()));
1820 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1821 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1822 EXPECT_FALSE(handle.is_initialized());
1823 EXPECT_FALSE(handle.socket());
1824 EXPECT_TRUE(handle.is_ssl_error());
1825 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181826}
1827
[email protected]4d3b05d2010-01-27 21:27:291828TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161829 CreatePoolWithIdleTimeouts(
1830 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1831 base::TimeDelta(), // Time out unused sockets immediately.
1832 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1833
1834 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1835
1836 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1837
[email protected]2431756e2010-09-29 20:26:131838 ClientSocketHandle handle;
1839 TestCompletionCallback callback;
1840 int rv = handle.Init("a",
1841 params_,
1842 LOWEST,
1843 &callback,
1844 pool_.get(),
1845 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161846 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131847 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161848
[email protected]2431756e2010-09-29 20:26:131849 ClientSocketHandle handle2;
1850 TestCompletionCallback callback2;
1851 rv = handle2.Init("a",
1852 params_,
1853 LOWEST,
1854 &callback2,
1855 pool_.get(),
1856 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161857 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131858 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161859
1860 // Cancel one of the requests. Wait for the other, which will get the first
1861 // job. Release the socket. Run the loop again to make sure the second
1862 // socket is sitting idle and the first one is released (since ReleaseSocket()
1863 // just posts a DoReleaseSocket() task).
1864
[email protected]2431756e2010-09-29 20:26:131865 handle.Reset();
1866 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011867 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131868 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1869 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471870
1871 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1872 // actually become pending until 2ms after they have been created. In order
1873 // to flush all tasks, we need to wait so that we know there are no
1874 // soon-to-be-pending tasks waiting.
1875 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161876 MessageLoop::current()->RunAllPending();
1877
1878 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041879
[email protected]9bf28db2009-08-29 01:35:161880 // Invoke the idle socket cleanup check. Only one socket should be left, the
1881 // used socket. Request it to make sure that it's used.
1882
1883 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531884 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131885 rv = handle.Init("a",
1886 params_,
1887 LOWEST,
1888 &callback,
1889 pool_.get(),
1890 log.bound());
[email protected]9bf28db2009-08-29 01:35:161891 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131892 EXPECT_TRUE(handle.is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151893 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451894 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161895}
1896
[email protected]2041cf342010-02-19 03:15:591897// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161898// because of multiple releasing disconnected sockets.
1899TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1900 CreatePoolWithIdleTimeouts(
1901 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1902 base::TimeDelta(), // Time out unused sockets immediately.
1903 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1904
1905 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1906
1907 // Startup 4 connect jobs. Two of them will be pending.
1908
[email protected]2431756e2010-09-29 20:26:131909 ClientSocketHandle handle;
1910 TestCompletionCallback callback;
1911 int rv = handle.Init("a",
1912 params_,
1913 LOWEST,
1914 &callback,
1915 pool_.get(),
1916 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161917 EXPECT_EQ(OK, rv);
1918
[email protected]2431756e2010-09-29 20:26:131919 ClientSocketHandle handle2;
1920 TestCompletionCallback callback2;
1921 rv = handle2.Init("a",
1922 params_,
1923 LOWEST,
1924 &callback2,
1925 pool_.get(),
1926 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161927 EXPECT_EQ(OK, rv);
1928
[email protected]2431756e2010-09-29 20:26:131929 ClientSocketHandle handle3;
1930 TestCompletionCallback callback3;
1931 rv = handle3.Init("a",
1932 params_,
1933 LOWEST,
1934 &callback3,
1935 pool_.get(),
1936 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161937 EXPECT_EQ(ERR_IO_PENDING, rv);
1938
[email protected]2431756e2010-09-29 20:26:131939 ClientSocketHandle handle4;
1940 TestCompletionCallback callback4;
1941 rv = handle4.Init("a",
1942 params_,
1943 LOWEST,
1944 &callback4,
1945 pool_.get(),
1946 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161947 EXPECT_EQ(ERR_IO_PENDING, rv);
1948
1949 // Release two disconnected sockets.
1950
[email protected]2431756e2010-09-29 20:26:131951 handle.socket()->Disconnect();
1952 handle.Reset();
1953 handle2.socket()->Disconnect();
1954 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161955
[email protected]2431756e2010-09-29 20:26:131956 EXPECT_EQ(OK, callback3.WaitForResult());
1957 EXPECT_FALSE(handle3.is_reused());
1958 EXPECT_EQ(OK, callback4.WaitForResult());
1959 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161960}
1961
[email protected]d7027bb2010-05-10 18:58:541962// Regression test for http://crbug.com/42267.
1963// When DoReleaseSocket() is processed for one socket, it is blocked because the
1964// other stalled groups all have releasing sockets, so no progress can be made.
1965TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1966 CreatePoolWithIdleTimeouts(
1967 4 /* socket limit */, 4 /* socket limit per group */,
1968 base::TimeDelta(), // Time out unused sockets immediately.
1969 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1970
1971 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1972
1973 // Max out the socket limit with 2 per group.
1974
[email protected]2431756e2010-09-29 20:26:131975 ClientSocketHandle handle_a[4];
1976 TestCompletionCallback callback_a[4];
1977 ClientSocketHandle handle_b[4];
1978 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541979
1980 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:131981 EXPECT_EQ(OK, handle_a[i].Init("a",
1982 params_,
1983 LOWEST,
1984 &callback_a[i],
1985 pool_.get(),
1986 BoundNetLog()));
1987 EXPECT_EQ(OK, handle_b[i].Init("b",
1988 params_,
1989 LOWEST,
1990 &callback_b[i],
1991 pool_.get(),
1992 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541993 }
[email protected]b89f7e42010-05-20 20:37:001994
[email protected]d7027bb2010-05-10 18:58:541995 // Make 4 pending requests, 2 per group.
1996
1997 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:131998 EXPECT_EQ(ERR_IO_PENDING,
1999 handle_a[i].Init("a",
2000 params_,
2001 LOWEST,
2002 &callback_a[i],
2003 pool_.get(),
2004 BoundNetLog()));
2005 EXPECT_EQ(ERR_IO_PENDING,
2006 handle_b[i].Init("b",
2007 params_,
2008 LOWEST,
2009 &callback_b[i],
2010 pool_.get(),
2011 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542012 }
2013
2014 // Release b's socket first. The order is important, because in
2015 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2016 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2017 // first, which has a releasing socket, so it refuses to start up another
2018 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132019 handle_b[0].socket()->Disconnect();
2020 handle_b[0].Reset();
2021 handle_a[0].socket()->Disconnect();
2022 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542023
2024 // Used to get stuck here.
2025 MessageLoop::current()->RunAllPending();
2026
[email protected]2431756e2010-09-29 20:26:132027 handle_b[1].socket()->Disconnect();
2028 handle_b[1].Reset();
2029 handle_a[1].socket()->Disconnect();
2030 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542031
2032 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132033 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2034 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542035 }
2036}
2037
[email protected]fd4fe0b2010-02-08 23:02:152038TEST_F(ClientSocketPoolBaseTest,
2039 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2040 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2041
2042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2043
2044 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2045 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2046 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2047 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2048
[email protected]2431756e2010-09-29 20:26:132049 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2050 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2051 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152052
2053 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132054 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2055 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152056
[email protected]2431756e2010-09-29 20:26:132057 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2058 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2059 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152060
2061 EXPECT_EQ(1, GetOrderOfRequest(1));
2062 EXPECT_EQ(2, GetOrderOfRequest(2));
2063 EXPECT_EQ(3, GetOrderOfRequest(3));
2064 EXPECT_EQ(4, GetOrderOfRequest(4));
2065
2066 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132067 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152068}
2069
[email protected]4f1e4982010-03-02 18:31:042070class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2071 public:
[email protected]2431756e2010-09-29 20:26:132072 TestReleasingSocketRequest(TestClientSocketPool* pool,
2073 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182074 bool reset_releasing_handle)
2075 : pool_(pool),
2076 expected_result_(expected_result),
2077 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042078
2079 ClientSocketHandle* handle() { return &handle_; }
2080
2081 int WaitForResult() {
2082 return callback_.WaitForResult();
2083 }
2084
2085 virtual void RunWithParams(const Tuple1<int>& params) {
2086 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182087 if (reset_releasing_handle_)
2088 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:212089 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:132090 EXPECT_EQ(expected_result_, handle2_.Init("a",
2091 con_params,
2092 kDefaultPriority,
2093 &callback2_,
2094 pool_,
[email protected]e60e47a2010-07-14 03:37:182095 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042096 }
2097
2098 private:
[email protected]2431756e2010-09-29 20:26:132099 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182100 int expected_result_;
2101 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042102 ClientSocketHandle handle_;
2103 ClientSocketHandle handle2_;
2104 TestCompletionCallback callback_;
2105 TestCompletionCallback callback2_;
2106};
2107
[email protected]e60e47a2010-07-14 03:37:182108
2109TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2110 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2111
2112 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2113 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2114 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2115
[email protected]2431756e2010-09-29 20:26:132116 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182117 client_socket_factory_.allocation_count());
2118
2119 connect_job_factory_->set_job_type(
2120 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2121 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132122 EXPECT_EQ(ERR_IO_PENDING,
2123 req.handle()->Init("a",
2124 params_,
2125 kDefaultPriority,
2126 &req,
2127 pool_.get(),
2128 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182129 // The next job should complete synchronously
2130 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2131
2132 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2133 EXPECT_FALSE(req.handle()->is_initialized());
2134 EXPECT_FALSE(req.handle()->socket());
2135 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432136 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182137}
2138
[email protected]b6501d3d2010-06-03 23:53:342139// http://crbug.com/44724 regression test.
2140// We start releasing the pool when we flush on network change. When that
2141// happens, the only active references are in the ClientSocketHandles. When a
2142// ConnectJob completes and calls back into the last ClientSocketHandle, that
2143// callback can release the last reference and delete the pool. After the
2144// callback finishes, we go back to the stack frame within the now-deleted pool.
2145// Executing any code that refers to members of the now-deleted pool can cause
2146// crashes.
2147TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2148 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2149 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2150
2151 ClientSocketHandle handle;
2152 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132153 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2154 params_,
2155 kDefaultPriority,
2156 &callback,
2157 pool_.get(),
2158 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342159
[email protected]2431756e2010-09-29 20:26:132160 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342161
2162 // We'll call back into this now.
2163 callback.WaitForResult();
2164}
2165
[email protected]a7e38572010-06-07 18:22:242166TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2167 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2168 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2169
2170 ClientSocketHandle handle;
2171 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132172 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2173 params_,
2174 kDefaultPriority,
2175 &callback,
2176 pool_.get(),
2177 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242178 EXPECT_EQ(OK, callback.WaitForResult());
2179 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2180
2181 pool_->Flush();
2182
2183 handle.Reset();
2184 MessageLoop::current()->RunAllPending();
2185
[email protected]2431756e2010-09-29 20:26:132186 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2187 params_,
2188 kDefaultPriority,
2189 &callback,
2190 pool_.get(),
2191 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242192 EXPECT_EQ(OK, callback.WaitForResult());
2193 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2194}
2195
[email protected]06f92462010-08-31 19:24:142196class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2197 public:
2198 ConnectWithinCallback(
2199 const std::string& group_name,
2200 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132201 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142202 : group_name_(group_name), params_(params), pool_(pool) {}
2203
2204 ~ConnectWithinCallback() {}
2205
2206 virtual void RunWithParams(const Tuple1<int>& params) {
2207 callback_.RunWithParams(params);
2208 EXPECT_EQ(ERR_IO_PENDING,
2209 handle_.Init(group_name_,
2210 params_,
2211 kDefaultPriority,
2212 &nested_callback_,
2213 pool_,
2214 BoundNetLog()));
2215 }
2216
2217 int WaitForResult() {
2218 return callback_.WaitForResult();
2219 }
2220
2221 int WaitForNestedResult() {
2222 return nested_callback_.WaitForResult();
2223 }
2224
2225 private:
2226 const std::string group_name_;
2227 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132228 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142229 ClientSocketHandle handle_;
2230 TestCompletionCallback callback_;
2231 TestCompletionCallback nested_callback_;
2232};
2233
2234TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2235 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2236
2237 // First job will be waiting until it gets aborted.
2238 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2239
2240 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132241 ConnectWithinCallback callback("a", params_, pool_.get());
2242 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2243 params_,
2244 kDefaultPriority,
2245 &callback,
2246 pool_.get(),
2247 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142248
2249 // Second job will be started during the first callback, and will
2250 // asynchronously complete with OK.
2251 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2252 pool_->Flush();
2253 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2254 EXPECT_EQ(OK, callback.WaitForNestedResult());
2255}
2256
[email protected]25eea382010-07-10 23:55:262257// Cancel a pending socket request while we're at max sockets,
2258// and verify that the backup socket firing doesn't cause a crash.
2259TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2260 // Max 4 sockets globally, max 4 sockets per group.
2261 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222262 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262263
[email protected]4baaf9d2010-08-31 15:15:442264 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2265 // timer.
[email protected]25eea382010-07-10 23:55:262266 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2267 ClientSocketHandle handle;
2268 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132269 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2270 params_,
2271 kDefaultPriority,
2272 &callback,
2273 pool_.get(),
2274 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262275
2276 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2277 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2278 ClientSocketHandle handles[kDefaultMaxSockets];
2279 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2280 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132281 EXPECT_EQ(OK, handles[i].Init("bar",
2282 params_,
2283 kDefaultPriority,
2284 &callback,
2285 pool_.get(),
2286 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262287 }
2288
2289 MessageLoop::current()->RunAllPending();
2290
2291 // Cancel the pending request.
2292 handle.Reset();
2293
2294 // Wait for the backup timer to fire (add some slop to ensure it fires)
2295 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2296
2297 MessageLoop::current()->RunAllPending();
2298 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2299}
2300
[email protected]3f00be82010-09-27 19:50:022301TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442302 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2303 pool_->EnableConnectBackupJobs();
2304
2305 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2306 // timer.
2307 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2308 ClientSocketHandle handle;
2309 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132310 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2311 params_,
2312 kDefaultPriority,
2313 &callback,
2314 pool_.get(),
2315 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442316 ASSERT_TRUE(pool_->HasGroup("bar"));
2317 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2318
2319 // Cancel the socket request. This should cancel the backup timer. Wait for
2320 // the backup time to see if it indeed got canceled.
2321 handle.Reset();
2322 // Wait for the backup timer to fire (add some slop to ensure it fires)
2323 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2324 MessageLoop::current()->RunAllPending();
2325 ASSERT_TRUE(pool_->HasGroup("bar"));
2326 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2327}
2328
[email protected]3f00be82010-09-27 19:50:022329TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2330 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2331 pool_->EnableConnectBackupJobs();
2332
2333 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2334 // timer.
2335 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2336 ClientSocketHandle handle;
2337 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132338 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2339 params_,
2340 kDefaultPriority,
2341 &callback,
2342 pool_.get(),
2343 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022344 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2345 ClientSocketHandle handle2;
2346 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132347 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2348 params_,
2349 kDefaultPriority,
2350 &callback2,
2351 pool_.get(),
2352 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022353 ASSERT_TRUE(pool_->HasGroup("bar"));
2354 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2355
2356 // Cancel request 1 and then complete request 2. With the requests finished,
2357 // the backup timer should be cancelled.
2358 handle.Reset();
2359 EXPECT_EQ(OK, callback2.WaitForResult());
2360 // Wait for the backup timer to fire (add some slop to ensure it fires)
2361 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2362 MessageLoop::current()->RunAllPending();
2363}
2364
[email protected]eb5a99382010-07-11 03:18:262365// Test delayed socket binding for the case where we have two connects,
2366// and while one is waiting on a connect, the other frees up.
2367// The socket waiting on a connect should switch immediately to the freed
2368// up socket.
2369TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2370 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2372
2373 ClientSocketHandle handle1;
2374 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132375 EXPECT_EQ(ERR_IO_PENDING,
2376 handle1.Init("a",
2377 params_,
2378 kDefaultPriority,
2379 &callback,
2380 pool_.get(),
2381 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262382 EXPECT_EQ(OK, callback.WaitForResult());
2383
2384 // No idle sockets, no pending jobs.
2385 EXPECT_EQ(0, pool_->IdleSocketCount());
2386 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2387
2388 // Create a second socket to the same host, but this one will wait.
2389 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2390 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132391 EXPECT_EQ(ERR_IO_PENDING,
2392 handle2.Init("a",
2393 params_,
2394 kDefaultPriority,
2395 &callback,
2396 pool_.get(),
2397 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262398 // No idle sockets, and one connecting job.
2399 EXPECT_EQ(0, pool_->IdleSocketCount());
2400 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2401
2402 // Return the first handle to the pool. This will initiate the delayed
2403 // binding.
2404 handle1.Reset();
2405
2406 MessageLoop::current()->RunAllPending();
2407
2408 // Still no idle sockets, still one pending connect job.
2409 EXPECT_EQ(0, pool_->IdleSocketCount());
2410 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2411
2412 // The second socket connected, even though it was a Waiting Job.
2413 EXPECT_EQ(OK, callback.WaitForResult());
2414
2415 // And we can see there is still one job waiting.
2416 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2417
2418 // Finally, signal the waiting Connect.
2419 client_socket_factory_.SignalJobs();
2420 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2421
2422 MessageLoop::current()->RunAllPending();
2423}
2424
2425// Test delayed socket binding when a group is at capacity and one
2426// of the group's sockets frees up.
2427TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2428 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2429 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2430
2431 ClientSocketHandle handle1;
2432 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132433 EXPECT_EQ(ERR_IO_PENDING,
2434 handle1.Init("a",
2435 params_,
2436 kDefaultPriority,
2437 &callback,
2438 pool_.get(),
2439 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262440 EXPECT_EQ(OK, callback.WaitForResult());
2441
2442 // No idle sockets, no pending jobs.
2443 EXPECT_EQ(0, pool_->IdleSocketCount());
2444 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2445
2446 // Create a second socket to the same host, but this one will wait.
2447 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2448 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132449 EXPECT_EQ(ERR_IO_PENDING,
2450 handle2.Init("a",
2451 params_,
2452 kDefaultPriority,
2453 &callback,
2454 pool_.get(),
2455 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262456 // No idle sockets, and one connecting job.
2457 EXPECT_EQ(0, pool_->IdleSocketCount());
2458 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2459
2460 // Return the first handle to the pool. This will initiate the delayed
2461 // binding.
2462 handle1.Reset();
2463
2464 MessageLoop::current()->RunAllPending();
2465
2466 // Still no idle sockets, still one pending connect job.
2467 EXPECT_EQ(0, pool_->IdleSocketCount());
2468 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2469
2470 // The second socket connected, even though it was a Waiting Job.
2471 EXPECT_EQ(OK, callback.WaitForResult());
2472
2473 // And we can see there is still one job waiting.
2474 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2475
2476 // Finally, signal the waiting Connect.
2477 client_socket_factory_.SignalJobs();
2478 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2479
2480 MessageLoop::current()->RunAllPending();
2481}
2482
2483// Test out the case where we have one socket connected, one
2484// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512485// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262486// should complete, by taking the first socket's idle socket.
2487TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2488 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2489 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2490
2491 ClientSocketHandle handle1;
2492 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132493 EXPECT_EQ(ERR_IO_PENDING,
2494 handle1.Init("a",
2495 params_,
2496 kDefaultPriority,
2497 &callback,
2498 pool_.get(),
2499 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262500 EXPECT_EQ(OK, callback.WaitForResult());
2501
2502 // No idle sockets, no pending jobs.
2503 EXPECT_EQ(0, pool_->IdleSocketCount());
2504 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2505
2506 // Create a second socket to the same host, but this one will wait.
2507 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2508 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132509 EXPECT_EQ(ERR_IO_PENDING,
2510 handle2.Init("a",
2511 params_,
2512 kDefaultPriority,
2513 &callback,
2514 pool_.get(),
2515 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262516 // No idle sockets, and one connecting job.
2517 EXPECT_EQ(0, pool_->IdleSocketCount());
2518 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2519
2520 // Return the first handle to the pool. This will initiate the delayed
2521 // binding.
2522 handle1.Reset();
2523
2524 MessageLoop::current()->RunAllPending();
2525
2526 // Still no idle sockets, still one pending connect job.
2527 EXPECT_EQ(0, pool_->IdleSocketCount());
2528 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2529
2530 // The second socket connected, even though it was a Waiting Job.
2531 EXPECT_EQ(OK, callback.WaitForResult());
2532
2533 // And we can see there is still one job waiting.
2534 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2535
2536 // Finally, signal the waiting Connect.
2537 client_socket_factory_.SignalJobs();
2538 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2539
2540 MessageLoop::current()->RunAllPending();
2541}
2542
[email protected]2abfe90a2010-08-25 17:49:512543// Cover the case where on an available socket slot, we have one pending
2544// request that completes synchronously, thereby making the Group empty.
2545TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2546 const int kUnlimitedSockets = 100;
2547 const int kOneSocketPerGroup = 1;
2548 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2549
2550 // Make the first request asynchronous fail.
2551 // This will free up a socket slot later.
2552 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2553
2554 ClientSocketHandle handle1;
2555 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132556 EXPECT_EQ(ERR_IO_PENDING,
2557 handle1.Init("a",
2558 params_,
2559 kDefaultPriority,
2560 &callback1,
2561 pool_.get(),
2562 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512563 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2564
2565 // Make the second request synchronously fail. This should make the Group
2566 // empty.
2567 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2568 ClientSocketHandle handle2;
2569 TestCompletionCallback callback2;
2570 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2571 // when created.
[email protected]2431756e2010-09-29 20:26:132572 EXPECT_EQ(ERR_IO_PENDING,
2573 handle2.Init("a",
2574 params_,
2575 kDefaultPriority,
2576 &callback2,
2577 pool_.get(),
2578 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512579
2580 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2581
2582 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2583 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2584 EXPECT_FALSE(pool_->HasGroup("a"));
2585}
2586
[email protected]e1b54dc2010-10-06 21:27:222587TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2588 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2589
2590 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2591
2592 ClientSocketHandle handle1;
2593 TestCompletionCallback callback1;
2594 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2595 params_,
2596 kDefaultPriority,
2597 &callback1,
2598 pool_.get(),
2599 BoundNetLog()));
2600
2601 ClientSocketHandle handle2;
2602 TestCompletionCallback callback2;
2603 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2604 params_,
2605 kDefaultPriority,
2606 &callback2,
2607 pool_.get(),
2608 BoundNetLog()));
2609 ClientSocketHandle handle3;
2610 TestCompletionCallback callback3;
2611 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2612 params_,
2613 kDefaultPriority,
2614 &callback3,
2615 pool_.get(),
2616 BoundNetLog()));
2617
2618 EXPECT_EQ(OK, callback1.WaitForResult());
2619 EXPECT_EQ(OK, callback2.WaitForResult());
2620 EXPECT_EQ(OK, callback3.WaitForResult());
2621
2622 // Use the socket.
2623 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2624 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2625
2626 handle1.Reset();
2627 handle2.Reset();
2628 handle3.Reset();
2629
2630 EXPECT_EQ(OK, handle1.Init("a",
2631 params_,
2632 kDefaultPriority,
2633 &callback1,
2634 pool_.get(),
2635 BoundNetLog()));
2636 EXPECT_EQ(OK, handle2.Init("a",
2637 params_,
2638 kDefaultPriority,
2639 &callback2,
2640 pool_.get(),
2641 BoundNetLog()));
2642 EXPECT_EQ(OK, handle3.Init("a",
2643 params_,
2644 kDefaultPriority,
2645 &callback3,
2646 pool_.get(),
2647 BoundNetLog()));
2648
2649 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2650 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2651 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2652}
2653
[email protected]2c2bef152010-10-13 00:55:032654TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2655 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2656 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2657
2658 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2659
2660 ASSERT_TRUE(pool_->HasGroup("a"));
2661 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2662 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2663
2664 ClientSocketHandle handle1;
2665 TestCompletionCallback callback1;
2666 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2667 params_,
2668 kDefaultPriority,
2669 &callback1,
2670 pool_.get(),
2671 BoundNetLog()));
2672
2673 ClientSocketHandle handle2;
2674 TestCompletionCallback callback2;
2675 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2676 params_,
2677 kDefaultPriority,
2678 &callback2,
2679 pool_.get(),
2680 BoundNetLog()));
2681
2682 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2683 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2684
2685 EXPECT_EQ(OK, callback1.WaitForResult());
2686 EXPECT_EQ(OK, callback2.WaitForResult());
2687 handle1.Reset();
2688 handle2.Reset();
2689
2690 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2691 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2692}
2693
2694TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2695 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2696 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2697
2698 ClientSocketHandle handle1;
2699 TestCompletionCallback callback1;
2700 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2701 params_,
2702 kDefaultPriority,
2703 &callback1,
2704 pool_.get(),
2705 BoundNetLog()));
2706
2707 ASSERT_TRUE(pool_->HasGroup("a"));
2708 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2709 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2710
2711 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2712
2713 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2714 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2715
2716 ClientSocketHandle handle2;
2717 TestCompletionCallback callback2;
2718 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2719 params_,
2720 kDefaultPriority,
2721 &callback2,
2722 pool_.get(),
2723 BoundNetLog()));
2724
2725 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2726 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2727
2728 EXPECT_EQ(OK, callback1.WaitForResult());
2729 EXPECT_EQ(OK, callback2.WaitForResult());
2730 handle1.Reset();
2731 handle2.Reset();
2732
2733 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2734 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2735}
2736
2737TEST_F(ClientSocketPoolBaseTest,
2738 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2739 CreatePool(4, 4);
2740 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2741
2742 ClientSocketHandle handle1;
2743 TestCompletionCallback callback1;
2744 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2745 params_,
2746 kDefaultPriority,
2747 &callback1,
2748 pool_.get(),
2749 BoundNetLog()));
2750
2751 ClientSocketHandle handle2;
2752 TestCompletionCallback callback2;
2753 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2754 params_,
2755 kDefaultPriority,
2756 &callback2,
2757 pool_.get(),
2758 BoundNetLog()));
2759
2760 ClientSocketHandle handle3;
2761 TestCompletionCallback callback3;
2762 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2763 params_,
2764 kDefaultPriority,
2765 &callback3,
2766 pool_.get(),
2767 BoundNetLog()));
2768
2769 ASSERT_TRUE(pool_->HasGroup("a"));
2770 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2771 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2772
2773 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2774
2775 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2776 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2777
2778 EXPECT_EQ(OK, callback1.WaitForResult());
2779 EXPECT_EQ(OK, callback2.WaitForResult());
2780 EXPECT_EQ(OK, callback3.WaitForResult());
2781 handle1.Reset();
2782 handle2.Reset();
2783 handle3.Reset();
2784
2785 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2786 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2787}
2788
2789TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2790 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2791 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2792
2793 ASSERT_FALSE(pool_->HasGroup("a"));
2794
2795 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2796 BoundNetLog());
2797
2798 ASSERT_TRUE(pool_->HasGroup("a"));
2799 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2800
2801 ASSERT_FALSE(pool_->HasGroup("b"));
2802
2803 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2804 BoundNetLog());
2805
2806 ASSERT_FALSE(pool_->HasGroup("b"));
2807}
2808
2809TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2810 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2811 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2812
2813 ASSERT_FALSE(pool_->HasGroup("a"));
2814
2815 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2816 BoundNetLog());
2817
2818 ASSERT_TRUE(pool_->HasGroup("a"));
2819 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2820
2821 ASSERT_FALSE(pool_->HasGroup("b"));
2822
2823 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2824 BoundNetLog());
2825
2826 ASSERT_TRUE(pool_->HasGroup("b"));
2827 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2828}
2829
2830TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2831 CreatePool(4, 4);
2832 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2833
2834 ClientSocketHandle handle1;
2835 TestCompletionCallback callback1;
2836 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2837 params_,
2838 kDefaultPriority,
2839 &callback1,
2840 pool_.get(),
2841 BoundNetLog()));
2842 ASSERT_EQ(OK, callback1.WaitForResult());
2843 handle1.Reset();
2844
2845 ASSERT_TRUE(pool_->HasGroup("a"));
2846 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2847 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2848
2849 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2850
2851 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2852 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2853}
2854
2855TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2856 CreatePool(4, 4);
2857 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2858
2859 ClientSocketHandle handle1;
2860 TestCompletionCallback callback1;
2861 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2862 params_,
2863 kDefaultPriority,
2864 &callback1,
2865 pool_.get(),
2866 BoundNetLog()));
2867 ASSERT_EQ(OK, callback1.WaitForResult());
2868
2869 ASSERT_TRUE(pool_->HasGroup("a"));
2870 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2871 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2872 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2873
2874 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2875
2876 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2877 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2878 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2879}
2880
2881TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2882 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2883 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2884
2885 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2886 BoundNetLog());
2887
2888 ASSERT_TRUE(pool_->HasGroup("a"));
2889 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2890 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2891
2892 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2893 BoundNetLog());
2894
2895 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2896 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2897}
2898
2899TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2900 CreatePool(4, 4);
2901 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2902
2903 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2904
2905 ASSERT_TRUE(pool_->HasGroup("a"));
2906 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2907 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2908
2909 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2910 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2911 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2912
2913 ClientSocketHandle handle1;
2914 TestCompletionCallback callback1;
2915 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2916 params_,
2917 kDefaultPriority,
2918 &callback1,
2919 pool_.get(),
2920 BoundNetLog()));
2921 ASSERT_EQ(OK, callback1.WaitForResult());
2922
2923 ClientSocketHandle handle2;
2924 TestCompletionCallback callback2;
2925 int rv = handle2.Init("a",
2926 params_,
2927 kDefaultPriority,
2928 &callback2,
2929 pool_.get(),
2930 BoundNetLog());
2931 if (rv != OK) {
2932 EXPECT_EQ(ERR_IO_PENDING, rv);
2933 EXPECT_EQ(OK, callback2.WaitForResult());
2934 }
2935
2936 handle1.Reset();
2937 handle2.Reset();
2938
2939 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2940
2941 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2942 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2943 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2944}
2945
2946TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2947 CreatePool(4, 4);
2948 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2949
2950 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2951
2952 ASSERT_TRUE(pool_->HasGroup("a"));
2953 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2954 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2955
2956 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2957 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2958 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2959
2960 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2961 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2962 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2963
2964 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2965 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2966 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2967}
2968
2969TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
2970 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2971 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2972
2973 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2974
2975 ASSERT_TRUE(pool_->HasGroup("a"));
2976 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2977 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2978
2979 ClientSocketHandle handle1;
2980 TestCompletionCallback callback1;
2981 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2982 params_,
2983 kDefaultPriority,
2984 &callback1,
2985 pool_.get(),
2986 BoundNetLog()));
2987
2988 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2989 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2990
2991 ASSERT_EQ(OK, callback1.WaitForResult());
2992
2993 handle1.Reset();
2994
2995 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2996}
2997
[email protected]f6d1d6eb2009-06-24 20:16:092998} // namespace
2999
3000} // namespace net