blob: 7cf35e3cff45b99c6768448ec605c8ed3909818e [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]7f7e92392010-10-26 18:29:2984 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]9b5614a2010-08-25 20:29:4585
[email protected]f6d1d6eb2009-06-24 20:16:0986 private:
87 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0288 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0189 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0990
[email protected]ab838892009-06-30 18:49:0591 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0992};
93
[email protected]5fc08e32009-07-15 17:09:5794class TestConnectJob;
95
[email protected]f6d1d6eb2009-06-24 20:16:0996class MockClientSocketFactory : public ClientSocketFactory {
97 public:
[email protected]ab838892009-06-30 18:49:0598 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0999
[email protected]0a0b7682010-08-25 17:08:07100 virtual ClientSocket* CreateTCPClientSocket(
101 const AddressList& addresses,
102 NetLog* /* net_log */,
103 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09104 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05105 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09106 }
107
108 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18109 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:09110 const std::string& hostname,
[email protected]7ab5bbd12010-10-19 13:33:21111 const SSLConfig& ssl_config,
112 SSLHostInfo* ssl_host_info) {
[email protected]f6d1d6eb2009-06-24 20:16:09113 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21114 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09115 return NULL;
116 }
117
[email protected]5fc08e32009-07-15 17:09:57118 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
119 void SignalJobs();
120
[email protected]f6d1d6eb2009-06-24 20:16:09121 int allocation_count() const { return allocation_count_; }
122
[email protected]f6d1d6eb2009-06-24 20:16:09123 private:
124 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57125 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09126};
127
[email protected]ab838892009-06-30 18:49:05128class TestConnectJob : public ConnectJob {
129 public:
130 enum JobType {
131 kMockJob,
132 kMockFailingJob,
133 kMockPendingJob,
134 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57135 kMockWaitingJob,
136 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13137 kMockRecoverableJob,
138 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18139 kMockAdditionalErrorStateJob,
140 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05141 };
142
[email protected]994d4932010-07-12 17:55:13143 // The kMockPendingJob uses a slight delay before allowing the connect
144 // to complete.
145 static const int kPendingConnectDelay = 2;
146
[email protected]ab838892009-06-30 18:49:05147 TestConnectJob(JobType job_type,
148 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49149 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34150 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05151 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30152 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17153 NetLog* net_log)
154 : ConnectJob(group_name, timeout_duration, delegate,
155 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58156 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05157 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21158 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18159 load_state_(LOAD_STATE_IDLE),
160 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05161
[email protected]974ebd62009-08-03 23:14:34162 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13163 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34164 }
165
[email protected]46451352009-09-01 14:54:21166 virtual LoadState GetLoadState() const { return load_state_; }
167
[email protected]e60e47a2010-07-14 03:37:18168 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
169 if (store_additional_error_state_) {
170 // Set all of the additional error state fields in some way.
171 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43172 HttpResponseInfo info;
173 info.headers = new HttpResponseHeaders("");
174 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18175 }
176 }
177
[email protected]974ebd62009-08-03 23:14:34178 private:
[email protected]ab838892009-06-30 18:49:05179 // ConnectJob methods:
180
[email protected]974ebd62009-08-03 23:14:34181 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05182 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07183 client_socket_factory_->CreateTCPClientSocket(
184 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40185 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05186 switch (job_type_) {
187 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13188 return DoConnect(true /* successful */, false /* sync */,
189 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05190 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13191 return DoConnect(false /* error */, false /* sync */,
192 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05193 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57194 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47195
196 // Depending on execution timings, posting a delayed task can result
197 // in the task getting executed the at the earliest possible
198 // opportunity or only after returning once from the message loop and
199 // then a second call into the message loop. In order to make behavior
200 // more deterministic, we change the default delay to 2ms. This should
201 // always require us to wait for the second call into the message loop.
202 //
203 // N.B. The correct fix for this and similar timing problems is to
204 // abstract time for the purpose of unittests. Unfortunately, we have
205 // a lot of third-party components that directly call the various
206 // time functions, so this change would be rather invasive.
207 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05208 FROM_HERE,
209 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47210 &TestConnectJob::DoConnect,
211 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13212 true /* async */,
213 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13214 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05215 return ERR_IO_PENDING;
216 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57217 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47218 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05219 FROM_HERE,
220 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47221 &TestConnectJob::DoConnect,
222 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13223 true /* async */,
224 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47225 2);
[email protected]ab838892009-06-30 18:49:05226 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57227 case kMockWaitingJob:
228 client_socket_factory_->WaitForSignal(this);
229 waiting_success_ = true;
230 return ERR_IO_PENDING;
231 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46232 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57233 FROM_HERE,
234 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46235 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57236 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13237 case kMockRecoverableJob:
238 return DoConnect(false /* error */, false /* sync */,
239 true /* recoverable */);
240 case kMockPendingRecoverableJob:
241 set_load_state(LOAD_STATE_CONNECTING);
242 MessageLoop::current()->PostDelayedTask(
243 FROM_HERE,
244 method_factory_.NewRunnableMethod(
245 &TestConnectJob::DoConnect,
246 false /* error */,
247 true /* async */,
248 true /* recoverable */),
249 2);
250 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18251 case kMockAdditionalErrorStateJob:
252 store_additional_error_state_ = true;
253 return DoConnect(false /* error */, false /* sync */,
254 false /* recoverable */);
255 case kMockPendingAdditionalErrorStateJob:
256 set_load_state(LOAD_STATE_CONNECTING);
257 store_additional_error_state_ = true;
258 MessageLoop::current()->PostDelayedTask(
259 FROM_HERE,
260 method_factory_.NewRunnableMethod(
261 &TestConnectJob::DoConnect,
262 false /* error */,
263 true /* async */,
264 false /* recoverable */),
265 2);
266 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05267 default:
268 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40269 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05270 return ERR_FAILED;
271 }
272 }
273
[email protected]46451352009-09-01 14:54:21274 void set_load_state(LoadState load_state) { load_state_ = load_state; }
275
[email protected]e772db3f2010-07-12 18:11:13276 int DoConnect(bool succeed, bool was_async, bool recoverable) {
277 int result = OK;
[email protected]ab838892009-06-30 18:49:05278 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02279 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13280 } else if (recoverable) {
281 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40282 } else {
[email protected]e772db3f2010-07-12 18:11:13283 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40284 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05285 }
[email protected]2ab05b52009-07-01 23:57:58286
287 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30288 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05289 return result;
290 }
291
[email protected]cfa8228c2010-06-17 01:07:56292 // This function helps simulate the progress of load states on a ConnectJob.
293 // Each time it is called it advances the load state and posts a task to be
294 // called again. It stops at the last connecting load state (the one
295 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57296 void AdvanceLoadState(LoadState state) {
297 int tmp = state;
298 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56299 if (tmp < LOAD_STATE_SENDING_REQUEST) {
300 state = static_cast<LoadState>(tmp);
301 set_load_state(state);
302 MessageLoop::current()->PostTask(
303 FROM_HERE,
304 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
305 state));
306 }
[email protected]5fc08e32009-07-15 17:09:57307 }
308
309 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05310 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57311 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05312 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21313 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18314 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05315
316 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
317};
318
[email protected]d80a4322009-08-14 07:07:49319class TestConnectJobFactory
320 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05321 public:
[email protected]5fc08e32009-07-15 17:09:57322 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05323 : job_type_(TestConnectJob::kMockJob),
324 client_socket_factory_(client_socket_factory) {}
325
326 virtual ~TestConnectJobFactory() {}
327
328 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
329
[email protected]974ebd62009-08-03 23:14:34330 void set_timeout_duration(base::TimeDelta timeout_duration) {
331 timeout_duration_ = timeout_duration;
332 }
333
[email protected]ab838892009-06-30 18:49:05334 // ConnectJobFactory methods:
335
336 virtual ConnectJob* NewConnectJob(
337 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49338 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17339 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05340 return new TestConnectJob(job_type_,
341 group_name,
342 request,
[email protected]974ebd62009-08-03 23:14:34343 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05344 delegate,
[email protected]fd7b7c92009-08-20 19:38:30345 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17346 NULL);
[email protected]ab838892009-06-30 18:49:05347 }
348
[email protected]a796bcec2010-03-22 17:17:26349 virtual base::TimeDelta ConnectionTimeout() const {
350 return timeout_duration_;
351 }
352
[email protected]ab838892009-06-30 18:49:05353 private:
354 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34355 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57356 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05357
358 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
359};
360
361class TestClientSocketPool : public ClientSocketPool {
362 public:
363 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53364 int max_sockets,
[email protected]ab838892009-06-30 18:49:05365 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13366 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16367 base::TimeDelta unused_idle_socket_timeout,
368 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49369 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00370 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16371 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38372 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05373
[email protected]2431756e2010-09-29 20:26:13374 virtual ~TestClientSocketPool() {}
375
[email protected]ab838892009-06-30 18:49:05376 virtual int RequestSocket(
377 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49378 const void* params,
[email protected]ac790b42009-12-02 04:31:31379 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05380 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46381 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53382 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21383 const scoped_refptr<TestSocketParams>* casted_socket_params =
384 static_cast<const scoped_refptr<TestSocketParams>*>(params);
385 return base_.RequestSocket(group_name, *casted_socket_params, priority,
386 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05387 }
388
[email protected]2c2bef152010-10-13 00:55:03389 virtual void RequestSockets(const std::string& group_name,
390 const void* params,
391 int num_sockets,
392 const BoundNetLog& net_log) {
393 const scoped_refptr<TestSocketParams>* casted_params =
394 static_cast<const scoped_refptr<TestSocketParams>*>(params);
395
396 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
397 }
398
[email protected]ab838892009-06-30 18:49:05399 virtual void CancelRequest(
400 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21401 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49402 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05403 }
404
405 virtual void ReleaseSocket(
406 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24407 ClientSocket* socket,
408 int id) {
409 base_.ReleaseSocket(group_name, socket, id);
410 }
411
412 virtual void Flush() {
413 base_.Flush();
[email protected]ab838892009-06-30 18:49:05414 }
415
416 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49417 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05418 }
419
[email protected]d80a4322009-08-14 07:07:49420 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05421
422 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49423 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05424 }
425
426 virtual LoadState GetLoadState(const std::string& group_name,
427 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49428 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05429 }
430
[email protected]ba00b492010-09-08 14:53:38431 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
432 const std::string& type,
433 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27434 return base_.GetInfoAsValue(name, type);
435 }
436
[email protected]a796bcec2010-03-22 17:17:26437 virtual base::TimeDelta ConnectionTimeout() const {
438 return base_.ConnectionTimeout();
439 }
440
[email protected]2431756e2010-09-29 20:26:13441 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00442 return base_.histograms();
443 }
[email protected]a796bcec2010-03-22 17:17:26444
[email protected]d80a4322009-08-14 07:07:49445 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20446
[email protected]974ebd62009-08-03 23:14:34447 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49448 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34449 }
450
[email protected]2c2bef152010-10-13 00:55:03451 int NumActiveSocketsInGroup(const std::string& group_name) const {
452 return base_.NumActiveSocketsInGroup(group_name);
453 }
454
[email protected]2abfe90a2010-08-25 17:49:51455 bool HasGroup(const std::string& group_name) const {
456 return base_.HasGroup(group_name);
457 }
458
[email protected]9bf28db2009-08-29 01:35:16459 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
460
[email protected]06d94042010-08-25 01:45:22461 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54462
[email protected]ab838892009-06-30 18:49:05463 private:
[email protected]d80a4322009-08-14 07:07:49464 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05465
466 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
467};
468
[email protected]a937a06d2009-08-19 21:19:24469} // namespace
470
[email protected]7fc5b09a2010-02-27 00:07:38471REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24472
473namespace {
474
[email protected]5fc08e32009-07-15 17:09:57475void MockClientSocketFactory::SignalJobs() {
476 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
477 it != waiting_jobs_.end(); ++it) {
478 (*it)->Signal();
479 }
480 waiting_jobs_.clear();
481}
482
[email protected]974ebd62009-08-03 23:14:34483class TestConnectJobDelegate : public ConnectJob::Delegate {
484 public:
485 TestConnectJobDelegate()
486 : have_result_(false), waiting_for_result_(false), result_(OK) {}
487 virtual ~TestConnectJobDelegate() {}
488
489 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
490 result_ = result;
[email protected]6e713f02009-08-06 02:56:40491 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07492 // socket.get() should be NULL iff result != OK
493 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34494 delete job;
495 have_result_ = true;
496 if (waiting_for_result_)
497 MessageLoop::current()->Quit();
498 }
499
500 int WaitForResult() {
501 DCHECK(!waiting_for_result_);
502 while (!have_result_) {
503 waiting_for_result_ = true;
504 MessageLoop::current()->Run();
505 waiting_for_result_ = false;
506 }
507 have_result_ = false; // auto-reset for next callback
508 return result_;
509 }
510
511 private:
512 bool have_result_;
513 bool waiting_for_result_;
514 int result_;
515};
516
[email protected]2431756e2010-09-29 20:26:13517class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09518 protected:
[email protected]b89f7e42010-05-20 20:37:00519 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21520 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13521 histograms_("ClientSocketPoolTest") {}
522
523 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20524
[email protected]211d21722009-07-22 15:48:53525 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16526 CreatePoolWithIdleTimeouts(
527 max_sockets,
528 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00529 base::TimeDelta::FromSeconds(
530 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16531 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
532 }
533
534 void CreatePoolWithIdleTimeouts(
535 int max_sockets, int max_sockets_per_group,
536 base::TimeDelta unused_idle_socket_timeout,
537 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20538 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04539 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13540 pool_.reset(new TestClientSocketPool(max_sockets,
541 max_sockets_per_group,
542 &histograms_,
543 unused_idle_socket_timeout,
544 used_idle_socket_timeout,
545 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20546 }
[email protected]f6d1d6eb2009-06-24 20:16:09547
[email protected]ac790b42009-12-02 04:31:31548 int StartRequest(const std::string& group_name,
549 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13550 return test_base_.StartRequestUsingPool<
551 TestClientSocketPool, TestSocketParams>(
552 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09553 }
554
[email protected]2431756e2010-09-29 20:26:13555 int GetOrderOfRequest(size_t index) const {
556 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09557 }
558
[email protected]2431756e2010-09-29 20:26:13559 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
560 return test_base_.ReleaseOneConnection(keep_alive);
561 }
562
563 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
564 test_base_.ReleaseAllConnections(keep_alive);
565 }
566
567 TestSocketRequest* request(int i) { return test_base_.request(i); }
568 size_t requests_size() const { return test_base_.requests_size(); }
569 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
570 size_t completion_count() const { return test_base_.completion_count(); }
571
[email protected]f6d1d6eb2009-06-24 20:16:09572 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04573 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21574 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13575 ClientSocketPoolHistograms histograms_;
576 scoped_ptr<TestClientSocketPool> pool_;
577 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09578};
579
[email protected]974ebd62009-08-03 23:14:34580// Even though a timeout is specified, it doesn't time out on a synchronous
581// completion.
582TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
583 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06584 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49585 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03586 &ignored, NULL, kDefaultPriority,
587 internal::ClientSocketPoolBaseHelper::NORMAL,
588 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34589 scoped_ptr<TestConnectJob> job(
590 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12591 "a",
[email protected]974ebd62009-08-03 23:14:34592 request,
593 base::TimeDelta::FromMicroseconds(1),
594 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30595 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17596 NULL));
[email protected]974ebd62009-08-03 23:14:34597 EXPECT_EQ(OK, job->Connect());
598}
599
600TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
601 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06602 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17603 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53604
[email protected]d80a4322009-08-14 07:07:49605 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03606 &ignored, NULL, kDefaultPriority,
607 internal::ClientSocketPoolBaseHelper::NORMAL,
608 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34609 // Deleted by TestConnectJobDelegate.
610 TestConnectJob* job =
611 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12612 "a",
[email protected]974ebd62009-08-03 23:14:34613 request,
614 base::TimeDelta::FromMicroseconds(1),
615 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30616 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17617 &log);
[email protected]974ebd62009-08-03 23:14:34618 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
619 PlatformThread::Sleep(1);
620 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30621
[email protected]06650c52010-06-03 00:49:17622 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46623 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53624 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17625 EXPECT_TRUE(LogContainsBeginEvent(
626 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46627 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17628 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
629 NetLog::PHASE_NONE));
630 EXPECT_TRUE(LogContainsEvent(
631 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53632 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46633 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17634 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
635 EXPECT_TRUE(LogContainsEndEvent(
636 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34637}
638
[email protected]5fc08e32009-07-15 17:09:57639TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53640 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20641
[email protected]f6d1d6eb2009-06-24 20:16:09642 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06643 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53644 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
645
[email protected]2431756e2010-09-29 20:26:13646 EXPECT_EQ(OK,
647 handle.Init("a",
648 params_,
649 kDefaultPriority,
650 &callback,
651 pool_.get(),
652 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09653 EXPECT_TRUE(handle.is_initialized());
654 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09655 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30656
[email protected]06650c52010-06-03 00:49:17657 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46658 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53659 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53660 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17661 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
662 NetLog::PHASE_NONE));
663 EXPECT_TRUE(LogContainsEvent(
664 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53665 NetLog::PHASE_NONE));
666 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17667 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09668}
669
[email protected]ab838892009-06-30 18:49:05670TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53671 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20672
[email protected]ab838892009-06-30 18:49:05673 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53674 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
675
[email protected]2431756e2010-09-29 20:26:13676 ClientSocketHandle handle;
677 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18678 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13679 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43680 HttpResponseInfo info;
681 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13682 handle.set_ssl_error_response_info(info);
683 EXPECT_EQ(ERR_CONNECTION_FAILED,
684 handle.Init("a",
685 params_,
686 kDefaultPriority,
687 &callback,
688 pool_.get(),
689 log.bound()));
690 EXPECT_FALSE(handle.socket());
691 EXPECT_FALSE(handle.is_ssl_error());
692 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30693
[email protected]06650c52010-06-03 00:49:17694 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27695 EXPECT_TRUE(LogContainsBeginEvent(
696 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17697 EXPECT_TRUE(LogContainsEvent(
698 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
699 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02700 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17701 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09702}
703
[email protected]211d21722009-07-22 15:48:53704TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
705 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
706
[email protected]9e743cd2010-03-16 07:03:53707 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30708
[email protected]211d21722009-07-22 15:48:53709 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
710 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
711 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
712 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
713
[email protected]2431756e2010-09-29 20:26:13714 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53715 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13716 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53717
718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
719 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
720 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
721
[email protected]2431756e2010-09-29 20:26:13722 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53723
[email protected]2431756e2010-09-29 20:26:13724 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53725 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13726 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53727
728 EXPECT_EQ(1, GetOrderOfRequest(1));
729 EXPECT_EQ(2, GetOrderOfRequest(2));
730 EXPECT_EQ(3, GetOrderOfRequest(3));
731 EXPECT_EQ(4, GetOrderOfRequest(4));
732 EXPECT_EQ(5, GetOrderOfRequest(5));
733 EXPECT_EQ(6, GetOrderOfRequest(6));
734 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17735
736 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13737 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53738}
739
740TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
741 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
742
[email protected]9e743cd2010-03-16 07:03:53743 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30744
[email protected]211d21722009-07-22 15:48:53745 // Reach all limits: max total sockets, and max sockets per group.
746 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
747 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
748 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
749 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
750
[email protected]2431756e2010-09-29 20:26:13751 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53752 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13753 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53754
755 // Now create a new group and verify that we don't starve it.
756 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
757
[email protected]2431756e2010-09-29 20:26:13758 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53759
[email protected]2431756e2010-09-29 20:26:13760 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53761 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13762 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53763
764 EXPECT_EQ(1, GetOrderOfRequest(1));
765 EXPECT_EQ(2, GetOrderOfRequest(2));
766 EXPECT_EQ(3, GetOrderOfRequest(3));
767 EXPECT_EQ(4, GetOrderOfRequest(4));
768 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17769
770 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13771 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53772}
773
774TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
775 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
776
[email protected]ac790b42009-12-02 04:31:31777 EXPECT_EQ(OK, StartRequest("b", LOWEST));
778 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
779 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
780 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53781
[email protected]2431756e2010-09-29 20:26:13782 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53783 client_socket_factory_.allocation_count());
784
[email protected]ac790b42009-12-02 04:31:31785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
787 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53788
[email protected]2431756e2010-09-29 20:26:13789 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53790
[email protected]2431756e2010-09-29 20:26:13791 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53792
793 // First 4 requests don't have to wait, and finish in order.
794 EXPECT_EQ(1, GetOrderOfRequest(1));
795 EXPECT_EQ(2, GetOrderOfRequest(2));
796 EXPECT_EQ(3, GetOrderOfRequest(3));
797 EXPECT_EQ(4, GetOrderOfRequest(4));
798
[email protected]ac790b42009-12-02 04:31:31799 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
800 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53801 EXPECT_EQ(7, GetOrderOfRequest(5));
802 EXPECT_EQ(6, GetOrderOfRequest(6));
803 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17804
805 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13806 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53807}
808
809TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
810 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
811
[email protected]ac790b42009-12-02 04:31:31812 EXPECT_EQ(OK, StartRequest("a", LOWEST));
813 EXPECT_EQ(OK, StartRequest("a", LOW));
814 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
815 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53816
[email protected]2431756e2010-09-29 20:26:13817 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53818 client_socket_factory_.allocation_count());
819
[email protected]ac790b42009-12-02 04:31:31820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
822 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53823
[email protected]2431756e2010-09-29 20:26:13824 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53825
[email protected]2431756e2010-09-29 20:26:13826 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53827 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13828 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53829
830 // First 4 requests don't have to wait, and finish in order.
831 EXPECT_EQ(1, GetOrderOfRequest(1));
832 EXPECT_EQ(2, GetOrderOfRequest(2));
833 EXPECT_EQ(3, GetOrderOfRequest(3));
834 EXPECT_EQ(4, GetOrderOfRequest(4));
835
836 // Request ("b", 7) has the highest priority, but we can't make new socket for
837 // group "b", because it has reached the per-group limit. Then we make
838 // socket for ("c", 6), because it has higher priority than ("a", 4),
839 // and we still can't make a socket for group "b".
840 EXPECT_EQ(5, GetOrderOfRequest(5));
841 EXPECT_EQ(6, GetOrderOfRequest(6));
842 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17843
844 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13845 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53846}
847
848// Make sure that we count connecting sockets against the total limit.
849TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
851
852 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
853 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
854 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
855
856 // Create one asynchronous request.
857 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
858 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
859
[email protected]6b175382009-10-13 06:47:47860 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
861 // actually become pending until 2ms after they have been created. In order
862 // to flush all tasks, we need to wait so that we know there are no
863 // soon-to-be-pending tasks waiting.
864 PlatformThread::Sleep(10);
865 MessageLoop::current()->RunAllPending();
866
[email protected]211d21722009-07-22 15:48:53867 // The next synchronous request should wait for its turn.
868 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
870
[email protected]2431756e2010-09-29 20:26:13871 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53872
[email protected]2431756e2010-09-29 20:26:13873 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53874 client_socket_factory_.allocation_count());
875
876 EXPECT_EQ(1, GetOrderOfRequest(1));
877 EXPECT_EQ(2, GetOrderOfRequest(2));
878 EXPECT_EQ(3, GetOrderOfRequest(3));
879 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17880 EXPECT_EQ(5, GetOrderOfRequest(5));
881
882 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13883 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53884}
885
[email protected]6427fe22010-04-16 22:27:41886TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
887 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
888 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
889
890 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
891 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
892 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
893 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
894
895 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
896
897 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
898
899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
900 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
901
902 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
903
[email protected]2431756e2010-09-29 20:26:13904 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41905 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13906 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41907 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13908 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
909 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41910 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
911}
912
[email protected]d7027bb2010-05-10 18:58:54913TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
914 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
915 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
916
917 ClientSocketHandle handle;
918 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_EQ(ERR_IO_PENDING,
920 handle.Init("a",
921 params_,
922 kDefaultPriority,
923 &callback,
924 pool_.get(),
925 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54926
927 ClientSocketHandle handles[4];
928 for (size_t i = 0; i < arraysize(handles); ++i) {
929 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13930 EXPECT_EQ(ERR_IO_PENDING,
931 handles[i].Init("b",
932 params_,
933 kDefaultPriority,
934 &callback,
935 pool_.get(),
936 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54937 }
938
939 // One will be stalled, cancel all the handles now.
940 // This should hit the OnAvailableSocketSlot() code where we previously had
941 // stalled groups, but no longer have any.
942 for (size_t i = 0; i < arraysize(handles); ++i)
943 handles[i].Reset();
944}
945
[email protected]eb5a99382010-07-11 03:18:26946TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54947 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
948 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
949
[email protected]eb5a99382010-07-11 03:18:26950 {
951 ClientSocketHandle handles[kDefaultMaxSockets];
952 TestCompletionCallback callbacks[kDefaultMaxSockets];
953 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13954 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
955 params_,
[email protected]e83326f2010-07-31 17:29:25956 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13957 &callbacks[i],
958 pool_.get(),
959 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26960 }
961
962 // Force a stalled group.
963 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54964 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13965 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
966 params_,
967 kDefaultPriority,
968 &callback,
969 pool_.get(),
970 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26971
972 // Cancel the stalled request.
973 stalled_handle.Reset();
974
975 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
976 EXPECT_EQ(0, pool_->IdleSocketCount());
977
978 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54979 }
980
[email protected]43a21b82010-06-10 21:30:54981 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
982 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26983}
[email protected]43a21b82010-06-10 21:30:54984
[email protected]eb5a99382010-07-11 03:18:26985TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
986 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
987 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
988
989 {
990 ClientSocketHandle handles[kDefaultMaxSockets];
991 for (int i = 0; i < kDefaultMaxSockets; ++i) {
992 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13993 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
994 params_,
995 kDefaultPriority,
996 &callback,
997 pool_.get(),
998 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26999 }
1000
1001 // Force a stalled group.
1002 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1003 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541004 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131005 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1006 params_,
1007 kDefaultPriority,
1008 &callback,
1009 pool_.get(),
1010 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261011
1012 // Since it is stalled, it should have no connect jobs.
1013 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1014
1015 // Cancel the stalled request.
1016 handles[0].Reset();
1017
[email protected]eb5a99382010-07-11 03:18:261018 // Now we should have a connect job.
1019 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1020
1021 // The stalled socket should connect.
1022 EXPECT_EQ(OK, callback.WaitForResult());
1023
1024 EXPECT_EQ(kDefaultMaxSockets + 1,
1025 client_socket_factory_.allocation_count());
1026 EXPECT_EQ(0, pool_->IdleSocketCount());
1027 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1028
1029 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541030 }
1031
[email protected]eb5a99382010-07-11 03:18:261032 EXPECT_EQ(1, pool_->IdleSocketCount());
1033}
[email protected]43a21b82010-06-10 21:30:541034
[email protected]eb5a99382010-07-11 03:18:261035TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1036 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1037 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541038
[email protected]eb5a99382010-07-11 03:18:261039 ClientSocketHandle stalled_handle;
1040 TestCompletionCallback callback;
1041 {
1042 ClientSocketHandle handles[kDefaultMaxSockets];
1043 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1044 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061045 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131046 params_,
1047 kDefaultPriority,
1048 &callback,
1049 pool_.get(),
1050 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261051 }
1052
1053 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1054 EXPECT_EQ(0, pool_->IdleSocketCount());
1055
1056 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131057 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1058 params_,
1059 kDefaultPriority,
1060 &callback,
1061 pool_.get(),
1062 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261063
1064 // Dropping out of scope will close all handles and return them to idle.
1065 }
[email protected]43a21b82010-06-10 21:30:541066
1067 // But if we wait for it, the released idle sockets will be closed in
1068 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101069 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261070
1071 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1072 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541073}
1074
1075// Regression test for http://crbug.com/40952.
1076TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1077 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221078 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541079 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1080
1081 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1082 ClientSocketHandle handle;
1083 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131084 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1085 params_,
1086 kDefaultPriority,
1087 &callback,
1088 pool_.get(),
1089 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541090 }
1091
1092 // Flush all the DoReleaseSocket tasks.
1093 MessageLoop::current()->RunAllPending();
1094
1095 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1096 // reuse a socket.
1097 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1098 ClientSocketHandle handle;
1099 TestCompletionCallback callback;
1100
1101 // "0" is special here, since it should be the first entry in the sorted map,
1102 // which is the one which we would close an idle socket for. We shouldn't
1103 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131104 EXPECT_EQ(OK, handle.Init("0",
1105 params_,
1106 kDefaultPriority,
1107 &callback,
1108 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211109 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541110
1111 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1112 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1113}
1114
[email protected]ab838892009-06-30 18:49:051115TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531116 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091117
[email protected]c9d6a1d2009-07-14 16:15:201118 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1119 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031120 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311121 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1122 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1123 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1124 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1125 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091126
[email protected]2431756e2010-09-29 20:26:131127 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091128
[email protected]c9d6a1d2009-07-14 16:15:201129 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1130 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131131 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1132 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091133
[email protected]c9d6a1d2009-07-14 16:15:201134 EXPECT_EQ(1, GetOrderOfRequest(1));
1135 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031136 EXPECT_EQ(8, GetOrderOfRequest(3));
1137 EXPECT_EQ(6, GetOrderOfRequest(4));
1138 EXPECT_EQ(4, GetOrderOfRequest(5));
1139 EXPECT_EQ(3, GetOrderOfRequest(6));
1140 EXPECT_EQ(5, GetOrderOfRequest(7));
1141 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171142
1143 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131144 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091145}
1146
[email protected]ab838892009-06-30 18:49:051147TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531148 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091149
[email protected]c9d6a1d2009-07-14 16:15:201150 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1151 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311152 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1155 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1156 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091157
[email protected]2431756e2010-09-29 20:26:131158 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091159
[email protected]2431756e2010-09-29 20:26:131160 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1161 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201162
[email protected]2431756e2010-09-29 20:26:131163 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201164 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131165 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1166 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091167}
1168
1169// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051170// The pending connect job will be cancelled and should not call back into
1171// ClientSocketPoolBase.
1172TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531173 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201174
[email protected]ab838892009-06-30 18:49:051175 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131176 ClientSocketHandle handle;
1177 TestCompletionCallback callback;
1178 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1179 params_,
1180 kDefaultPriority,
1181 &callback,
1182 pool_.get(),
1183 BoundNetLog()));
1184 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091185}
1186
[email protected]ab838892009-06-30 18:49:051187TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531188 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201189
[email protected]ab838892009-06-30 18:49:051190 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061191 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091192 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091193
[email protected]2431756e2010-09-29 20:26:131194 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1195 params_,
1196 kDefaultPriority,
1197 &callback,
1198 pool_.get(),
1199 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091200
1201 handle.Reset();
1202
1203 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131204 EXPECT_EQ(ERR_IO_PENDING,
1205 handle.Init("a",
1206 params_,
1207 kDefaultPriority,
1208 &callback2,
1209 pool_.get(),
1210 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091211
1212 EXPECT_EQ(OK, callback2.WaitForResult());
1213 EXPECT_FALSE(callback.have_result());
1214
1215 handle.Reset();
1216}
1217
[email protected]ab838892009-06-30 18:49:051218TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091220
[email protected]c9d6a1d2009-07-14 16:15:201221 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1222 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1227 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091228
1229 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201230 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131231 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1232 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091233
[email protected]2431756e2010-09-29 20:26:131234 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091235
[email protected]c9d6a1d2009-07-14 16:15:201236 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1237 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131238 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1239 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091240
[email protected]c9d6a1d2009-07-14 16:15:201241 EXPECT_EQ(1, GetOrderOfRequest(1));
1242 EXPECT_EQ(2, GetOrderOfRequest(2));
1243 EXPECT_EQ(5, GetOrderOfRequest(3));
1244 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131245 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1246 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201247 EXPECT_EQ(4, GetOrderOfRequest(6));
1248 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171249
1250 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131251 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091252}
1253
1254class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1255 public:
[email protected]2ab05b52009-07-01 23:57:581256 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241257 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581258 TestConnectJobFactory* test_connect_job_factory,
1259 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091260 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061261 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581262 within_callback_(false),
1263 test_connect_job_factory_(test_connect_job_factory),
1264 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091265
1266 virtual void RunWithParams(const Tuple1<int>& params) {
1267 callback_.RunWithParams(params);
1268 ASSERT_EQ(OK, params.a);
1269
1270 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581271 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111272
1273 // Don't allow reuse of the socket. Disconnect it and then release it and
1274 // run through the MessageLoop once to get it completely released.
1275 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091276 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111277 {
1278 MessageLoop::ScopedNestableTaskAllower nestable(
1279 MessageLoop::current());
1280 MessageLoop::current()->RunAllPending();
1281 }
[email protected]f6d1d6eb2009-06-24 20:16:091282 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471283 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271284 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131285 int rv = handle_->Init("a",
1286 params,
1287 kDefaultPriority,
1288 &next_job_callback,
1289 pool_,
1290 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581291 switch (next_job_type_) {
1292 case TestConnectJob::kMockJob:
1293 EXPECT_EQ(OK, rv);
1294 break;
1295 case TestConnectJob::kMockPendingJob:
1296 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471297
1298 // For pending jobs, wait for new socket to be created. This makes
1299 // sure there are no more pending operations nor any unclosed sockets
1300 // when the test finishes.
1301 // We need to give it a little bit of time to run, so that all the
1302 // operations that happen on timers (e.g. cleanup of idle
1303 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111304 {
1305 MessageLoop::ScopedNestableTaskAllower nestable(
1306 MessageLoop::current());
1307 PlatformThread::Sleep(10);
1308 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1309 }
[email protected]2ab05b52009-07-01 23:57:581310 break;
1311 default:
1312 FAIL() << "Unexpected job type: " << next_job_type_;
1313 break;
1314 }
[email protected]f6d1d6eb2009-06-24 20:16:091315 }
1316 }
1317
1318 int WaitForResult() {
1319 return callback_.WaitForResult();
1320 }
1321
1322 private:
1323 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131324 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091325 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581326 TestConnectJobFactory* const test_connect_job_factory_;
1327 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091328 TestCompletionCallback callback_;
1329};
1330
[email protected]2ab05b52009-07-01 23:57:581331TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531332 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201333
[email protected]0b7648c2009-07-06 20:14:011334 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061335 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581336 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061337 &handle, pool_.get(), connect_job_factory_,
1338 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131339 int rv = handle.Init("a",
1340 params_,
1341 kDefaultPriority,
1342 &callback,
1343 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211344 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091345 ASSERT_EQ(ERR_IO_PENDING, rv);
1346
1347 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581348}
[email protected]f6d1d6eb2009-06-24 20:16:091349
[email protected]2ab05b52009-07-01 23:57:581350TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531351 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201352
[email protected]0b7648c2009-07-06 20:14:011353 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061354 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581355 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061356 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131357 int rv = handle.Init("a",
1358 params_,
1359 kDefaultPriority,
1360 &callback,
1361 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211362 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581363 ASSERT_EQ(ERR_IO_PENDING, rv);
1364
1365 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091366}
1367
1368// Make sure that pending requests get serviced after active requests get
1369// cancelled.
[email protected]ab838892009-06-30 18:49:051370TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531371 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201372
[email protected]0b7648c2009-07-06 20:14:011373 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091374
[email protected]c9d6a1d2009-07-14 16:15:201375 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));
1381 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091382
[email protected]c9d6a1d2009-07-14 16:15:201383 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1384 // Let's cancel them.
1385 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131386 ASSERT_FALSE(request(i)->handle()->is_initialized());
1387 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091388 }
1389
[email protected]f6d1d6eb2009-06-24 20:16:091390 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131391 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1392 EXPECT_EQ(OK, request(i)->WaitForResult());
1393 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091394 }
1395
[email protected]2431756e2010-09-29 20:26:131396 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1397 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091398}
1399
1400// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051401TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531402 const size_t kMaxSockets = 5;
1403 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201404
[email protected]0b7648c2009-07-06 20:14:011405 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091406
[email protected]211d21722009-07-22 15:48:531407 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1408 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091409
1410 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531411 for (size_t i = 0; i < kNumberOfRequests; ++i)
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091413
[email protected]211d21722009-07-22 15:48:531414 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131415 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091416}
1417
[email protected]5fc08e32009-07-15 17:09:571418TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531419 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571420
1421 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1422
[email protected]2431756e2010-09-29 20:26:131423 ClientSocketHandle handle;
1424 TestCompletionCallback callback;
1425 int rv = handle.Init("a",
1426 params_,
1427 kDefaultPriority,
1428 &callback,
1429 pool_.get(),
1430 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571431 EXPECT_EQ(ERR_IO_PENDING, rv);
1432
1433 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131434 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571435
[email protected]2431756e2010-09-29 20:26:131436 rv = handle.Init("a",
1437 params_,
1438 kDefaultPriority,
1439 &callback,
1440 pool_.get(),
1441 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571442 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131443 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571444
[email protected]2431756e2010-09-29 20:26:131445 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571446 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1447}
1448
[email protected]2b7523d2009-07-29 20:29:231449// Regression test for http://crbug.com/17985.
1450TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1451 const int kMaxSockets = 3;
1452 const int kMaxSocketsPerGroup = 2;
1453 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1454
[email protected]ac790b42009-12-02 04:31:311455 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231456
1457 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1458 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1459
1460 // This is going to be a pending request in an otherwise empty group.
1461 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1462
1463 // Reach the maximum socket limit.
1464 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1465
1466 // Create a stalled group with high priorities.
1467 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1468 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231469
[email protected]eb5a99382010-07-11 03:18:261470 // Release the first two sockets from "a". Because this is a keepalive,
1471 // the first release will unblock the pending request for "a". The
1472 // second release will unblock a request for "c", becaue it is the next
1473 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131474 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1475 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231476
1477 // Closing idle sockets should not get us into trouble, but in the bug
1478 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411479 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541480 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261481
1482 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231483}
1484
[email protected]4d3b05d2010-01-27 21:27:291485TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531486 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571487
1488 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131489 ClientSocketHandle handle;
1490 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531491 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131492 int rv = handle.Init("a",
1493 params_,
1494 LOWEST,
1495 &callback,
1496 pool_.get(),
1497 log.bound());
[email protected]5fc08e32009-07-15 17:09:571498 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131499 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1500 EXPECT_EQ(OK, callback.WaitForResult());
1501 EXPECT_TRUE(handle.is_initialized());
1502 EXPECT_TRUE(handle.socket());
1503 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301504
[email protected]06650c52010-06-03 00:49:171505 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461506 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531507 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171508 EXPECT_TRUE(LogContainsEvent(
1509 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1510 NetLog::PHASE_NONE));
1511 EXPECT_TRUE(LogContainsEvent(
1512 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1513 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461514 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171515 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571516}
1517
[email protected]4d3b05d2010-01-27 21:27:291518TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571519 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571521
1522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131523 ClientSocketHandle handle;
1524 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531525 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181526 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131527 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431528 HttpResponseInfo info;
1529 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131530 handle.set_ssl_error_response_info(info);
1531 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1532 params_,
1533 kDefaultPriority,
1534 &callback,
1535 pool_.get(),
1536 log.bound()));
1537 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1538 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1539 EXPECT_FALSE(handle.is_ssl_error());
1540 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301541
[email protected]06650c52010-06-03 00:49:171542 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461543 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531544 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171545 EXPECT_TRUE(LogContainsEvent(
1546 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1547 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321548 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171549 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571550}
1551
[email protected]4d3b05d2010-01-27 21:27:291552TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101553 // TODO(eroman): Add back the log expectations! Removed them because the
1554 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531555 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571556
1557 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131558 ClientSocketHandle handle;
1559 TestCompletionCallback callback;
1560 ClientSocketHandle handle2;
1561 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571562
[email protected]2431756e2010-09-29 20:26:131563 EXPECT_EQ(ERR_IO_PENDING,
1564 handle.Init("a",
1565 params_,
1566 kDefaultPriority,
1567 &callback,
1568 pool_.get(),
1569 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531570 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131571 EXPECT_EQ(ERR_IO_PENDING,
1572 handle2.Init("a",
1573 params_,
1574 kDefaultPriority,
1575 &callback2,
1576 pool_.get(),
1577 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571578
[email protected]2431756e2010-09-29 20:26:131579 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571580
[email protected]fd7b7c92009-08-20 19:38:301581
1582 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301583
[email protected]2431756e2010-09-29 20:26:131584 EXPECT_EQ(OK, callback2.WaitForResult());
1585 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301586
1587 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531588 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571589}
1590
[email protected]4d3b05d2010-01-27 21:27:291591TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341592 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1593
[email protected]17a0c6c2009-08-04 00:07:041594 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1595
[email protected]ac790b42009-12-02 04:31:311596 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1599 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341600
1601 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131602 (*requests())[2]->handle()->Reset();
1603 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341604 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1605
[email protected]2431756e2010-09-29 20:26:131606 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341607 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1608
[email protected]2431756e2010-09-29 20:26:131609 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261610 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341611}
1612
[email protected]5fc08e32009-07-15 17:09:571613// When requests and ConnectJobs are not coupled, the request will get serviced
1614// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291615TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571617
1618 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321619 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571620
[email protected]2431756e2010-09-29 20:26:131621 std::vector<TestSocketRequest*> request_order;
1622 size_t completion_count; // unused
1623 TestSocketRequest req1(&request_order, &completion_count);
1624 int rv = req1.handle()->Init("a",
1625 params_,
1626 kDefaultPriority,
1627 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211628 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571629 EXPECT_EQ(ERR_IO_PENDING, rv);
1630 EXPECT_EQ(OK, req1.WaitForResult());
1631
1632 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1633 // without a job.
1634 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1635
[email protected]2431756e2010-09-29 20:26:131636 TestSocketRequest req2(&request_order, &completion_count);
1637 rv = req2.handle()->Init("a",
1638 params_,
1639 kDefaultPriority,
1640 &req2,
1641 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211642 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571643 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131644 TestSocketRequest req3(&request_order, &completion_count);
1645 rv = req3.handle()->Init("a",
1646 params_,
1647 kDefaultPriority,
1648 &req3,
1649 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211650 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571651 EXPECT_EQ(ERR_IO_PENDING, rv);
1652
1653 // Both Requests 2 and 3 are pending. We release socket 1 which should
1654 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331655 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261656 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331657 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571658 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331659 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571660
1661 // Signal job 2, which should service request 3.
1662
1663 client_socket_factory_.SignalJobs();
1664 EXPECT_EQ(OK, req3.WaitForResult());
1665
[email protected]2431756e2010-09-29 20:26:131666 ASSERT_EQ(3U, request_order.size());
1667 EXPECT_EQ(&req1, request_order[0]);
1668 EXPECT_EQ(&req2, request_order[1]);
1669 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571670 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1671}
1672
1673// The requests are not coupled to the jobs. So, the requests should finish in
1674// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291675TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571677 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571679
[email protected]2431756e2010-09-29 20:26:131680 std::vector<TestSocketRequest*> request_order;
1681 size_t completion_count; // unused
1682 TestSocketRequest req1(&request_order, &completion_count);
1683 int rv = req1.handle()->Init("a",
1684 params_,
1685 kDefaultPriority,
1686 &req1,
1687 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211688 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571689 EXPECT_EQ(ERR_IO_PENDING, rv);
1690
[email protected]2431756e2010-09-29 20:26:131691 TestSocketRequest req2(&request_order, &completion_count);
1692 rv = req2.handle()->Init("a",
1693 params_,
1694 kDefaultPriority,
1695 &req2,
1696 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211697 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571698 EXPECT_EQ(ERR_IO_PENDING, rv);
1699
1700 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321701 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571702
[email protected]2431756e2010-09-29 20:26:131703 TestSocketRequest req3(&request_order, &completion_count);
1704 rv = req3.handle()->Init("a",
1705 params_,
1706 kDefaultPriority,
1707 &req3,
1708 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211709 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571710 EXPECT_EQ(ERR_IO_PENDING, rv);
1711
1712 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1713 EXPECT_EQ(OK, req2.WaitForResult());
1714 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1715
[email protected]2431756e2010-09-29 20:26:131716 ASSERT_EQ(3U, request_order.size());
1717 EXPECT_EQ(&req1, request_order[0]);
1718 EXPECT_EQ(&req2, request_order[1]);
1719 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571720}
1721
[email protected]e6ec67b2010-06-16 00:12:461722TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531723 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571724 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321725 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571726
[email protected]2431756e2010-09-29 20:26:131727 ClientSocketHandle handle;
1728 TestCompletionCallback callback;
1729 int rv = handle.Init("a",
1730 params_,
1731 kDefaultPriority,
1732 &callback,
1733 pool_.get(),
1734 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571735 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131736 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571737
1738 MessageLoop::current()->RunAllPending();
1739
[email protected]2431756e2010-09-29 20:26:131740 ClientSocketHandle handle2;
1741 TestCompletionCallback callback2;
1742 rv = handle2.Init("a",
1743 params_,
1744 kDefaultPriority,
1745 &callback2, pool_.get(),
1746 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571747 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131748 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1749 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571750}
1751
[email protected]e772db3f2010-07-12 18:11:131752TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1753 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1754 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1755
[email protected]2431756e2010-09-29 20:26:131756 ClientSocketHandle handle;
1757 TestCompletionCallback callback;
1758 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1759 params_,
1760 kDefaultPriority,
1761 &callback, pool_.get(),
1762 BoundNetLog()));
1763 EXPECT_TRUE(handle.is_initialized());
1764 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131765}
1766
1767TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1768 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1769
1770 connect_job_factory_->set_job_type(
1771 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131772 ClientSocketHandle handle;
1773 TestCompletionCallback callback;
1774 EXPECT_EQ(ERR_IO_PENDING,
1775 handle.Init("a",
1776 params_,
1777 kDefaultPriority,
1778 &callback,
1779 pool_.get(),
1780 BoundNetLog()));
1781 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1782 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1783 EXPECT_TRUE(handle.is_initialized());
1784 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131785}
1786
[email protected]e60e47a2010-07-14 03:37:181787TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1788 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1789 connect_job_factory_->set_job_type(
1790 TestConnectJob::kMockAdditionalErrorStateJob);
1791
[email protected]2431756e2010-09-29 20:26:131792 ClientSocketHandle handle;
1793 TestCompletionCallback callback;
1794 EXPECT_EQ(ERR_CONNECTION_FAILED,
1795 handle.Init("a",
1796 params_,
1797 kDefaultPriority,
1798 &callback,
1799 pool_.get(),
1800 BoundNetLog()));
1801 EXPECT_FALSE(handle.is_initialized());
1802 EXPECT_FALSE(handle.socket());
1803 EXPECT_TRUE(handle.is_ssl_error());
1804 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181805}
1806
1807TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1809
1810 connect_job_factory_->set_job_type(
1811 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131812 ClientSocketHandle handle;
1813 TestCompletionCallback callback;
1814 EXPECT_EQ(ERR_IO_PENDING,
1815 handle.Init("a",
1816 params_,
1817 kDefaultPriority,
1818 &callback,
1819 pool_.get(),
1820 BoundNetLog()));
1821 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1822 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1823 EXPECT_FALSE(handle.is_initialized());
1824 EXPECT_FALSE(handle.socket());
1825 EXPECT_TRUE(handle.is_ssl_error());
1826 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181827}
1828
[email protected]4d3b05d2010-01-27 21:27:291829TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161830 CreatePoolWithIdleTimeouts(
1831 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1832 base::TimeDelta(), // Time out unused sockets immediately.
1833 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1834
1835 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1836
1837 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1838
[email protected]2431756e2010-09-29 20:26:131839 ClientSocketHandle handle;
1840 TestCompletionCallback callback;
1841 int rv = handle.Init("a",
1842 params_,
1843 LOWEST,
1844 &callback,
1845 pool_.get(),
1846 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161847 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131848 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161849
[email protected]2431756e2010-09-29 20:26:131850 ClientSocketHandle handle2;
1851 TestCompletionCallback callback2;
1852 rv = handle2.Init("a",
1853 params_,
1854 LOWEST,
1855 &callback2,
1856 pool_.get(),
1857 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161858 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131859 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161860
1861 // Cancel one of the requests. Wait for the other, which will get the first
1862 // job. Release the socket. Run the loop again to make sure the second
1863 // socket is sitting idle and the first one is released (since ReleaseSocket()
1864 // just posts a DoReleaseSocket() task).
1865
[email protected]2431756e2010-09-29 20:26:131866 handle.Reset();
1867 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011868 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131869 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1870 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471871
1872 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1873 // actually become pending until 2ms after they have been created. In order
1874 // to flush all tasks, we need to wait so that we know there are no
1875 // soon-to-be-pending tasks waiting.
1876 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161877 MessageLoop::current()->RunAllPending();
1878
1879 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041880
[email protected]9bf28db2009-08-29 01:35:161881 // Invoke the idle socket cleanup check. Only one socket should be left, the
1882 // used socket. Request it to make sure that it's used.
1883
1884 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531885 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131886 rv = handle.Init("a",
1887 params_,
1888 LOWEST,
1889 &callback,
1890 pool_.get(),
1891 log.bound());
[email protected]9bf28db2009-08-29 01:35:161892 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131893 EXPECT_TRUE(handle.is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151894 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451895 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161896}
1897
[email protected]2041cf342010-02-19 03:15:591898// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161899// because of multiple releasing disconnected sockets.
1900TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1901 CreatePoolWithIdleTimeouts(
1902 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1903 base::TimeDelta(), // Time out unused sockets immediately.
1904 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1905
1906 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1907
1908 // Startup 4 connect jobs. Two of them will be pending.
1909
[email protected]2431756e2010-09-29 20:26:131910 ClientSocketHandle handle;
1911 TestCompletionCallback callback;
1912 int rv = handle.Init("a",
1913 params_,
1914 LOWEST,
1915 &callback,
1916 pool_.get(),
1917 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161918 EXPECT_EQ(OK, rv);
1919
[email protected]2431756e2010-09-29 20:26:131920 ClientSocketHandle handle2;
1921 TestCompletionCallback callback2;
1922 rv = handle2.Init("a",
1923 params_,
1924 LOWEST,
1925 &callback2,
1926 pool_.get(),
1927 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161928 EXPECT_EQ(OK, rv);
1929
[email protected]2431756e2010-09-29 20:26:131930 ClientSocketHandle handle3;
1931 TestCompletionCallback callback3;
1932 rv = handle3.Init("a",
1933 params_,
1934 LOWEST,
1935 &callback3,
1936 pool_.get(),
1937 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161938 EXPECT_EQ(ERR_IO_PENDING, rv);
1939
[email protected]2431756e2010-09-29 20:26:131940 ClientSocketHandle handle4;
1941 TestCompletionCallback callback4;
1942 rv = handle4.Init("a",
1943 params_,
1944 LOWEST,
1945 &callback4,
1946 pool_.get(),
1947 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161948 EXPECT_EQ(ERR_IO_PENDING, rv);
1949
1950 // Release two disconnected sockets.
1951
[email protected]2431756e2010-09-29 20:26:131952 handle.socket()->Disconnect();
1953 handle.Reset();
1954 handle2.socket()->Disconnect();
1955 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161956
[email protected]2431756e2010-09-29 20:26:131957 EXPECT_EQ(OK, callback3.WaitForResult());
1958 EXPECT_FALSE(handle3.is_reused());
1959 EXPECT_EQ(OK, callback4.WaitForResult());
1960 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161961}
1962
[email protected]d7027bb2010-05-10 18:58:541963// Regression test for http://crbug.com/42267.
1964// When DoReleaseSocket() is processed for one socket, it is blocked because the
1965// other stalled groups all have releasing sockets, so no progress can be made.
1966TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1967 CreatePoolWithIdleTimeouts(
1968 4 /* socket limit */, 4 /* socket limit per group */,
1969 base::TimeDelta(), // Time out unused sockets immediately.
1970 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1971
1972 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1973
1974 // Max out the socket limit with 2 per group.
1975
[email protected]2431756e2010-09-29 20:26:131976 ClientSocketHandle handle_a[4];
1977 TestCompletionCallback callback_a[4];
1978 ClientSocketHandle handle_b[4];
1979 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541980
1981 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:131982 EXPECT_EQ(OK, handle_a[i].Init("a",
1983 params_,
1984 LOWEST,
1985 &callback_a[i],
1986 pool_.get(),
1987 BoundNetLog()));
1988 EXPECT_EQ(OK, handle_b[i].Init("b",
1989 params_,
1990 LOWEST,
1991 &callback_b[i],
1992 pool_.get(),
1993 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541994 }
[email protected]b89f7e42010-05-20 20:37:001995
[email protected]d7027bb2010-05-10 18:58:541996 // Make 4 pending requests, 2 per group.
1997
1998 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:131999 EXPECT_EQ(ERR_IO_PENDING,
2000 handle_a[i].Init("a",
2001 params_,
2002 LOWEST,
2003 &callback_a[i],
2004 pool_.get(),
2005 BoundNetLog()));
2006 EXPECT_EQ(ERR_IO_PENDING,
2007 handle_b[i].Init("b",
2008 params_,
2009 LOWEST,
2010 &callback_b[i],
2011 pool_.get(),
2012 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542013 }
2014
2015 // Release b's socket first. The order is important, because in
2016 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2017 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2018 // first, which has a releasing socket, so it refuses to start up another
2019 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132020 handle_b[0].socket()->Disconnect();
2021 handle_b[0].Reset();
2022 handle_a[0].socket()->Disconnect();
2023 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542024
2025 // Used to get stuck here.
2026 MessageLoop::current()->RunAllPending();
2027
[email protected]2431756e2010-09-29 20:26:132028 handle_b[1].socket()->Disconnect();
2029 handle_b[1].Reset();
2030 handle_a[1].socket()->Disconnect();
2031 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542032
2033 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132034 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2035 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542036 }
2037}
2038
[email protected]fd4fe0b2010-02-08 23:02:152039TEST_F(ClientSocketPoolBaseTest,
2040 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2041 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2042
2043 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2044
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 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2049
[email protected]2431756e2010-09-29 20:26:132050 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2051 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2052 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152053
2054 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132055 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2056 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152057
[email protected]2431756e2010-09-29 20:26:132058 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2059 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2060 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152061
2062 EXPECT_EQ(1, GetOrderOfRequest(1));
2063 EXPECT_EQ(2, GetOrderOfRequest(2));
2064 EXPECT_EQ(3, GetOrderOfRequest(3));
2065 EXPECT_EQ(4, GetOrderOfRequest(4));
2066
2067 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132068 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152069}
2070
[email protected]4f1e4982010-03-02 18:31:042071class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2072 public:
[email protected]2431756e2010-09-29 20:26:132073 TestReleasingSocketRequest(TestClientSocketPool* pool,
2074 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182075 bool reset_releasing_handle)
2076 : pool_(pool),
2077 expected_result_(expected_result),
2078 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042079
2080 ClientSocketHandle* handle() { return &handle_; }
2081
2082 int WaitForResult() {
2083 return callback_.WaitForResult();
2084 }
2085
2086 virtual void RunWithParams(const Tuple1<int>& params) {
2087 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182088 if (reset_releasing_handle_)
2089 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272090 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132091 EXPECT_EQ(expected_result_, handle2_.Init("a",
2092 con_params,
2093 kDefaultPriority,
2094 &callback2_,
2095 pool_,
[email protected]e60e47a2010-07-14 03:37:182096 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042097 }
2098
2099 private:
[email protected]2431756e2010-09-29 20:26:132100 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182101 int expected_result_;
2102 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042103 ClientSocketHandle handle_;
2104 ClientSocketHandle handle2_;
2105 TestCompletionCallback callback_;
2106 TestCompletionCallback callback2_;
2107};
2108
[email protected]e60e47a2010-07-14 03:37:182109
2110TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2112
2113 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2114 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2115 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2116
[email protected]2431756e2010-09-29 20:26:132117 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182118 client_socket_factory_.allocation_count());
2119
2120 connect_job_factory_->set_job_type(
2121 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2122 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132123 EXPECT_EQ(ERR_IO_PENDING,
2124 req.handle()->Init("a",
2125 params_,
2126 kDefaultPriority,
2127 &req,
2128 pool_.get(),
2129 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182130 // The next job should complete synchronously
2131 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2132
2133 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2134 EXPECT_FALSE(req.handle()->is_initialized());
2135 EXPECT_FALSE(req.handle()->socket());
2136 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432137 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182138}
2139
[email protected]b6501d3d2010-06-03 23:53:342140// http://crbug.com/44724 regression test.
2141// We start releasing the pool when we flush on network change. When that
2142// happens, the only active references are in the ClientSocketHandles. When a
2143// ConnectJob completes and calls back into the last ClientSocketHandle, that
2144// callback can release the last reference and delete the pool. After the
2145// callback finishes, we go back to the stack frame within the now-deleted pool.
2146// Executing any code that refers to members of the now-deleted pool can cause
2147// crashes.
2148TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2149 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2150 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2151
2152 ClientSocketHandle handle;
2153 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132154 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2155 params_,
2156 kDefaultPriority,
2157 &callback,
2158 pool_.get(),
2159 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342160
[email protected]2431756e2010-09-29 20:26:132161 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342162
2163 // We'll call back into this now.
2164 callback.WaitForResult();
2165}
2166
[email protected]a7e38572010-06-07 18:22:242167TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2168 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2169 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2170
2171 ClientSocketHandle handle;
2172 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132173 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2174 params_,
2175 kDefaultPriority,
2176 &callback,
2177 pool_.get(),
2178 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242179 EXPECT_EQ(OK, callback.WaitForResult());
2180 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2181
2182 pool_->Flush();
2183
2184 handle.Reset();
2185 MessageLoop::current()->RunAllPending();
2186
[email protected]2431756e2010-09-29 20:26:132187 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2188 params_,
2189 kDefaultPriority,
2190 &callback,
2191 pool_.get(),
2192 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242193 EXPECT_EQ(OK, callback.WaitForResult());
2194 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2195}
2196
[email protected]06f92462010-08-31 19:24:142197class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2198 public:
2199 ConnectWithinCallback(
2200 const std::string& group_name,
2201 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132202 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142203 : group_name_(group_name), params_(params), pool_(pool) {}
2204
2205 ~ConnectWithinCallback() {}
2206
2207 virtual void RunWithParams(const Tuple1<int>& params) {
2208 callback_.RunWithParams(params);
2209 EXPECT_EQ(ERR_IO_PENDING,
2210 handle_.Init(group_name_,
2211 params_,
2212 kDefaultPriority,
2213 &nested_callback_,
2214 pool_,
2215 BoundNetLog()));
2216 }
2217
2218 int WaitForResult() {
2219 return callback_.WaitForResult();
2220 }
2221
2222 int WaitForNestedResult() {
2223 return nested_callback_.WaitForResult();
2224 }
2225
2226 private:
2227 const std::string group_name_;
2228 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132229 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142230 ClientSocketHandle handle_;
2231 TestCompletionCallback callback_;
2232 TestCompletionCallback nested_callback_;
2233};
2234
2235TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2237
2238 // First job will be waiting until it gets aborted.
2239 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2240
2241 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132242 ConnectWithinCallback callback("a", params_, pool_.get());
2243 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2244 params_,
2245 kDefaultPriority,
2246 &callback,
2247 pool_.get(),
2248 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142249
2250 // Second job will be started during the first callback, and will
2251 // asynchronously complete with OK.
2252 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2253 pool_->Flush();
2254 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2255 EXPECT_EQ(OK, callback.WaitForNestedResult());
2256}
2257
[email protected]25eea382010-07-10 23:55:262258// Cancel a pending socket request while we're at max sockets,
2259// and verify that the backup socket firing doesn't cause a crash.
2260TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2261 // Max 4 sockets globally, max 4 sockets per group.
2262 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222263 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262264
[email protected]4baaf9d2010-08-31 15:15:442265 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2266 // timer.
[email protected]25eea382010-07-10 23:55:262267 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2268 ClientSocketHandle handle;
2269 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132270 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2271 params_,
2272 kDefaultPriority,
2273 &callback,
2274 pool_.get(),
2275 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262276
2277 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2278 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2279 ClientSocketHandle handles[kDefaultMaxSockets];
2280 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2281 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132282 EXPECT_EQ(OK, handles[i].Init("bar",
2283 params_,
2284 kDefaultPriority,
2285 &callback,
2286 pool_.get(),
2287 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262288 }
2289
2290 MessageLoop::current()->RunAllPending();
2291
2292 // Cancel the pending request.
2293 handle.Reset();
2294
2295 // Wait for the backup timer to fire (add some slop to ensure it fires)
2296 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2297
2298 MessageLoop::current()->RunAllPending();
2299 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2300}
2301
[email protected]3f00be82010-09-27 19:50:022302TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442303 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2304 pool_->EnableConnectBackupJobs();
2305
2306 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2307 // timer.
2308 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2309 ClientSocketHandle handle;
2310 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132311 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2312 params_,
2313 kDefaultPriority,
2314 &callback,
2315 pool_.get(),
2316 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442317 ASSERT_TRUE(pool_->HasGroup("bar"));
2318 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2319
2320 // Cancel the socket request. This should cancel the backup timer. Wait for
2321 // the backup time to see if it indeed got canceled.
2322 handle.Reset();
2323 // Wait for the backup timer to fire (add some slop to ensure it fires)
2324 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2325 MessageLoop::current()->RunAllPending();
2326 ASSERT_TRUE(pool_->HasGroup("bar"));
2327 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2328}
2329
[email protected]3f00be82010-09-27 19:50:022330TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2331 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2332 pool_->EnableConnectBackupJobs();
2333
2334 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2335 // timer.
2336 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2337 ClientSocketHandle handle;
2338 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132339 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2340 params_,
2341 kDefaultPriority,
2342 &callback,
2343 pool_.get(),
2344 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022345 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2346 ClientSocketHandle handle2;
2347 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132348 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2349 params_,
2350 kDefaultPriority,
2351 &callback2,
2352 pool_.get(),
2353 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022354 ASSERT_TRUE(pool_->HasGroup("bar"));
2355 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2356
2357 // Cancel request 1 and then complete request 2. With the requests finished,
2358 // the backup timer should be cancelled.
2359 handle.Reset();
2360 EXPECT_EQ(OK, callback2.WaitForResult());
2361 // Wait for the backup timer to fire (add some slop to ensure it fires)
2362 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2363 MessageLoop::current()->RunAllPending();
2364}
2365
[email protected]eb5a99382010-07-11 03:18:262366// Test delayed socket binding for the case where we have two connects,
2367// and while one is waiting on a connect, the other frees up.
2368// The socket waiting on a connect should switch immediately to the freed
2369// up socket.
2370TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2371 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2373
2374 ClientSocketHandle handle1;
2375 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132376 EXPECT_EQ(ERR_IO_PENDING,
2377 handle1.Init("a",
2378 params_,
2379 kDefaultPriority,
2380 &callback,
2381 pool_.get(),
2382 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262383 EXPECT_EQ(OK, callback.WaitForResult());
2384
2385 // No idle sockets, no pending jobs.
2386 EXPECT_EQ(0, pool_->IdleSocketCount());
2387 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2388
2389 // Create a second socket to the same host, but this one will wait.
2390 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2391 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132392 EXPECT_EQ(ERR_IO_PENDING,
2393 handle2.Init("a",
2394 params_,
2395 kDefaultPriority,
2396 &callback,
2397 pool_.get(),
2398 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262399 // No idle sockets, and one connecting job.
2400 EXPECT_EQ(0, pool_->IdleSocketCount());
2401 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2402
2403 // Return the first handle to the pool. This will initiate the delayed
2404 // binding.
2405 handle1.Reset();
2406
2407 MessageLoop::current()->RunAllPending();
2408
2409 // Still no idle sockets, still one pending connect job.
2410 EXPECT_EQ(0, pool_->IdleSocketCount());
2411 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2412
2413 // The second socket connected, even though it was a Waiting Job.
2414 EXPECT_EQ(OK, callback.WaitForResult());
2415
2416 // And we can see there is still one job waiting.
2417 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2418
2419 // Finally, signal the waiting Connect.
2420 client_socket_factory_.SignalJobs();
2421 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2422
2423 MessageLoop::current()->RunAllPending();
2424}
2425
2426// Test delayed socket binding when a group is at capacity and one
2427// of the group's sockets frees up.
2428TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2429 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2430 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2431
2432 ClientSocketHandle handle1;
2433 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132434 EXPECT_EQ(ERR_IO_PENDING,
2435 handle1.Init("a",
2436 params_,
2437 kDefaultPriority,
2438 &callback,
2439 pool_.get(),
2440 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262441 EXPECT_EQ(OK, callback.WaitForResult());
2442
2443 // No idle sockets, no pending jobs.
2444 EXPECT_EQ(0, pool_->IdleSocketCount());
2445 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2446
2447 // Create a second socket to the same host, but this one will wait.
2448 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2449 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132450 EXPECT_EQ(ERR_IO_PENDING,
2451 handle2.Init("a",
2452 params_,
2453 kDefaultPriority,
2454 &callback,
2455 pool_.get(),
2456 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262457 // No idle sockets, and one connecting job.
2458 EXPECT_EQ(0, pool_->IdleSocketCount());
2459 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2460
2461 // Return the first handle to the pool. This will initiate the delayed
2462 // binding.
2463 handle1.Reset();
2464
2465 MessageLoop::current()->RunAllPending();
2466
2467 // Still no idle sockets, still one pending connect job.
2468 EXPECT_EQ(0, pool_->IdleSocketCount());
2469 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2470
2471 // The second socket connected, even though it was a Waiting Job.
2472 EXPECT_EQ(OK, callback.WaitForResult());
2473
2474 // And we can see there is still one job waiting.
2475 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2476
2477 // Finally, signal the waiting Connect.
2478 client_socket_factory_.SignalJobs();
2479 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2480
2481 MessageLoop::current()->RunAllPending();
2482}
2483
2484// Test out the case where we have one socket connected, one
2485// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512486// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262487// should complete, by taking the first socket's idle socket.
2488TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2489 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2490 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2491
2492 ClientSocketHandle handle1;
2493 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132494 EXPECT_EQ(ERR_IO_PENDING,
2495 handle1.Init("a",
2496 params_,
2497 kDefaultPriority,
2498 &callback,
2499 pool_.get(),
2500 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262501 EXPECT_EQ(OK, callback.WaitForResult());
2502
2503 // No idle sockets, no pending jobs.
2504 EXPECT_EQ(0, pool_->IdleSocketCount());
2505 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2506
2507 // Create a second socket to the same host, but this one will wait.
2508 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2509 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132510 EXPECT_EQ(ERR_IO_PENDING,
2511 handle2.Init("a",
2512 params_,
2513 kDefaultPriority,
2514 &callback,
2515 pool_.get(),
2516 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262517 // No idle sockets, and one connecting job.
2518 EXPECT_EQ(0, pool_->IdleSocketCount());
2519 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2520
2521 // Return the first handle to the pool. This will initiate the delayed
2522 // binding.
2523 handle1.Reset();
2524
2525 MessageLoop::current()->RunAllPending();
2526
2527 // Still no idle sockets, still one pending connect job.
2528 EXPECT_EQ(0, pool_->IdleSocketCount());
2529 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2530
2531 // The second socket connected, even though it was a Waiting Job.
2532 EXPECT_EQ(OK, callback.WaitForResult());
2533
2534 // And we can see there is still one job waiting.
2535 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2536
2537 // Finally, signal the waiting Connect.
2538 client_socket_factory_.SignalJobs();
2539 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2540
2541 MessageLoop::current()->RunAllPending();
2542}
2543
[email protected]2abfe90a2010-08-25 17:49:512544// Cover the case where on an available socket slot, we have one pending
2545// request that completes synchronously, thereby making the Group empty.
2546TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2547 const int kUnlimitedSockets = 100;
2548 const int kOneSocketPerGroup = 1;
2549 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2550
2551 // Make the first request asynchronous fail.
2552 // This will free up a socket slot later.
2553 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2554
2555 ClientSocketHandle handle1;
2556 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132557 EXPECT_EQ(ERR_IO_PENDING,
2558 handle1.Init("a",
2559 params_,
2560 kDefaultPriority,
2561 &callback1,
2562 pool_.get(),
2563 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512564 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2565
2566 // Make the second request synchronously fail. This should make the Group
2567 // empty.
2568 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2569 ClientSocketHandle handle2;
2570 TestCompletionCallback callback2;
2571 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2572 // when created.
[email protected]2431756e2010-09-29 20:26:132573 EXPECT_EQ(ERR_IO_PENDING,
2574 handle2.Init("a",
2575 params_,
2576 kDefaultPriority,
2577 &callback2,
2578 pool_.get(),
2579 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512580
2581 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2582
2583 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2584 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2585 EXPECT_FALSE(pool_->HasGroup("a"));
2586}
2587
[email protected]e1b54dc2010-10-06 21:27:222588TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2589 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2590
2591 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2592
2593 ClientSocketHandle handle1;
2594 TestCompletionCallback callback1;
2595 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2596 params_,
2597 kDefaultPriority,
2598 &callback1,
2599 pool_.get(),
2600 BoundNetLog()));
2601
2602 ClientSocketHandle handle2;
2603 TestCompletionCallback callback2;
2604 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2605 params_,
2606 kDefaultPriority,
2607 &callback2,
2608 pool_.get(),
2609 BoundNetLog()));
2610 ClientSocketHandle handle3;
2611 TestCompletionCallback callback3;
2612 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2613 params_,
2614 kDefaultPriority,
2615 &callback3,
2616 pool_.get(),
2617 BoundNetLog()));
2618
2619 EXPECT_EQ(OK, callback1.WaitForResult());
2620 EXPECT_EQ(OK, callback2.WaitForResult());
2621 EXPECT_EQ(OK, callback3.WaitForResult());
2622
2623 // Use the socket.
2624 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2625 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2626
2627 handle1.Reset();
2628 handle2.Reset();
2629 handle3.Reset();
2630
2631 EXPECT_EQ(OK, handle1.Init("a",
2632 params_,
2633 kDefaultPriority,
2634 &callback1,
2635 pool_.get(),
2636 BoundNetLog()));
2637 EXPECT_EQ(OK, handle2.Init("a",
2638 params_,
2639 kDefaultPriority,
2640 &callback2,
2641 pool_.get(),
2642 BoundNetLog()));
2643 EXPECT_EQ(OK, handle3.Init("a",
2644 params_,
2645 kDefaultPriority,
2646 &callback3,
2647 pool_.get(),
2648 BoundNetLog()));
2649
2650 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2651 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2652 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2653}
2654
[email protected]2c2bef152010-10-13 00:55:032655TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2656 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2657 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2658
2659 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2660
2661 ASSERT_TRUE(pool_->HasGroup("a"));
2662 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2663 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2664
2665 ClientSocketHandle handle1;
2666 TestCompletionCallback callback1;
2667 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2668 params_,
2669 kDefaultPriority,
2670 &callback1,
2671 pool_.get(),
2672 BoundNetLog()));
2673
2674 ClientSocketHandle handle2;
2675 TestCompletionCallback callback2;
2676 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2677 params_,
2678 kDefaultPriority,
2679 &callback2,
2680 pool_.get(),
2681 BoundNetLog()));
2682
2683 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2684 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2685
2686 EXPECT_EQ(OK, callback1.WaitForResult());
2687 EXPECT_EQ(OK, callback2.WaitForResult());
2688 handle1.Reset();
2689 handle2.Reset();
2690
2691 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2692 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2693}
2694
2695TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2696 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2697 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2698
2699 ClientSocketHandle handle1;
2700 TestCompletionCallback callback1;
2701 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2702 params_,
2703 kDefaultPriority,
2704 &callback1,
2705 pool_.get(),
2706 BoundNetLog()));
2707
2708 ASSERT_TRUE(pool_->HasGroup("a"));
2709 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2710 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2711
2712 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2713
2714 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2715 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2716
2717 ClientSocketHandle handle2;
2718 TestCompletionCallback callback2;
2719 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2720 params_,
2721 kDefaultPriority,
2722 &callback2,
2723 pool_.get(),
2724 BoundNetLog()));
2725
2726 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2727 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2728
2729 EXPECT_EQ(OK, callback1.WaitForResult());
2730 EXPECT_EQ(OK, callback2.WaitForResult());
2731 handle1.Reset();
2732 handle2.Reset();
2733
2734 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2735 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2736}
2737
2738TEST_F(ClientSocketPoolBaseTest,
2739 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2740 CreatePool(4, 4);
2741 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2742
2743 ClientSocketHandle handle1;
2744 TestCompletionCallback callback1;
2745 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2746 params_,
2747 kDefaultPriority,
2748 &callback1,
2749 pool_.get(),
2750 BoundNetLog()));
2751
2752 ClientSocketHandle handle2;
2753 TestCompletionCallback callback2;
2754 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2755 params_,
2756 kDefaultPriority,
2757 &callback2,
2758 pool_.get(),
2759 BoundNetLog()));
2760
2761 ClientSocketHandle handle3;
2762 TestCompletionCallback callback3;
2763 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2764 params_,
2765 kDefaultPriority,
2766 &callback3,
2767 pool_.get(),
2768 BoundNetLog()));
2769
2770 ASSERT_TRUE(pool_->HasGroup("a"));
2771 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2772 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2773
2774 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2775
2776 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2777 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2778
2779 EXPECT_EQ(OK, callback1.WaitForResult());
2780 EXPECT_EQ(OK, callback2.WaitForResult());
2781 EXPECT_EQ(OK, callback3.WaitForResult());
2782 handle1.Reset();
2783 handle2.Reset();
2784 handle3.Reset();
2785
2786 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2787 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2788}
2789
2790TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2791 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2792 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2793
2794 ASSERT_FALSE(pool_->HasGroup("a"));
2795
2796 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2797 BoundNetLog());
2798
2799 ASSERT_TRUE(pool_->HasGroup("a"));
2800 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2801
2802 ASSERT_FALSE(pool_->HasGroup("b"));
2803
2804 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2805 BoundNetLog());
2806
2807 ASSERT_FALSE(pool_->HasGroup("b"));
2808}
2809
2810TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2811 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2812 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2813
2814 ASSERT_FALSE(pool_->HasGroup("a"));
2815
2816 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2817 BoundNetLog());
2818
2819 ASSERT_TRUE(pool_->HasGroup("a"));
2820 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2821
2822 ASSERT_FALSE(pool_->HasGroup("b"));
2823
2824 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2825 BoundNetLog());
2826
2827 ASSERT_TRUE(pool_->HasGroup("b"));
2828 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2829}
2830
2831TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2832 CreatePool(4, 4);
2833 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2834
2835 ClientSocketHandle handle1;
2836 TestCompletionCallback callback1;
2837 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2838 params_,
2839 kDefaultPriority,
2840 &callback1,
2841 pool_.get(),
2842 BoundNetLog()));
2843 ASSERT_EQ(OK, callback1.WaitForResult());
2844 handle1.Reset();
2845
2846 ASSERT_TRUE(pool_->HasGroup("a"));
2847 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2848 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2849
2850 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2851
2852 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2853 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2854}
2855
2856TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2857 CreatePool(4, 4);
2858 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2859
2860 ClientSocketHandle handle1;
2861 TestCompletionCallback callback1;
2862 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2863 params_,
2864 kDefaultPriority,
2865 &callback1,
2866 pool_.get(),
2867 BoundNetLog()));
2868 ASSERT_EQ(OK, callback1.WaitForResult());
2869
2870 ASSERT_TRUE(pool_->HasGroup("a"));
2871 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2872 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2873 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2874
2875 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2876
2877 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2878 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2879 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2880}
2881
2882TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2883 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2884 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2885
2886 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2887 BoundNetLog());
2888
2889 ASSERT_TRUE(pool_->HasGroup("a"));
2890 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2891 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2892
2893 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2894 BoundNetLog());
2895
2896 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2897 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2898}
2899
2900TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2901 CreatePool(4, 4);
2902 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2903
2904 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2905
2906 ASSERT_TRUE(pool_->HasGroup("a"));
2907 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2908 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2909
2910 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2911 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2912 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2913
2914 ClientSocketHandle handle1;
2915 TestCompletionCallback callback1;
2916 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2917 params_,
2918 kDefaultPriority,
2919 &callback1,
2920 pool_.get(),
2921 BoundNetLog()));
2922 ASSERT_EQ(OK, callback1.WaitForResult());
2923
2924 ClientSocketHandle handle2;
2925 TestCompletionCallback callback2;
2926 int rv = handle2.Init("a",
2927 params_,
2928 kDefaultPriority,
2929 &callback2,
2930 pool_.get(),
2931 BoundNetLog());
2932 if (rv != OK) {
2933 EXPECT_EQ(ERR_IO_PENDING, rv);
2934 EXPECT_EQ(OK, callback2.WaitForResult());
2935 }
2936
2937 handle1.Reset();
2938 handle2.Reset();
2939
2940 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2941
2942 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2943 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2944 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2945}
2946
2947TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2948 CreatePool(4, 4);
2949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2950
2951 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2952
2953 ASSERT_TRUE(pool_->HasGroup("a"));
2954 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2955 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2956
2957 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2958 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2959 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2960
2961 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2962 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2963 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2964
2965 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2966 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2967 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2968}
2969
2970TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
2971 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2972 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2973
2974 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2975
2976 ASSERT_TRUE(pool_->HasGroup("a"));
2977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2978 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2979
2980 ClientSocketHandle handle1;
2981 TestCompletionCallback callback1;
2982 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2983 params_,
2984 kDefaultPriority,
2985 &callback1,
2986 pool_.get(),
2987 BoundNetLog()));
2988
2989 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2990 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2991
2992 ASSERT_EQ(OK, callback1.WaitForResult());
2993
2994 handle1.Reset();
2995
2996 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2997}
2998
[email protected]f6d1d6eb2009-06-24 20:16:092999} // namespace
3000
3001} // namespace net