blob: 1f99b3da225d2e0bc0a4c92607f7e40aa4dcc63d [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]f6d1d6eb2009-06-24 20:16:0926#include "testing/gtest/include/gtest/gtest.h"
27
28namespace net {
29
30namespace {
31
[email protected]211d21722009-07-22 15:48:5332const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2033const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5234const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0135
[email protected]df4b4ef2010-07-12 18:25:2136class TestSocketParams : public base::RefCounted<TestSocketParams> {
37 private:
38 friend class base::RefCounted<TestSocketParams>;
39 ~TestSocketParams() {}
40};
[email protected]7fc5b09a2010-02-27 00:07:3841typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4942
[email protected]f6d1d6eb2009-06-24 20:16:0943class MockClientSocket : public ClientSocket {
44 public:
[email protected]0f873e82010-09-02 16:09:0145 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0946
[email protected]ab838892009-06-30 18:49:0547 // Socket methods:
48 virtual int Read(
49 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
50 return ERR_UNEXPECTED;
51 }
52
53 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0154 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
55 was_used_to_convey_data_ = true;
56 return len;
[email protected]ab838892009-06-30 18:49:0557 }
[email protected]06650c52010-06-03 00:49:1758 virtual bool SetReceiveBufferSize(int32 size) { return true; }
59 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0560
[email protected]f6d1d6eb2009-06-24 20:16:0961 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0562
[email protected]a2006ece2010-04-23 16:44:0263 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0964 connected_ = true;
65 return OK;
66 }
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]ab838892009-06-30 18:49:0568 virtual void Disconnect() { connected_ = false; }
69 virtual bool IsConnected() const { return connected_; }
70 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0171
[email protected]ac9eec62010-02-20 18:50:3872 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1673 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0974 }
[email protected]f6d1d6eb2009-06-24 20:16:0975
[email protected]a2006ece2010-04-23 16:44:0276 virtual const BoundNetLog& NetLog() const {
77 return net_log_;
78 }
79
[email protected]9b5614a2010-08-25 20:29:4580 virtual void SetSubresourceSpeculation() {}
81 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0182 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]9b5614a2010-08-25 20:29:4583
[email protected]f6d1d6eb2009-06-24 20:16:0984 private:
85 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0286 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0187 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0988
[email protected]ab838892009-06-30 18:49:0589 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0990};
91
[email protected]5fc08e32009-07-15 17:09:5792class TestConnectJob;
93
[email protected]f6d1d6eb2009-06-24 20:16:0994class MockClientSocketFactory : public ClientSocketFactory {
95 public:
[email protected]ab838892009-06-30 18:49:0596 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0997
[email protected]0a0b7682010-08-25 17:08:0798 virtual ClientSocket* CreateTCPClientSocket(
99 const AddressList& addresses,
100 NetLog* /* net_log */,
101 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09102 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05103 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09104 }
105
106 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18107 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:09108 const std::string& hostname,
[email protected]7ab5bbd12010-10-19 13:33:21109 const SSLConfig& ssl_config,
110 SSLHostInfo* ssl_host_info) {
[email protected]f6d1d6eb2009-06-24 20:16:09111 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21112 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09113 return NULL;
114 }
115
[email protected]5fc08e32009-07-15 17:09:57116 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
117 void SignalJobs();
118
[email protected]f6d1d6eb2009-06-24 20:16:09119 int allocation_count() const { return allocation_count_; }
120
[email protected]f6d1d6eb2009-06-24 20:16:09121 private:
122 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57123 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09124};
125
[email protected]ab838892009-06-30 18:49:05126class TestConnectJob : public ConnectJob {
127 public:
128 enum JobType {
129 kMockJob,
130 kMockFailingJob,
131 kMockPendingJob,
132 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57133 kMockWaitingJob,
134 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13135 kMockRecoverableJob,
136 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18137 kMockAdditionalErrorStateJob,
138 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05139 };
140
[email protected]994d4932010-07-12 17:55:13141 // The kMockPendingJob uses a slight delay before allowing the connect
142 // to complete.
143 static const int kPendingConnectDelay = 2;
144
[email protected]ab838892009-06-30 18:49:05145 TestConnectJob(JobType job_type,
146 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49147 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34148 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05149 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30150 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17151 NetLog* net_log)
152 : ConnectJob(group_name, timeout_duration, delegate,
153 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58154 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05155 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21156 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18157 load_state_(LOAD_STATE_IDLE),
158 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05159
[email protected]974ebd62009-08-03 23:14:34160 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13161 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34162 }
163
[email protected]46451352009-09-01 14:54:21164 virtual LoadState GetLoadState() const { return load_state_; }
165
[email protected]e60e47a2010-07-14 03:37:18166 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
167 if (store_additional_error_state_) {
168 // Set all of the additional error state fields in some way.
169 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43170 HttpResponseInfo info;
171 info.headers = new HttpResponseHeaders("");
172 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18173 }
174 }
175
[email protected]974ebd62009-08-03 23:14:34176 private:
[email protected]ab838892009-06-30 18:49:05177 // ConnectJob methods:
178
[email protected]974ebd62009-08-03 23:14:34179 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05180 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07181 client_socket_factory_->CreateTCPClientSocket(
182 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40183 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05184 switch (job_type_) {
185 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13186 return DoConnect(true /* successful */, false /* sync */,
187 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05188 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13189 return DoConnect(false /* error */, false /* sync */,
190 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05191 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57192 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47193
194 // Depending on execution timings, posting a delayed task can result
195 // in the task getting executed the at the earliest possible
196 // opportunity or only after returning once from the message loop and
197 // then a second call into the message loop. In order to make behavior
198 // more deterministic, we change the default delay to 2ms. This should
199 // always require us to wait for the second call into the message loop.
200 //
201 // N.B. The correct fix for this and similar timing problems is to
202 // abstract time for the purpose of unittests. Unfortunately, we have
203 // a lot of third-party components that directly call the various
204 // time functions, so this change would be rather invasive.
205 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05206 FROM_HERE,
207 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47208 &TestConnectJob::DoConnect,
209 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13210 true /* async */,
211 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13212 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05213 return ERR_IO_PENDING;
214 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57215 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47216 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05217 FROM_HERE,
218 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47219 &TestConnectJob::DoConnect,
220 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13221 true /* async */,
222 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47223 2);
[email protected]ab838892009-06-30 18:49:05224 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57225 case kMockWaitingJob:
226 client_socket_factory_->WaitForSignal(this);
227 waiting_success_ = true;
228 return ERR_IO_PENDING;
229 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46230 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57231 FROM_HERE,
232 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46233 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57234 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13235 case kMockRecoverableJob:
236 return DoConnect(false /* error */, false /* sync */,
237 true /* recoverable */);
238 case kMockPendingRecoverableJob:
239 set_load_state(LOAD_STATE_CONNECTING);
240 MessageLoop::current()->PostDelayedTask(
241 FROM_HERE,
242 method_factory_.NewRunnableMethod(
243 &TestConnectJob::DoConnect,
244 false /* error */,
245 true /* async */,
246 true /* recoverable */),
247 2);
248 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18249 case kMockAdditionalErrorStateJob:
250 store_additional_error_state_ = true;
251 return DoConnect(false /* error */, false /* sync */,
252 false /* recoverable */);
253 case kMockPendingAdditionalErrorStateJob:
254 set_load_state(LOAD_STATE_CONNECTING);
255 store_additional_error_state_ = true;
256 MessageLoop::current()->PostDelayedTask(
257 FROM_HERE,
258 method_factory_.NewRunnableMethod(
259 &TestConnectJob::DoConnect,
260 false /* error */,
261 true /* async */,
262 false /* recoverable */),
263 2);
264 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05265 default:
266 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40267 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05268 return ERR_FAILED;
269 }
270 }
271
[email protected]46451352009-09-01 14:54:21272 void set_load_state(LoadState load_state) { load_state_ = load_state; }
273
[email protected]e772db3f2010-07-12 18:11:13274 int DoConnect(bool succeed, bool was_async, bool recoverable) {
275 int result = OK;
[email protected]ab838892009-06-30 18:49:05276 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02277 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13278 } else if (recoverable) {
279 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40280 } else {
[email protected]e772db3f2010-07-12 18:11:13281 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40282 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05283 }
[email protected]2ab05b52009-07-01 23:57:58284
285 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30286 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05287 return result;
288 }
289
[email protected]cfa8228c2010-06-17 01:07:56290 // This function helps simulate the progress of load states on a ConnectJob.
291 // Each time it is called it advances the load state and posts a task to be
292 // called again. It stops at the last connecting load state (the one
293 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57294 void AdvanceLoadState(LoadState state) {
295 int tmp = state;
296 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56297 if (tmp < LOAD_STATE_SENDING_REQUEST) {
298 state = static_cast<LoadState>(tmp);
299 set_load_state(state);
300 MessageLoop::current()->PostTask(
301 FROM_HERE,
302 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
303 state));
304 }
[email protected]5fc08e32009-07-15 17:09:57305 }
306
307 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05308 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57309 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05310 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21311 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18312 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05313
314 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
315};
316
[email protected]d80a4322009-08-14 07:07:49317class TestConnectJobFactory
318 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05319 public:
[email protected]5fc08e32009-07-15 17:09:57320 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05321 : job_type_(TestConnectJob::kMockJob),
322 client_socket_factory_(client_socket_factory) {}
323
324 virtual ~TestConnectJobFactory() {}
325
326 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
327
[email protected]974ebd62009-08-03 23:14:34328 void set_timeout_duration(base::TimeDelta timeout_duration) {
329 timeout_duration_ = timeout_duration;
330 }
331
[email protected]ab838892009-06-30 18:49:05332 // ConnectJobFactory methods:
333
334 virtual ConnectJob* NewConnectJob(
335 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49336 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17337 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05338 return new TestConnectJob(job_type_,
339 group_name,
340 request,
[email protected]974ebd62009-08-03 23:14:34341 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05342 delegate,
[email protected]fd7b7c92009-08-20 19:38:30343 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17344 NULL);
[email protected]ab838892009-06-30 18:49:05345 }
346
[email protected]a796bcec2010-03-22 17:17:26347 virtual base::TimeDelta ConnectionTimeout() const {
348 return timeout_duration_;
349 }
350
[email protected]ab838892009-06-30 18:49:05351 private:
352 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34353 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57354 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05355
356 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
357};
358
359class TestClientSocketPool : public ClientSocketPool {
360 public:
361 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53362 int max_sockets,
[email protected]ab838892009-06-30 18:49:05363 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13364 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16365 base::TimeDelta unused_idle_socket_timeout,
366 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49367 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00368 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16369 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38370 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05371
[email protected]2431756e2010-09-29 20:26:13372 virtual ~TestClientSocketPool() {}
373
[email protected]ab838892009-06-30 18:49:05374 virtual int RequestSocket(
375 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49376 const void* params,
[email protected]ac790b42009-12-02 04:31:31377 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05378 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46379 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53380 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21381 const scoped_refptr<TestSocketParams>* casted_socket_params =
382 static_cast<const scoped_refptr<TestSocketParams>*>(params);
383 return base_.RequestSocket(group_name, *casted_socket_params, priority,
384 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05385 }
386
[email protected]2c2bef152010-10-13 00:55:03387 virtual void RequestSockets(const std::string& group_name,
388 const void* params,
389 int num_sockets,
390 const BoundNetLog& net_log) {
391 const scoped_refptr<TestSocketParams>* casted_params =
392 static_cast<const scoped_refptr<TestSocketParams>*>(params);
393
394 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
395 }
396
[email protected]ab838892009-06-30 18:49:05397 virtual void CancelRequest(
398 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21399 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49400 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05401 }
402
403 virtual void ReleaseSocket(
404 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24405 ClientSocket* socket,
406 int id) {
407 base_.ReleaseSocket(group_name, socket, id);
408 }
409
410 virtual void Flush() {
411 base_.Flush();
[email protected]ab838892009-06-30 18:49:05412 }
413
414 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49415 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05416 }
417
[email protected]d80a4322009-08-14 07:07:49418 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05419
420 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49421 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05422 }
423
424 virtual LoadState GetLoadState(const std::string& group_name,
425 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49426 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05427 }
428
[email protected]ba00b492010-09-08 14:53:38429 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
430 const std::string& type,
431 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27432 return base_.GetInfoAsValue(name, type);
433 }
434
[email protected]a796bcec2010-03-22 17:17:26435 virtual base::TimeDelta ConnectionTimeout() const {
436 return base_.ConnectionTimeout();
437 }
438
[email protected]2431756e2010-09-29 20:26:13439 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00440 return base_.histograms();
441 }
[email protected]a796bcec2010-03-22 17:17:26442
[email protected]d80a4322009-08-14 07:07:49443 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20444
[email protected]974ebd62009-08-03 23:14:34445 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49446 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34447 }
448
[email protected]2c2bef152010-10-13 00:55:03449 int NumActiveSocketsInGroup(const std::string& group_name) const {
450 return base_.NumActiveSocketsInGroup(group_name);
451 }
452
[email protected]2abfe90a2010-08-25 17:49:51453 bool HasGroup(const std::string& group_name) const {
454 return base_.HasGroup(group_name);
455 }
456
[email protected]9bf28db2009-08-29 01:35:16457 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
458
[email protected]06d94042010-08-25 01:45:22459 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54460
[email protected]ab838892009-06-30 18:49:05461 private:
[email protected]d80a4322009-08-14 07:07:49462 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05463
464 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
465};
466
[email protected]a937a06d2009-08-19 21:19:24467} // namespace
468
[email protected]7fc5b09a2010-02-27 00:07:38469REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24470
471namespace {
472
[email protected]5fc08e32009-07-15 17:09:57473void MockClientSocketFactory::SignalJobs() {
474 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
475 it != waiting_jobs_.end(); ++it) {
476 (*it)->Signal();
477 }
478 waiting_jobs_.clear();
479}
480
[email protected]974ebd62009-08-03 23:14:34481class TestConnectJobDelegate : public ConnectJob::Delegate {
482 public:
483 TestConnectJobDelegate()
484 : have_result_(false), waiting_for_result_(false), result_(OK) {}
485 virtual ~TestConnectJobDelegate() {}
486
487 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
488 result_ = result;
[email protected]6e713f02009-08-06 02:56:40489 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07490 // socket.get() should be NULL iff result != OK
491 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34492 delete job;
493 have_result_ = true;
494 if (waiting_for_result_)
495 MessageLoop::current()->Quit();
496 }
497
498 int WaitForResult() {
499 DCHECK(!waiting_for_result_);
500 while (!have_result_) {
501 waiting_for_result_ = true;
502 MessageLoop::current()->Run();
503 waiting_for_result_ = false;
504 }
505 have_result_ = false; // auto-reset for next callback
506 return result_;
507 }
508
509 private:
510 bool have_result_;
511 bool waiting_for_result_;
512 int result_;
513};
514
[email protected]2431756e2010-09-29 20:26:13515class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09516 protected:
[email protected]b89f7e42010-05-20 20:37:00517 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21518 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13519 histograms_("ClientSocketPoolTest") {}
520
521 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20522
[email protected]211d21722009-07-22 15:48:53523 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16524 CreatePoolWithIdleTimeouts(
525 max_sockets,
526 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00527 base::TimeDelta::FromSeconds(
528 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16529 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
530 }
531
532 void CreatePoolWithIdleTimeouts(
533 int max_sockets, int max_sockets_per_group,
534 base::TimeDelta unused_idle_socket_timeout,
535 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20536 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04537 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13538 pool_.reset(new TestClientSocketPool(max_sockets,
539 max_sockets_per_group,
540 &histograms_,
541 unused_idle_socket_timeout,
542 used_idle_socket_timeout,
543 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20544 }
[email protected]f6d1d6eb2009-06-24 20:16:09545
[email protected]ac790b42009-12-02 04:31:31546 int StartRequest(const std::string& group_name,
547 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13548 return test_base_.StartRequestUsingPool<
549 TestClientSocketPool, TestSocketParams>(
550 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09551 }
552
[email protected]2431756e2010-09-29 20:26:13553 int GetOrderOfRequest(size_t index) const {
554 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09555 }
556
[email protected]2431756e2010-09-29 20:26:13557 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
558 return test_base_.ReleaseOneConnection(keep_alive);
559 }
560
561 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
562 test_base_.ReleaseAllConnections(keep_alive);
563 }
564
565 TestSocketRequest* request(int i) { return test_base_.request(i); }
566 size_t requests_size() const { return test_base_.requests_size(); }
567 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
568 size_t completion_count() const { return test_base_.completion_count(); }
569
[email protected]f6d1d6eb2009-06-24 20:16:09570 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04571 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21572 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13573 ClientSocketPoolHistograms histograms_;
574 scoped_ptr<TestClientSocketPool> pool_;
575 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09576};
577
[email protected]974ebd62009-08-03 23:14:34578// Even though a timeout is specified, it doesn't time out on a synchronous
579// completion.
580TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
581 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06582 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49583 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03584 &ignored, NULL, kDefaultPriority,
585 internal::ClientSocketPoolBaseHelper::NORMAL,
586 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34587 scoped_ptr<TestConnectJob> job(
588 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12589 "a",
[email protected]974ebd62009-08-03 23:14:34590 request,
591 base::TimeDelta::FromMicroseconds(1),
592 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30593 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17594 NULL));
[email protected]974ebd62009-08-03 23:14:34595 EXPECT_EQ(OK, job->Connect());
596}
597
598TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
599 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06600 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17601 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53602
[email protected]d80a4322009-08-14 07:07:49603 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03604 &ignored, NULL, kDefaultPriority,
605 internal::ClientSocketPoolBaseHelper::NORMAL,
606 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34607 // Deleted by TestConnectJobDelegate.
608 TestConnectJob* job =
609 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12610 "a",
[email protected]974ebd62009-08-03 23:14:34611 request,
612 base::TimeDelta::FromMicroseconds(1),
613 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30614 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17615 &log);
[email protected]974ebd62009-08-03 23:14:34616 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
617 PlatformThread::Sleep(1);
618 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30619
[email protected]06650c52010-06-03 00:49:17620 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46621 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53622 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17623 EXPECT_TRUE(LogContainsBeginEvent(
624 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46625 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17626 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
627 NetLog::PHASE_NONE));
628 EXPECT_TRUE(LogContainsEvent(
629 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53630 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46631 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17632 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
633 EXPECT_TRUE(LogContainsEndEvent(
634 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34635}
636
[email protected]5fc08e32009-07-15 17:09:57637TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53638 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20639
[email protected]f6d1d6eb2009-06-24 20:16:09640 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06641 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53642 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
643
[email protected]2431756e2010-09-29 20:26:13644 EXPECT_EQ(OK,
645 handle.Init("a",
646 params_,
647 kDefaultPriority,
648 &callback,
649 pool_.get(),
650 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09651 EXPECT_TRUE(handle.is_initialized());
652 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09653 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30654
[email protected]06650c52010-06-03 00:49:17655 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46656 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53657 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53658 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17659 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
660 NetLog::PHASE_NONE));
661 EXPECT_TRUE(LogContainsEvent(
662 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53663 NetLog::PHASE_NONE));
664 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17665 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09666}
667
[email protected]ab838892009-06-30 18:49:05668TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53669 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20670
[email protected]ab838892009-06-30 18:49:05671 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53672 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
673
[email protected]2431756e2010-09-29 20:26:13674 ClientSocketHandle handle;
675 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18676 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13677 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43678 HttpResponseInfo info;
679 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13680 handle.set_ssl_error_response_info(info);
681 EXPECT_EQ(ERR_CONNECTION_FAILED,
682 handle.Init("a",
683 params_,
684 kDefaultPriority,
685 &callback,
686 pool_.get(),
687 log.bound()));
688 EXPECT_FALSE(handle.socket());
689 EXPECT_FALSE(handle.is_ssl_error());
690 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30691
[email protected]06650c52010-06-03 00:49:17692 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27693 EXPECT_TRUE(LogContainsBeginEvent(
694 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17695 EXPECT_TRUE(LogContainsEvent(
696 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
697 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02698 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17699 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09700}
701
[email protected]211d21722009-07-22 15:48:53702TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
703 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
704
[email protected]9e743cd2010-03-16 07:03:53705 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30706
[email protected]211d21722009-07-22 15:48:53707 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
708 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
709 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
710 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
711
[email protected]2431756e2010-09-29 20:26:13712 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53713 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13714 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53715
716 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
717 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
719
[email protected]2431756e2010-09-29 20:26:13720 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53721
[email protected]2431756e2010-09-29 20:26:13722 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53723 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13724 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53725
726 EXPECT_EQ(1, GetOrderOfRequest(1));
727 EXPECT_EQ(2, GetOrderOfRequest(2));
728 EXPECT_EQ(3, GetOrderOfRequest(3));
729 EXPECT_EQ(4, GetOrderOfRequest(4));
730 EXPECT_EQ(5, GetOrderOfRequest(5));
731 EXPECT_EQ(6, GetOrderOfRequest(6));
732 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17733
734 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13735 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53736}
737
738TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
740
[email protected]9e743cd2010-03-16 07:03:53741 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30742
[email protected]211d21722009-07-22 15:48:53743 // Reach all limits: max total sockets, and max sockets per group.
744 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
745 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
746 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
747 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
748
[email protected]2431756e2010-09-29 20:26:13749 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53750 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13751 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53752
753 // Now create a new group and verify that we don't starve it.
754 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
755
[email protected]2431756e2010-09-29 20:26:13756 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53757
[email protected]2431756e2010-09-29 20:26:13758 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53759 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13760 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53761
762 EXPECT_EQ(1, GetOrderOfRequest(1));
763 EXPECT_EQ(2, GetOrderOfRequest(2));
764 EXPECT_EQ(3, GetOrderOfRequest(3));
765 EXPECT_EQ(4, GetOrderOfRequest(4));
766 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17767
768 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13769 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53770}
771
772TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
773 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
774
[email protected]ac790b42009-12-02 04:31:31775 EXPECT_EQ(OK, StartRequest("b", LOWEST));
776 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
777 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
778 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53779
[email protected]2431756e2010-09-29 20:26:13780 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53781 client_socket_factory_.allocation_count());
782
[email protected]ac790b42009-12-02 04:31:31783 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
784 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53786
[email protected]2431756e2010-09-29 20:26:13787 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53788
[email protected]2431756e2010-09-29 20:26:13789 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53790
791 // First 4 requests don't have to wait, and finish in order.
792 EXPECT_EQ(1, GetOrderOfRequest(1));
793 EXPECT_EQ(2, GetOrderOfRequest(2));
794 EXPECT_EQ(3, GetOrderOfRequest(3));
795 EXPECT_EQ(4, GetOrderOfRequest(4));
796
[email protected]ac790b42009-12-02 04:31:31797 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
798 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53799 EXPECT_EQ(7, GetOrderOfRequest(5));
800 EXPECT_EQ(6, GetOrderOfRequest(6));
801 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17802
803 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13804 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53805}
806
807TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
808 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
809
[email protected]ac790b42009-12-02 04:31:31810 EXPECT_EQ(OK, StartRequest("a", LOWEST));
811 EXPECT_EQ(OK, StartRequest("a", LOW));
812 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
813 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53814
[email protected]2431756e2010-09-29 20:26:13815 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53816 client_socket_factory_.allocation_count());
817
[email protected]ac790b42009-12-02 04:31:31818 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53821
[email protected]2431756e2010-09-29 20:26:13822 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53823
[email protected]2431756e2010-09-29 20:26:13824 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53825 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13826 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53827
828 // First 4 requests don't have to wait, and finish in order.
829 EXPECT_EQ(1, GetOrderOfRequest(1));
830 EXPECT_EQ(2, GetOrderOfRequest(2));
831 EXPECT_EQ(3, GetOrderOfRequest(3));
832 EXPECT_EQ(4, GetOrderOfRequest(4));
833
834 // Request ("b", 7) has the highest priority, but we can't make new socket for
835 // group "b", because it has reached the per-group limit. Then we make
836 // socket for ("c", 6), because it has higher priority than ("a", 4),
837 // and we still can't make a socket for group "b".
838 EXPECT_EQ(5, GetOrderOfRequest(5));
839 EXPECT_EQ(6, GetOrderOfRequest(6));
840 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17841
842 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13843 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53844}
845
846// Make sure that we count connecting sockets against the total limit.
847TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
849
850 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
851 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
852 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
853
854 // Create one asynchronous request.
855 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
857
[email protected]6b175382009-10-13 06:47:47858 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
859 // actually become pending until 2ms after they have been created. In order
860 // to flush all tasks, we need to wait so that we know there are no
861 // soon-to-be-pending tasks waiting.
862 PlatformThread::Sleep(10);
863 MessageLoop::current()->RunAllPending();
864
[email protected]211d21722009-07-22 15:48:53865 // The next synchronous request should wait for its turn.
866 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
867 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
868
[email protected]2431756e2010-09-29 20:26:13869 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53870
[email protected]2431756e2010-09-29 20:26:13871 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53872 client_socket_factory_.allocation_count());
873
874 EXPECT_EQ(1, GetOrderOfRequest(1));
875 EXPECT_EQ(2, GetOrderOfRequest(2));
876 EXPECT_EQ(3, GetOrderOfRequest(3));
877 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17878 EXPECT_EQ(5, GetOrderOfRequest(5));
879
880 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13881 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53882}
883
[email protected]6427fe22010-04-16 22:27:41884TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
885 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
886 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
887
888 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
889 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
890 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
891 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
892
893 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
894
895 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
896
897 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
899
900 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
901
[email protected]2431756e2010-09-29 20:26:13902 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41903 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[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 + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13906 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
907 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41908 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
909}
910
[email protected]d7027bb2010-05-10 18:58:54911TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
912 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
913 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
914
915 ClientSocketHandle handle;
916 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13917 EXPECT_EQ(ERR_IO_PENDING,
918 handle.Init("a",
919 params_,
920 kDefaultPriority,
921 &callback,
922 pool_.get(),
923 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54924
925 ClientSocketHandle handles[4];
926 for (size_t i = 0; i < arraysize(handles); ++i) {
927 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13928 EXPECT_EQ(ERR_IO_PENDING,
929 handles[i].Init("b",
930 params_,
931 kDefaultPriority,
932 &callback,
933 pool_.get(),
934 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54935 }
936
937 // One will be stalled, cancel all the handles now.
938 // This should hit the OnAvailableSocketSlot() code where we previously had
939 // stalled groups, but no longer have any.
940 for (size_t i = 0; i < arraysize(handles); ++i)
941 handles[i].Reset();
942}
943
[email protected]eb5a99382010-07-11 03:18:26944TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54945 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
946 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
947
[email protected]eb5a99382010-07-11 03:18:26948 {
949 ClientSocketHandle handles[kDefaultMaxSockets];
950 TestCompletionCallback callbacks[kDefaultMaxSockets];
951 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13952 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
953 params_,
[email protected]e83326f2010-07-31 17:29:25954 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13955 &callbacks[i],
956 pool_.get(),
957 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26958 }
959
960 // Force a stalled group.
961 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54962 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13963 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
964 params_,
965 kDefaultPriority,
966 &callback,
967 pool_.get(),
968 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26969
970 // Cancel the stalled request.
971 stalled_handle.Reset();
972
973 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
974 EXPECT_EQ(0, pool_->IdleSocketCount());
975
976 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54977 }
978
[email protected]43a21b82010-06-10 21:30:54979 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
980 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26981}
[email protected]43a21b82010-06-10 21:30:54982
[email protected]eb5a99382010-07-11 03:18:26983TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
984 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
985 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
986
987 {
988 ClientSocketHandle handles[kDefaultMaxSockets];
989 for (int i = 0; i < kDefaultMaxSockets; ++i) {
990 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
992 params_,
993 kDefaultPriority,
994 &callback,
995 pool_.get(),
996 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26997 }
998
999 // Force a stalled group.
1000 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1001 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541002 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131003 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1004 params_,
1005 kDefaultPriority,
1006 &callback,
1007 pool_.get(),
1008 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261009
1010 // Since it is stalled, it should have no connect jobs.
1011 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1012
1013 // Cancel the stalled request.
1014 handles[0].Reset();
1015
[email protected]eb5a99382010-07-11 03:18:261016 // Now we should have a connect job.
1017 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1018
1019 // The stalled socket should connect.
1020 EXPECT_EQ(OK, callback.WaitForResult());
1021
1022 EXPECT_EQ(kDefaultMaxSockets + 1,
1023 client_socket_factory_.allocation_count());
1024 EXPECT_EQ(0, pool_->IdleSocketCount());
1025 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1026
1027 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541028 }
1029
[email protected]eb5a99382010-07-11 03:18:261030 EXPECT_EQ(1, pool_->IdleSocketCount());
1031}
[email protected]43a21b82010-06-10 21:30:541032
[email protected]eb5a99382010-07-11 03:18:261033TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1034 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1035 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541036
[email protected]eb5a99382010-07-11 03:18:261037 ClientSocketHandle stalled_handle;
1038 TestCompletionCallback callback;
1039 {
1040 ClientSocketHandle handles[kDefaultMaxSockets];
1041 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1042 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061043 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131044 params_,
1045 kDefaultPriority,
1046 &callback,
1047 pool_.get(),
1048 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261049 }
1050
1051 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1052 EXPECT_EQ(0, pool_->IdleSocketCount());
1053
1054 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131055 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1056 params_,
1057 kDefaultPriority,
1058 &callback,
1059 pool_.get(),
1060 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261061
1062 // Dropping out of scope will close all handles and return them to idle.
1063 }
[email protected]43a21b82010-06-10 21:30:541064
1065 // But if we wait for it, the released idle sockets will be closed in
1066 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101067 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261068
1069 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1070 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541071}
1072
1073// Regression test for http://crbug.com/40952.
1074TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1075 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221076 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541077 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1078
1079 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1080 ClientSocketHandle handle;
1081 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131082 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1083 params_,
1084 kDefaultPriority,
1085 &callback,
1086 pool_.get(),
1087 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541088 }
1089
1090 // Flush all the DoReleaseSocket tasks.
1091 MessageLoop::current()->RunAllPending();
1092
1093 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1094 // reuse a socket.
1095 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1096 ClientSocketHandle handle;
1097 TestCompletionCallback callback;
1098
1099 // "0" is special here, since it should be the first entry in the sorted map,
1100 // which is the one which we would close an idle socket for. We shouldn't
1101 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131102 EXPECT_EQ(OK, handle.Init("0",
1103 params_,
1104 kDefaultPriority,
1105 &callback,
1106 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211107 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541108
1109 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1110 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1111}
1112
[email protected]ab838892009-06-30 18:49:051113TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531114 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091115
[email protected]c9d6a1d2009-07-14 16:15:201116 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1117 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031118 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1120 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1121 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1122 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1123 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091124
[email protected]2431756e2010-09-29 20:26:131125 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091126
[email protected]c9d6a1d2009-07-14 16:15:201127 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1128 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131129 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1130 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091131
[email protected]c9d6a1d2009-07-14 16:15:201132 EXPECT_EQ(1, GetOrderOfRequest(1));
1133 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031134 EXPECT_EQ(8, GetOrderOfRequest(3));
1135 EXPECT_EQ(6, GetOrderOfRequest(4));
1136 EXPECT_EQ(4, GetOrderOfRequest(5));
1137 EXPECT_EQ(3, GetOrderOfRequest(6));
1138 EXPECT_EQ(5, GetOrderOfRequest(7));
1139 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171140
1141 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131142 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091143}
1144
[email protected]ab838892009-06-30 18:49:051145TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091147
[email protected]c9d6a1d2009-07-14 16:15:201148 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1149 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311150 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1151 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1152 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091155
[email protected]2431756e2010-09-29 20:26:131156 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091157
[email protected]2431756e2010-09-29 20:26:131158 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1159 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201160
[email protected]2431756e2010-09-29 20:26:131161 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201162 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131163 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1164 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091165}
1166
1167// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051168// The pending connect job will be cancelled and should not call back into
1169// ClientSocketPoolBase.
1170TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531171 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201172
[email protected]ab838892009-06-30 18:49:051173 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131174 ClientSocketHandle handle;
1175 TestCompletionCallback callback;
1176 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1177 params_,
1178 kDefaultPriority,
1179 &callback,
1180 pool_.get(),
1181 BoundNetLog()));
1182 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091183}
1184
[email protected]ab838892009-06-30 18:49:051185TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531186 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201187
[email protected]ab838892009-06-30 18:49:051188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061189 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091190 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091191
[email protected]2431756e2010-09-29 20:26:131192 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1193 params_,
1194 kDefaultPriority,
1195 &callback,
1196 pool_.get(),
1197 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091198
1199 handle.Reset();
1200
1201 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131202 EXPECT_EQ(ERR_IO_PENDING,
1203 handle.Init("a",
1204 params_,
1205 kDefaultPriority,
1206 &callback2,
1207 pool_.get(),
1208 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091209
1210 EXPECT_EQ(OK, callback2.WaitForResult());
1211 EXPECT_FALSE(callback.have_result());
1212
1213 handle.Reset();
1214}
1215
[email protected]ab838892009-06-30 18:49:051216TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531217 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091218
[email protected]c9d6a1d2009-07-14 16:15:201219 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1220 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311221 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1222 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091226
1227 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201228 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131229 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1230 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091231
[email protected]2431756e2010-09-29 20:26:131232 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091233
[email protected]c9d6a1d2009-07-14 16:15:201234 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1235 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131236 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1237 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091238
[email protected]c9d6a1d2009-07-14 16:15:201239 EXPECT_EQ(1, GetOrderOfRequest(1));
1240 EXPECT_EQ(2, GetOrderOfRequest(2));
1241 EXPECT_EQ(5, GetOrderOfRequest(3));
1242 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131243 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1244 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201245 EXPECT_EQ(4, GetOrderOfRequest(6));
1246 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171247
1248 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131249 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091250}
1251
1252class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1253 public:
[email protected]2ab05b52009-07-01 23:57:581254 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241255 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581256 TestConnectJobFactory* test_connect_job_factory,
1257 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091258 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061259 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581260 within_callback_(false),
1261 test_connect_job_factory_(test_connect_job_factory),
1262 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091263
1264 virtual void RunWithParams(const Tuple1<int>& params) {
1265 callback_.RunWithParams(params);
1266 ASSERT_EQ(OK, params.a);
1267
1268 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581269 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111270
1271 // Don't allow reuse of the socket. Disconnect it and then release it and
1272 // run through the MessageLoop once to get it completely released.
1273 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091274 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111275 {
1276 MessageLoop::ScopedNestableTaskAllower nestable(
1277 MessageLoop::current());
1278 MessageLoop::current()->RunAllPending();
1279 }
[email protected]f6d1d6eb2009-06-24 20:16:091280 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471281 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211282 scoped_refptr<TestSocketParams> params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:131283 int rv = handle_->Init("a",
1284 params,
1285 kDefaultPriority,
1286 &next_job_callback,
1287 pool_,
1288 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581289 switch (next_job_type_) {
1290 case TestConnectJob::kMockJob:
1291 EXPECT_EQ(OK, rv);
1292 break;
1293 case TestConnectJob::kMockPendingJob:
1294 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471295
1296 // For pending jobs, wait for new socket to be created. This makes
1297 // sure there are no more pending operations nor any unclosed sockets
1298 // when the test finishes.
1299 // We need to give it a little bit of time to run, so that all the
1300 // operations that happen on timers (e.g. cleanup of idle
1301 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111302 {
1303 MessageLoop::ScopedNestableTaskAllower nestable(
1304 MessageLoop::current());
1305 PlatformThread::Sleep(10);
1306 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1307 }
[email protected]2ab05b52009-07-01 23:57:581308 break;
1309 default:
1310 FAIL() << "Unexpected job type: " << next_job_type_;
1311 break;
1312 }
[email protected]f6d1d6eb2009-06-24 20:16:091313 }
1314 }
1315
1316 int WaitForResult() {
1317 return callback_.WaitForResult();
1318 }
1319
1320 private:
1321 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131322 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091323 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581324 TestConnectJobFactory* const test_connect_job_factory_;
1325 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091326 TestCompletionCallback callback_;
1327};
1328
[email protected]2ab05b52009-07-01 23:57:581329TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531330 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201331
[email protected]0b7648c2009-07-06 20:14:011332 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061333 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581334 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061335 &handle, pool_.get(), connect_job_factory_,
1336 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131337 int rv = handle.Init("a",
1338 params_,
1339 kDefaultPriority,
1340 &callback,
1341 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211342 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091343 ASSERT_EQ(ERR_IO_PENDING, rv);
1344
1345 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581346}
[email protected]f6d1d6eb2009-06-24 20:16:091347
[email protected]2ab05b52009-07-01 23:57:581348TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531349 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201350
[email protected]0b7648c2009-07-06 20:14:011351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061352 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581353 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061354 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131355 int rv = handle.Init("a",
1356 params_,
1357 kDefaultPriority,
1358 &callback,
1359 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211360 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581361 ASSERT_EQ(ERR_IO_PENDING, rv);
1362
1363 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091364}
1365
1366// Make sure that pending requests get serviced after active requests get
1367// cancelled.
[email protected]ab838892009-06-30 18:49:051368TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201370
[email protected]0b7648c2009-07-06 20:14:011371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091372
[email protected]c9d6a1d2009-07-14 16:15:201373 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1374 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1375 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1376 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1377 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1378 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1379 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091380
[email protected]c9d6a1d2009-07-14 16:15:201381 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1382 // Let's cancel them.
1383 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131384 ASSERT_FALSE(request(i)->handle()->is_initialized());
1385 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091386 }
1387
[email protected]f6d1d6eb2009-06-24 20:16:091388 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131389 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1390 EXPECT_EQ(OK, request(i)->WaitForResult());
1391 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091392 }
1393
[email protected]2431756e2010-09-29 20:26:131394 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1395 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091396}
1397
1398// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051399TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531400 const size_t kMaxSockets = 5;
1401 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201402
[email protected]0b7648c2009-07-06 20:14:011403 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091404
[email protected]211d21722009-07-22 15:48:531405 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1406 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091407
1408 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531409 for (size_t i = 0; i < kNumberOfRequests; ++i)
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091411
[email protected]211d21722009-07-22 15:48:531412 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131413 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091414}
1415
[email protected]5fc08e32009-07-15 17:09:571416TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531417 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571418
1419 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1420
[email protected]2431756e2010-09-29 20:26:131421 ClientSocketHandle handle;
1422 TestCompletionCallback callback;
1423 int rv = handle.Init("a",
1424 params_,
1425 kDefaultPriority,
1426 &callback,
1427 pool_.get(),
1428 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571429 EXPECT_EQ(ERR_IO_PENDING, rv);
1430
1431 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131432 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571433
[email protected]2431756e2010-09-29 20:26:131434 rv = handle.Init("a",
1435 params_,
1436 kDefaultPriority,
1437 &callback,
1438 pool_.get(),
1439 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571440 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131441 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571442
[email protected]2431756e2010-09-29 20:26:131443 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571444 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1445}
1446
[email protected]2b7523d2009-07-29 20:29:231447// Regression test for http://crbug.com/17985.
1448TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1449 const int kMaxSockets = 3;
1450 const int kMaxSocketsPerGroup = 2;
1451 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1452
[email protected]ac790b42009-12-02 04:31:311453 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231454
1455 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1456 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1457
1458 // This is going to be a pending request in an otherwise empty group.
1459 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1460
1461 // Reach the maximum socket limit.
1462 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1463
1464 // Create a stalled group with high priorities.
1465 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1466 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231467
[email protected]eb5a99382010-07-11 03:18:261468 // Release the first two sockets from "a". Because this is a keepalive,
1469 // the first release will unblock the pending request for "a". The
1470 // second release will unblock a request for "c", becaue it is the next
1471 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131472 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1473 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231474
1475 // Closing idle sockets should not get us into trouble, but in the bug
1476 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411477 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541478 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261479
1480 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231481}
1482
[email protected]4d3b05d2010-01-27 21:27:291483TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531484 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571485
1486 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131487 ClientSocketHandle handle;
1488 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531489 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131490 int rv = handle.Init("a",
1491 params_,
1492 LOWEST,
1493 &callback,
1494 pool_.get(),
1495 log.bound());
[email protected]5fc08e32009-07-15 17:09:571496 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131497 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1498 EXPECT_EQ(OK, callback.WaitForResult());
1499 EXPECT_TRUE(handle.is_initialized());
1500 EXPECT_TRUE(handle.socket());
1501 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301502
[email protected]06650c52010-06-03 00:49:171503 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461504 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531505 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171506 EXPECT_TRUE(LogContainsEvent(
1507 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1508 NetLog::PHASE_NONE));
1509 EXPECT_TRUE(LogContainsEvent(
1510 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1511 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461512 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171513 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571514}
1515
[email protected]4d3b05d2010-01-27 21:27:291516TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571517 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571519
1520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131521 ClientSocketHandle handle;
1522 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531523 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181524 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131525 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431526 HttpResponseInfo info;
1527 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131528 handle.set_ssl_error_response_info(info);
1529 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1530 params_,
1531 kDefaultPriority,
1532 &callback,
1533 pool_.get(),
1534 log.bound()));
1535 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1536 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1537 EXPECT_FALSE(handle.is_ssl_error());
1538 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301539
[email protected]06650c52010-06-03 00:49:171540 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461541 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531542 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171543 EXPECT_TRUE(LogContainsEvent(
1544 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1545 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321546 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171547 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571548}
1549
[email protected]4d3b05d2010-01-27 21:27:291550TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101551 // TODO(eroman): Add back the log expectations! Removed them because the
1552 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531553 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571554
1555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131556 ClientSocketHandle handle;
1557 TestCompletionCallback callback;
1558 ClientSocketHandle handle2;
1559 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571560
[email protected]2431756e2010-09-29 20:26:131561 EXPECT_EQ(ERR_IO_PENDING,
1562 handle.Init("a",
1563 params_,
1564 kDefaultPriority,
1565 &callback,
1566 pool_.get(),
1567 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531568 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131569 EXPECT_EQ(ERR_IO_PENDING,
1570 handle2.Init("a",
1571 params_,
1572 kDefaultPriority,
1573 &callback2,
1574 pool_.get(),
1575 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571576
[email protected]2431756e2010-09-29 20:26:131577 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571578
[email protected]fd7b7c92009-08-20 19:38:301579
1580 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301581
[email protected]2431756e2010-09-29 20:26:131582 EXPECT_EQ(OK, callback2.WaitForResult());
1583 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301584
1585 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531586 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571587}
1588
[email protected]4d3b05d2010-01-27 21:27:291589TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341590 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1591
[email protected]17a0c6c2009-08-04 00:07:041592 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1593
[email protected]ac790b42009-12-02 04:31:311594 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1595 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1596 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341598
1599 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131600 (*requests())[2]->handle()->Reset();
1601 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341602 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1603
[email protected]2431756e2010-09-29 20:26:131604 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341605 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1606
[email protected]2431756e2010-09-29 20:26:131607 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261608 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341609}
1610
[email protected]5fc08e32009-07-15 17:09:571611// When requests and ConnectJobs are not coupled, the request will get serviced
1612// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291613TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531614 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571615
1616 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321617 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571618
[email protected]2431756e2010-09-29 20:26:131619 std::vector<TestSocketRequest*> request_order;
1620 size_t completion_count; // unused
1621 TestSocketRequest req1(&request_order, &completion_count);
1622 int rv = req1.handle()->Init("a",
1623 params_,
1624 kDefaultPriority,
1625 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211626 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571627 EXPECT_EQ(ERR_IO_PENDING, rv);
1628 EXPECT_EQ(OK, req1.WaitForResult());
1629
1630 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1631 // without a job.
1632 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1633
[email protected]2431756e2010-09-29 20:26:131634 TestSocketRequest req2(&request_order, &completion_count);
1635 rv = req2.handle()->Init("a",
1636 params_,
1637 kDefaultPriority,
1638 &req2,
1639 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211640 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571641 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131642 TestSocketRequest req3(&request_order, &completion_count);
1643 rv = req3.handle()->Init("a",
1644 params_,
1645 kDefaultPriority,
1646 &req3,
1647 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211648 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571649 EXPECT_EQ(ERR_IO_PENDING, rv);
1650
1651 // Both Requests 2 and 3 are pending. We release socket 1 which should
1652 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331653 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261654 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331655 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571656 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331657 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571658
1659 // Signal job 2, which should service request 3.
1660
1661 client_socket_factory_.SignalJobs();
1662 EXPECT_EQ(OK, req3.WaitForResult());
1663
[email protected]2431756e2010-09-29 20:26:131664 ASSERT_EQ(3U, request_order.size());
1665 EXPECT_EQ(&req1, request_order[0]);
1666 EXPECT_EQ(&req2, request_order[1]);
1667 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571668 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1669}
1670
1671// The requests are not coupled to the jobs. So, the requests should finish in
1672// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291673TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531674 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571675 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571677
[email protected]2431756e2010-09-29 20:26:131678 std::vector<TestSocketRequest*> request_order;
1679 size_t completion_count; // unused
1680 TestSocketRequest req1(&request_order, &completion_count);
1681 int rv = req1.handle()->Init("a",
1682 params_,
1683 kDefaultPriority,
1684 &req1,
1685 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211686 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571687 EXPECT_EQ(ERR_IO_PENDING, rv);
1688
[email protected]2431756e2010-09-29 20:26:131689 TestSocketRequest req2(&request_order, &completion_count);
1690 rv = req2.handle()->Init("a",
1691 params_,
1692 kDefaultPriority,
1693 &req2,
1694 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211695 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571696 EXPECT_EQ(ERR_IO_PENDING, rv);
1697
1698 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321699 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571700
[email protected]2431756e2010-09-29 20:26:131701 TestSocketRequest req3(&request_order, &completion_count);
1702 rv = req3.handle()->Init("a",
1703 params_,
1704 kDefaultPriority,
1705 &req3,
1706 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211707 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571708 EXPECT_EQ(ERR_IO_PENDING, rv);
1709
1710 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1711 EXPECT_EQ(OK, req2.WaitForResult());
1712 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1713
[email protected]2431756e2010-09-29 20:26:131714 ASSERT_EQ(3U, request_order.size());
1715 EXPECT_EQ(&req1, request_order[0]);
1716 EXPECT_EQ(&req2, request_order[1]);
1717 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571718}
1719
[email protected]e6ec67b2010-06-16 00:12:461720TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571722 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321723 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571724
[email protected]2431756e2010-09-29 20:26:131725 ClientSocketHandle handle;
1726 TestCompletionCallback callback;
1727 int rv = handle.Init("a",
1728 params_,
1729 kDefaultPriority,
1730 &callback,
1731 pool_.get(),
1732 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571733 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131734 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571735
1736 MessageLoop::current()->RunAllPending();
1737
[email protected]2431756e2010-09-29 20:26:131738 ClientSocketHandle handle2;
1739 TestCompletionCallback callback2;
1740 rv = handle2.Init("a",
1741 params_,
1742 kDefaultPriority,
1743 &callback2, pool_.get(),
1744 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571745 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131746 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1747 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571748}
1749
[email protected]e772db3f2010-07-12 18:11:131750TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1751 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1752 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1753
[email protected]2431756e2010-09-29 20:26:131754 ClientSocketHandle handle;
1755 TestCompletionCallback callback;
1756 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1757 params_,
1758 kDefaultPriority,
1759 &callback, pool_.get(),
1760 BoundNetLog()));
1761 EXPECT_TRUE(handle.is_initialized());
1762 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131763}
1764
1765TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1767
1768 connect_job_factory_->set_job_type(
1769 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131770 ClientSocketHandle handle;
1771 TestCompletionCallback callback;
1772 EXPECT_EQ(ERR_IO_PENDING,
1773 handle.Init("a",
1774 params_,
1775 kDefaultPriority,
1776 &callback,
1777 pool_.get(),
1778 BoundNetLog()));
1779 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1780 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1781 EXPECT_TRUE(handle.is_initialized());
1782 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131783}
1784
[email protected]e60e47a2010-07-14 03:37:181785TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1787 connect_job_factory_->set_job_type(
1788 TestConnectJob::kMockAdditionalErrorStateJob);
1789
[email protected]2431756e2010-09-29 20:26:131790 ClientSocketHandle handle;
1791 TestCompletionCallback callback;
1792 EXPECT_EQ(ERR_CONNECTION_FAILED,
1793 handle.Init("a",
1794 params_,
1795 kDefaultPriority,
1796 &callback,
1797 pool_.get(),
1798 BoundNetLog()));
1799 EXPECT_FALSE(handle.is_initialized());
1800 EXPECT_FALSE(handle.socket());
1801 EXPECT_TRUE(handle.is_ssl_error());
1802 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181803}
1804
1805TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1806 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1807
1808 connect_job_factory_->set_job_type(
1809 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131810 ClientSocketHandle handle;
1811 TestCompletionCallback callback;
1812 EXPECT_EQ(ERR_IO_PENDING,
1813 handle.Init("a",
1814 params_,
1815 kDefaultPriority,
1816 &callback,
1817 pool_.get(),
1818 BoundNetLog()));
1819 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1820 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1821 EXPECT_FALSE(handle.is_initialized());
1822 EXPECT_FALSE(handle.socket());
1823 EXPECT_TRUE(handle.is_ssl_error());
1824 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181825}
1826
[email protected]4d3b05d2010-01-27 21:27:291827TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161828 CreatePoolWithIdleTimeouts(
1829 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1830 base::TimeDelta(), // Time out unused sockets immediately.
1831 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1832
1833 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1834
1835 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1836
[email protected]2431756e2010-09-29 20:26:131837 ClientSocketHandle handle;
1838 TestCompletionCallback callback;
1839 int rv = handle.Init("a",
1840 params_,
1841 LOWEST,
1842 &callback,
1843 pool_.get(),
1844 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161845 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131846 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161847
[email protected]2431756e2010-09-29 20:26:131848 ClientSocketHandle handle2;
1849 TestCompletionCallback callback2;
1850 rv = handle2.Init("a",
1851 params_,
1852 LOWEST,
1853 &callback2,
1854 pool_.get(),
1855 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161856 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131857 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161858
1859 // Cancel one of the requests. Wait for the other, which will get the first
1860 // job. Release the socket. Run the loop again to make sure the second
1861 // socket is sitting idle and the first one is released (since ReleaseSocket()
1862 // just posts a DoReleaseSocket() task).
1863
[email protected]2431756e2010-09-29 20:26:131864 handle.Reset();
1865 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011866 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131867 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1868 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471869
1870 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1871 // actually become pending until 2ms after they have been created. In order
1872 // to flush all tasks, we need to wait so that we know there are no
1873 // soon-to-be-pending tasks waiting.
1874 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161875 MessageLoop::current()->RunAllPending();
1876
1877 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041878
[email protected]9bf28db2009-08-29 01:35:161879 // Invoke the idle socket cleanup check. Only one socket should be left, the
1880 // used socket. Request it to make sure that it's used.
1881
1882 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531883 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131884 rv = handle.Init("a",
1885 params_,
1886 LOWEST,
1887 &callback,
1888 pool_.get(),
1889 log.bound());
[email protected]9bf28db2009-08-29 01:35:161890 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131891 EXPECT_TRUE(handle.is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151892 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451893 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161894}
1895
[email protected]2041cf342010-02-19 03:15:591896// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161897// because of multiple releasing disconnected sockets.
1898TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1899 CreatePoolWithIdleTimeouts(
1900 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1901 base::TimeDelta(), // Time out unused sockets immediately.
1902 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1903
1904 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1905
1906 // Startup 4 connect jobs. Two of them will be pending.
1907
[email protected]2431756e2010-09-29 20:26:131908 ClientSocketHandle handle;
1909 TestCompletionCallback callback;
1910 int rv = handle.Init("a",
1911 params_,
1912 LOWEST,
1913 &callback,
1914 pool_.get(),
1915 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161916 EXPECT_EQ(OK, rv);
1917
[email protected]2431756e2010-09-29 20:26:131918 ClientSocketHandle handle2;
1919 TestCompletionCallback callback2;
1920 rv = handle2.Init("a",
1921 params_,
1922 LOWEST,
1923 &callback2,
1924 pool_.get(),
1925 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161926 EXPECT_EQ(OK, rv);
1927
[email protected]2431756e2010-09-29 20:26:131928 ClientSocketHandle handle3;
1929 TestCompletionCallback callback3;
1930 rv = handle3.Init("a",
1931 params_,
1932 LOWEST,
1933 &callback3,
1934 pool_.get(),
1935 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161936 EXPECT_EQ(ERR_IO_PENDING, rv);
1937
[email protected]2431756e2010-09-29 20:26:131938 ClientSocketHandle handle4;
1939 TestCompletionCallback callback4;
1940 rv = handle4.Init("a",
1941 params_,
1942 LOWEST,
1943 &callback4,
1944 pool_.get(),
1945 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161946 EXPECT_EQ(ERR_IO_PENDING, rv);
1947
1948 // Release two disconnected sockets.
1949
[email protected]2431756e2010-09-29 20:26:131950 handle.socket()->Disconnect();
1951 handle.Reset();
1952 handle2.socket()->Disconnect();
1953 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161954
[email protected]2431756e2010-09-29 20:26:131955 EXPECT_EQ(OK, callback3.WaitForResult());
1956 EXPECT_FALSE(handle3.is_reused());
1957 EXPECT_EQ(OK, callback4.WaitForResult());
1958 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161959}
1960
[email protected]d7027bb2010-05-10 18:58:541961// Regression test for http://crbug.com/42267.
1962// When DoReleaseSocket() is processed for one socket, it is blocked because the
1963// other stalled groups all have releasing sockets, so no progress can be made.
1964TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1965 CreatePoolWithIdleTimeouts(
1966 4 /* socket limit */, 4 /* socket limit per group */,
1967 base::TimeDelta(), // Time out unused sockets immediately.
1968 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1969
1970 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1971
1972 // Max out the socket limit with 2 per group.
1973
[email protected]2431756e2010-09-29 20:26:131974 ClientSocketHandle handle_a[4];
1975 TestCompletionCallback callback_a[4];
1976 ClientSocketHandle handle_b[4];
1977 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541978
1979 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:131980 EXPECT_EQ(OK, handle_a[i].Init("a",
1981 params_,
1982 LOWEST,
1983 &callback_a[i],
1984 pool_.get(),
1985 BoundNetLog()));
1986 EXPECT_EQ(OK, handle_b[i].Init("b",
1987 params_,
1988 LOWEST,
1989 &callback_b[i],
1990 pool_.get(),
1991 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541992 }
[email protected]b89f7e42010-05-20 20:37:001993
[email protected]d7027bb2010-05-10 18:58:541994 // Make 4 pending requests, 2 per group.
1995
1996 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:131997 EXPECT_EQ(ERR_IO_PENDING,
1998 handle_a[i].Init("a",
1999 params_,
2000 LOWEST,
2001 &callback_a[i],
2002 pool_.get(),
2003 BoundNetLog()));
2004 EXPECT_EQ(ERR_IO_PENDING,
2005 handle_b[i].Init("b",
2006 params_,
2007 LOWEST,
2008 &callback_b[i],
2009 pool_.get(),
2010 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542011 }
2012
2013 // Release b's socket first. The order is important, because in
2014 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2015 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2016 // first, which has a releasing socket, so it refuses to start up another
2017 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132018 handle_b[0].socket()->Disconnect();
2019 handle_b[0].Reset();
2020 handle_a[0].socket()->Disconnect();
2021 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542022
2023 // Used to get stuck here.
2024 MessageLoop::current()->RunAllPending();
2025
[email protected]2431756e2010-09-29 20:26:132026 handle_b[1].socket()->Disconnect();
2027 handle_b[1].Reset();
2028 handle_a[1].socket()->Disconnect();
2029 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542030
2031 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132032 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2033 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542034 }
2035}
2036
[email protected]fd4fe0b2010-02-08 23:02:152037TEST_F(ClientSocketPoolBaseTest,
2038 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2039 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2040
2041 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2042
2043 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2044 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2045 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2046 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2047
[email protected]2431756e2010-09-29 20:26:132048 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2049 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2050 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152051
2052 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132053 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2054 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152055
[email protected]2431756e2010-09-29 20:26:132056 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2057 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2058 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152059
2060 EXPECT_EQ(1, GetOrderOfRequest(1));
2061 EXPECT_EQ(2, GetOrderOfRequest(2));
2062 EXPECT_EQ(3, GetOrderOfRequest(3));
2063 EXPECT_EQ(4, GetOrderOfRequest(4));
2064
2065 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132066 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152067}
2068
[email protected]4f1e4982010-03-02 18:31:042069class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2070 public:
[email protected]2431756e2010-09-29 20:26:132071 TestReleasingSocketRequest(TestClientSocketPool* pool,
2072 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182073 bool reset_releasing_handle)
2074 : pool_(pool),
2075 expected_result_(expected_result),
2076 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042077
2078 ClientSocketHandle* handle() { return &handle_; }
2079
2080 int WaitForResult() {
2081 return callback_.WaitForResult();
2082 }
2083
2084 virtual void RunWithParams(const Tuple1<int>& params) {
2085 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182086 if (reset_releasing_handle_)
2087 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:212088 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:132089 EXPECT_EQ(expected_result_, handle2_.Init("a",
2090 con_params,
2091 kDefaultPriority,
2092 &callback2_,
2093 pool_,
[email protected]e60e47a2010-07-14 03:37:182094 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042095 }
2096
2097 private:
[email protected]2431756e2010-09-29 20:26:132098 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182099 int expected_result_;
2100 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042101 ClientSocketHandle handle_;
2102 ClientSocketHandle handle2_;
2103 TestCompletionCallback callback_;
2104 TestCompletionCallback callback2_;
2105};
2106
[email protected]e60e47a2010-07-14 03:37:182107
2108TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2109 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2110
2111 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2112 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2113 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2114
[email protected]2431756e2010-09-29 20:26:132115 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182116 client_socket_factory_.allocation_count());
2117
2118 connect_job_factory_->set_job_type(
2119 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2120 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132121 EXPECT_EQ(ERR_IO_PENDING,
2122 req.handle()->Init("a",
2123 params_,
2124 kDefaultPriority,
2125 &req,
2126 pool_.get(),
2127 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182128 // The next job should complete synchronously
2129 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2130
2131 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2132 EXPECT_FALSE(req.handle()->is_initialized());
2133 EXPECT_FALSE(req.handle()->socket());
2134 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432135 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182136}
2137
[email protected]b6501d3d2010-06-03 23:53:342138// http://crbug.com/44724 regression test.
2139// We start releasing the pool when we flush on network change. When that
2140// happens, the only active references are in the ClientSocketHandles. When a
2141// ConnectJob completes and calls back into the last ClientSocketHandle, that
2142// callback can release the last reference and delete the pool. After the
2143// callback finishes, we go back to the stack frame within the now-deleted pool.
2144// Executing any code that refers to members of the now-deleted pool can cause
2145// crashes.
2146TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2147 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2148 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2149
2150 ClientSocketHandle handle;
2151 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132152 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2153 params_,
2154 kDefaultPriority,
2155 &callback,
2156 pool_.get(),
2157 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342158
[email protected]2431756e2010-09-29 20:26:132159 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342160
2161 // We'll call back into this now.
2162 callback.WaitForResult();
2163}
2164
[email protected]a7e38572010-06-07 18:22:242165TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2166 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2167 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2168
2169 ClientSocketHandle handle;
2170 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132171 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2172 params_,
2173 kDefaultPriority,
2174 &callback,
2175 pool_.get(),
2176 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242177 EXPECT_EQ(OK, callback.WaitForResult());
2178 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2179
2180 pool_->Flush();
2181
2182 handle.Reset();
2183 MessageLoop::current()->RunAllPending();
2184
[email protected]2431756e2010-09-29 20:26:132185 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2186 params_,
2187 kDefaultPriority,
2188 &callback,
2189 pool_.get(),
2190 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242191 EXPECT_EQ(OK, callback.WaitForResult());
2192 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2193}
2194
[email protected]06f92462010-08-31 19:24:142195class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2196 public:
2197 ConnectWithinCallback(
2198 const std::string& group_name,
2199 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132200 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142201 : group_name_(group_name), params_(params), pool_(pool) {}
2202
2203 ~ConnectWithinCallback() {}
2204
2205 virtual void RunWithParams(const Tuple1<int>& params) {
2206 callback_.RunWithParams(params);
2207 EXPECT_EQ(ERR_IO_PENDING,
2208 handle_.Init(group_name_,
2209 params_,
2210 kDefaultPriority,
2211 &nested_callback_,
2212 pool_,
2213 BoundNetLog()));
2214 }
2215
2216 int WaitForResult() {
2217 return callback_.WaitForResult();
2218 }
2219
2220 int WaitForNestedResult() {
2221 return nested_callback_.WaitForResult();
2222 }
2223
2224 private:
2225 const std::string group_name_;
2226 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132227 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142228 ClientSocketHandle handle_;
2229 TestCompletionCallback callback_;
2230 TestCompletionCallback nested_callback_;
2231};
2232
2233TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2234 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2235
2236 // First job will be waiting until it gets aborted.
2237 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2238
2239 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132240 ConnectWithinCallback callback("a", params_, pool_.get());
2241 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2242 params_,
2243 kDefaultPriority,
2244 &callback,
2245 pool_.get(),
2246 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142247
2248 // Second job will be started during the first callback, and will
2249 // asynchronously complete with OK.
2250 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2251 pool_->Flush();
2252 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2253 EXPECT_EQ(OK, callback.WaitForNestedResult());
2254}
2255
[email protected]25eea382010-07-10 23:55:262256// Cancel a pending socket request while we're at max sockets,
2257// and verify that the backup socket firing doesn't cause a crash.
2258TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2259 // Max 4 sockets globally, max 4 sockets per group.
2260 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222261 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262262
[email protected]4baaf9d2010-08-31 15:15:442263 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2264 // timer.
[email protected]25eea382010-07-10 23:55:262265 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2266 ClientSocketHandle handle;
2267 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132268 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2269 params_,
2270 kDefaultPriority,
2271 &callback,
2272 pool_.get(),
2273 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262274
2275 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2276 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2277 ClientSocketHandle handles[kDefaultMaxSockets];
2278 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2279 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132280 EXPECT_EQ(OK, handles[i].Init("bar",
2281 params_,
2282 kDefaultPriority,
2283 &callback,
2284 pool_.get(),
2285 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262286 }
2287
2288 MessageLoop::current()->RunAllPending();
2289
2290 // Cancel the pending request.
2291 handle.Reset();
2292
2293 // Wait for the backup timer to fire (add some slop to ensure it fires)
2294 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2295
2296 MessageLoop::current()->RunAllPending();
2297 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2298}
2299
[email protected]3f00be82010-09-27 19:50:022300TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442301 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2302 pool_->EnableConnectBackupJobs();
2303
2304 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2305 // timer.
2306 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2307 ClientSocketHandle handle;
2308 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132309 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2310 params_,
2311 kDefaultPriority,
2312 &callback,
2313 pool_.get(),
2314 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442315 ASSERT_TRUE(pool_->HasGroup("bar"));
2316 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2317
2318 // Cancel the socket request. This should cancel the backup timer. Wait for
2319 // the backup time to see if it indeed got canceled.
2320 handle.Reset();
2321 // Wait for the backup timer to fire (add some slop to ensure it fires)
2322 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2323 MessageLoop::current()->RunAllPending();
2324 ASSERT_TRUE(pool_->HasGroup("bar"));
2325 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2326}
2327
[email protected]3f00be82010-09-27 19:50:022328TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2329 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2330 pool_->EnableConnectBackupJobs();
2331
2332 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2333 // timer.
2334 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2335 ClientSocketHandle handle;
2336 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132337 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2338 params_,
2339 kDefaultPriority,
2340 &callback,
2341 pool_.get(),
2342 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022343 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2344 ClientSocketHandle handle2;
2345 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132346 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2347 params_,
2348 kDefaultPriority,
2349 &callback2,
2350 pool_.get(),
2351 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022352 ASSERT_TRUE(pool_->HasGroup("bar"));
2353 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2354
2355 // Cancel request 1 and then complete request 2. With the requests finished,
2356 // the backup timer should be cancelled.
2357 handle.Reset();
2358 EXPECT_EQ(OK, callback2.WaitForResult());
2359 // Wait for the backup timer to fire (add some slop to ensure it fires)
2360 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2361 MessageLoop::current()->RunAllPending();
2362}
2363
[email protected]eb5a99382010-07-11 03:18:262364// Test delayed socket binding for the case where we have two connects,
2365// and while one is waiting on a connect, the other frees up.
2366// The socket waiting on a connect should switch immediately to the freed
2367// up socket.
2368TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2370 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2371
2372 ClientSocketHandle handle1;
2373 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132374 EXPECT_EQ(ERR_IO_PENDING,
2375 handle1.Init("a",
2376 params_,
2377 kDefaultPriority,
2378 &callback,
2379 pool_.get(),
2380 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262381 EXPECT_EQ(OK, callback.WaitForResult());
2382
2383 // No idle sockets, no pending jobs.
2384 EXPECT_EQ(0, pool_->IdleSocketCount());
2385 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2386
2387 // Create a second socket to the same host, but this one will wait.
2388 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2389 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132390 EXPECT_EQ(ERR_IO_PENDING,
2391 handle2.Init("a",
2392 params_,
2393 kDefaultPriority,
2394 &callback,
2395 pool_.get(),
2396 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262397 // No idle sockets, and one connecting job.
2398 EXPECT_EQ(0, pool_->IdleSocketCount());
2399 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2400
2401 // Return the first handle to the pool. This will initiate the delayed
2402 // binding.
2403 handle1.Reset();
2404
2405 MessageLoop::current()->RunAllPending();
2406
2407 // Still no idle sockets, still one pending connect job.
2408 EXPECT_EQ(0, pool_->IdleSocketCount());
2409 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2410
2411 // The second socket connected, even though it was a Waiting Job.
2412 EXPECT_EQ(OK, callback.WaitForResult());
2413
2414 // And we can see there is still one job waiting.
2415 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2416
2417 // Finally, signal the waiting Connect.
2418 client_socket_factory_.SignalJobs();
2419 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2420
2421 MessageLoop::current()->RunAllPending();
2422}
2423
2424// Test delayed socket binding when a group is at capacity and one
2425// of the group's sockets frees up.
2426TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2427 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2428 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2429
2430 ClientSocketHandle handle1;
2431 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132432 EXPECT_EQ(ERR_IO_PENDING,
2433 handle1.Init("a",
2434 params_,
2435 kDefaultPriority,
2436 &callback,
2437 pool_.get(),
2438 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262439 EXPECT_EQ(OK, callback.WaitForResult());
2440
2441 // No idle sockets, no pending jobs.
2442 EXPECT_EQ(0, pool_->IdleSocketCount());
2443 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2444
2445 // Create a second socket to the same host, but this one will wait.
2446 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2447 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132448 EXPECT_EQ(ERR_IO_PENDING,
2449 handle2.Init("a",
2450 params_,
2451 kDefaultPriority,
2452 &callback,
2453 pool_.get(),
2454 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262455 // No idle sockets, and one connecting job.
2456 EXPECT_EQ(0, pool_->IdleSocketCount());
2457 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2458
2459 // Return the first handle to the pool. This will initiate the delayed
2460 // binding.
2461 handle1.Reset();
2462
2463 MessageLoop::current()->RunAllPending();
2464
2465 // Still no idle sockets, still one pending connect job.
2466 EXPECT_EQ(0, pool_->IdleSocketCount());
2467 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2468
2469 // The second socket connected, even though it was a Waiting Job.
2470 EXPECT_EQ(OK, callback.WaitForResult());
2471
2472 // And we can see there is still one job waiting.
2473 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2474
2475 // Finally, signal the waiting Connect.
2476 client_socket_factory_.SignalJobs();
2477 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2478
2479 MessageLoop::current()->RunAllPending();
2480}
2481
2482// Test out the case where we have one socket connected, one
2483// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512484// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262485// should complete, by taking the first socket's idle socket.
2486TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2487 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2488 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2489
2490 ClientSocketHandle handle1;
2491 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132492 EXPECT_EQ(ERR_IO_PENDING,
2493 handle1.Init("a",
2494 params_,
2495 kDefaultPriority,
2496 &callback,
2497 pool_.get(),
2498 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262499 EXPECT_EQ(OK, callback.WaitForResult());
2500
2501 // No idle sockets, no pending jobs.
2502 EXPECT_EQ(0, pool_->IdleSocketCount());
2503 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2504
2505 // Create a second socket to the same host, but this one will wait.
2506 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2507 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132508 EXPECT_EQ(ERR_IO_PENDING,
2509 handle2.Init("a",
2510 params_,
2511 kDefaultPriority,
2512 &callback,
2513 pool_.get(),
2514 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262515 // No idle sockets, and one connecting job.
2516 EXPECT_EQ(0, pool_->IdleSocketCount());
2517 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2518
2519 // Return the first handle to the pool. This will initiate the delayed
2520 // binding.
2521 handle1.Reset();
2522
2523 MessageLoop::current()->RunAllPending();
2524
2525 // Still no idle sockets, still one pending connect job.
2526 EXPECT_EQ(0, pool_->IdleSocketCount());
2527 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2528
2529 // The second socket connected, even though it was a Waiting Job.
2530 EXPECT_EQ(OK, callback.WaitForResult());
2531
2532 // And we can see there is still one job waiting.
2533 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2534
2535 // Finally, signal the waiting Connect.
2536 client_socket_factory_.SignalJobs();
2537 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2538
2539 MessageLoop::current()->RunAllPending();
2540}
2541
[email protected]2abfe90a2010-08-25 17:49:512542// Cover the case where on an available socket slot, we have one pending
2543// request that completes synchronously, thereby making the Group empty.
2544TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2545 const int kUnlimitedSockets = 100;
2546 const int kOneSocketPerGroup = 1;
2547 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2548
2549 // Make the first request asynchronous fail.
2550 // This will free up a socket slot later.
2551 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2552
2553 ClientSocketHandle handle1;
2554 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132555 EXPECT_EQ(ERR_IO_PENDING,
2556 handle1.Init("a",
2557 params_,
2558 kDefaultPriority,
2559 &callback1,
2560 pool_.get(),
2561 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512562 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2563
2564 // Make the second request synchronously fail. This should make the Group
2565 // empty.
2566 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2567 ClientSocketHandle handle2;
2568 TestCompletionCallback callback2;
2569 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2570 // when created.
[email protected]2431756e2010-09-29 20:26:132571 EXPECT_EQ(ERR_IO_PENDING,
2572 handle2.Init("a",
2573 params_,
2574 kDefaultPriority,
2575 &callback2,
2576 pool_.get(),
2577 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512578
2579 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2580
2581 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2582 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2583 EXPECT_FALSE(pool_->HasGroup("a"));
2584}
2585
[email protected]e1b54dc2010-10-06 21:27:222586TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2587 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2588
2589 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2590
2591 ClientSocketHandle handle1;
2592 TestCompletionCallback callback1;
2593 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2594 params_,
2595 kDefaultPriority,
2596 &callback1,
2597 pool_.get(),
2598 BoundNetLog()));
2599
2600 ClientSocketHandle handle2;
2601 TestCompletionCallback callback2;
2602 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2603 params_,
2604 kDefaultPriority,
2605 &callback2,
2606 pool_.get(),
2607 BoundNetLog()));
2608 ClientSocketHandle handle3;
2609 TestCompletionCallback callback3;
2610 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2611 params_,
2612 kDefaultPriority,
2613 &callback3,
2614 pool_.get(),
2615 BoundNetLog()));
2616
2617 EXPECT_EQ(OK, callback1.WaitForResult());
2618 EXPECT_EQ(OK, callback2.WaitForResult());
2619 EXPECT_EQ(OK, callback3.WaitForResult());
2620
2621 // Use the socket.
2622 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2623 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2624
2625 handle1.Reset();
2626 handle2.Reset();
2627 handle3.Reset();
2628
2629 EXPECT_EQ(OK, handle1.Init("a",
2630 params_,
2631 kDefaultPriority,
2632 &callback1,
2633 pool_.get(),
2634 BoundNetLog()));
2635 EXPECT_EQ(OK, handle2.Init("a",
2636 params_,
2637 kDefaultPriority,
2638 &callback2,
2639 pool_.get(),
2640 BoundNetLog()));
2641 EXPECT_EQ(OK, handle3.Init("a",
2642 params_,
2643 kDefaultPriority,
2644 &callback3,
2645 pool_.get(),
2646 BoundNetLog()));
2647
2648 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2649 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2650 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2651}
2652
[email protected]2c2bef152010-10-13 00:55:032653TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2654 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2655 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2656
2657 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2658
2659 ASSERT_TRUE(pool_->HasGroup("a"));
2660 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2661 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2662
2663 ClientSocketHandle handle1;
2664 TestCompletionCallback callback1;
2665 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2666 params_,
2667 kDefaultPriority,
2668 &callback1,
2669 pool_.get(),
2670 BoundNetLog()));
2671
2672 ClientSocketHandle handle2;
2673 TestCompletionCallback callback2;
2674 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2675 params_,
2676 kDefaultPriority,
2677 &callback2,
2678 pool_.get(),
2679 BoundNetLog()));
2680
2681 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2682 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2683
2684 EXPECT_EQ(OK, callback1.WaitForResult());
2685 EXPECT_EQ(OK, callback2.WaitForResult());
2686 handle1.Reset();
2687 handle2.Reset();
2688
2689 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2690 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2691}
2692
2693TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2694 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2695 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2696
2697 ClientSocketHandle handle1;
2698 TestCompletionCallback callback1;
2699 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2700 params_,
2701 kDefaultPriority,
2702 &callback1,
2703 pool_.get(),
2704 BoundNetLog()));
2705
2706 ASSERT_TRUE(pool_->HasGroup("a"));
2707 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2708 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2709
2710 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2711
2712 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2713 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2714
2715 ClientSocketHandle handle2;
2716 TestCompletionCallback callback2;
2717 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2718 params_,
2719 kDefaultPriority,
2720 &callback2,
2721 pool_.get(),
2722 BoundNetLog()));
2723
2724 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2725 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2726
2727 EXPECT_EQ(OK, callback1.WaitForResult());
2728 EXPECT_EQ(OK, callback2.WaitForResult());
2729 handle1.Reset();
2730 handle2.Reset();
2731
2732 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2733 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2734}
2735
2736TEST_F(ClientSocketPoolBaseTest,
2737 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2738 CreatePool(4, 4);
2739 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2740
2741 ClientSocketHandle handle1;
2742 TestCompletionCallback callback1;
2743 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2744 params_,
2745 kDefaultPriority,
2746 &callback1,
2747 pool_.get(),
2748 BoundNetLog()));
2749
2750 ClientSocketHandle handle2;
2751 TestCompletionCallback callback2;
2752 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2753 params_,
2754 kDefaultPriority,
2755 &callback2,
2756 pool_.get(),
2757 BoundNetLog()));
2758
2759 ClientSocketHandle handle3;
2760 TestCompletionCallback callback3;
2761 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2762 params_,
2763 kDefaultPriority,
2764 &callback3,
2765 pool_.get(),
2766 BoundNetLog()));
2767
2768 ASSERT_TRUE(pool_->HasGroup("a"));
2769 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2770 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2771
2772 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2773
2774 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2775 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2776
2777 EXPECT_EQ(OK, callback1.WaitForResult());
2778 EXPECT_EQ(OK, callback2.WaitForResult());
2779 EXPECT_EQ(OK, callback3.WaitForResult());
2780 handle1.Reset();
2781 handle2.Reset();
2782 handle3.Reset();
2783
2784 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2785 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2786}
2787
2788TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2789 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2790 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2791
2792 ASSERT_FALSE(pool_->HasGroup("a"));
2793
2794 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2795 BoundNetLog());
2796
2797 ASSERT_TRUE(pool_->HasGroup("a"));
2798 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2799
2800 ASSERT_FALSE(pool_->HasGroup("b"));
2801
2802 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2803 BoundNetLog());
2804
2805 ASSERT_FALSE(pool_->HasGroup("b"));
2806}
2807
2808TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2809 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2810 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2811
2812 ASSERT_FALSE(pool_->HasGroup("a"));
2813
2814 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2815 BoundNetLog());
2816
2817 ASSERT_TRUE(pool_->HasGroup("a"));
2818 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2819
2820 ASSERT_FALSE(pool_->HasGroup("b"));
2821
2822 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2823 BoundNetLog());
2824
2825 ASSERT_TRUE(pool_->HasGroup("b"));
2826 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2827}
2828
2829TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2830 CreatePool(4, 4);
2831 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2832
2833 ClientSocketHandle handle1;
2834 TestCompletionCallback callback1;
2835 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2836 params_,
2837 kDefaultPriority,
2838 &callback1,
2839 pool_.get(),
2840 BoundNetLog()));
2841 ASSERT_EQ(OK, callback1.WaitForResult());
2842 handle1.Reset();
2843
2844 ASSERT_TRUE(pool_->HasGroup("a"));
2845 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2846 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2847
2848 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2849
2850 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2851 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2852}
2853
2854TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2855 CreatePool(4, 4);
2856 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2857
2858 ClientSocketHandle handle1;
2859 TestCompletionCallback callback1;
2860 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2861 params_,
2862 kDefaultPriority,
2863 &callback1,
2864 pool_.get(),
2865 BoundNetLog()));
2866 ASSERT_EQ(OK, callback1.WaitForResult());
2867
2868 ASSERT_TRUE(pool_->HasGroup("a"));
2869 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2870 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2871 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2872
2873 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2874
2875 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2876 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2877 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2878}
2879
2880TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2881 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2882 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2883
2884 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2885 BoundNetLog());
2886
2887 ASSERT_TRUE(pool_->HasGroup("a"));
2888 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2889 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2890
2891 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2892 BoundNetLog());
2893
2894 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2895 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2896}
2897
2898TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2899 CreatePool(4, 4);
2900 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2901
2902 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2903
2904 ASSERT_TRUE(pool_->HasGroup("a"));
2905 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2906 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2907
2908 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2909 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2910 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2911
2912 ClientSocketHandle handle1;
2913 TestCompletionCallback callback1;
2914 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2915 params_,
2916 kDefaultPriority,
2917 &callback1,
2918 pool_.get(),
2919 BoundNetLog()));
2920 ASSERT_EQ(OK, callback1.WaitForResult());
2921
2922 ClientSocketHandle handle2;
2923 TestCompletionCallback callback2;
2924 int rv = handle2.Init("a",
2925 params_,
2926 kDefaultPriority,
2927 &callback2,
2928 pool_.get(),
2929 BoundNetLog());
2930 if (rv != OK) {
2931 EXPECT_EQ(ERR_IO_PENDING, rv);
2932 EXPECT_EQ(OK, callback2.WaitForResult());
2933 }
2934
2935 handle1.Reset();
2936 handle2.Reset();
2937
2938 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2939
2940 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2941 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2942 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2943}
2944
2945TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2946 CreatePool(4, 4);
2947 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2948
2949 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2950
2951 ASSERT_TRUE(pool_->HasGroup("a"));
2952 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2953 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2954
2955 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2956 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2957 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2958
2959 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2960 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2961 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2962
2963 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2964 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2965 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2966}
2967
2968TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
2969 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2970 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2971
2972 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2973
2974 ASSERT_TRUE(pool_->HasGroup("a"));
2975 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2976 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2977
2978 ClientSocketHandle handle1;
2979 TestCompletionCallback callback1;
2980 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2981 params_,
2982 kDefaultPriority,
2983 &callback1,
2984 pool_.get(),
2985 BoundNetLog()));
2986
2987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2988 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2989
2990 ASSERT_EQ(OK, callback1.WaitForResult());
2991
2992 handle1.Reset();
2993
2994 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2995}
2996
[email protected]f6d1d6eb2009-06-24 20:16:092997} // namespace
2998
2999} // namespace net