blob: 70cc604abb26570d26690fd3bec20989223fb44c [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]43a21b82010-06-10 21:30:5413#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5314#include "net/base/net_log.h"
15#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3117#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0918#include "net/base/test_completion_callback.h"
19#include "net/socket/client_socket.h"
20#include "net/socket/client_socket_factory.h"
21#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0022#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1723#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0924#include "testing/gtest/include/gtest/gtest.h"
25
26namespace net {
27
28namespace {
29
[email protected]211d21722009-07-22 15:48:5330const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2031const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5232const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0133
[email protected]df4b4ef2010-07-12 18:25:2134class TestSocketParams : public base::RefCounted<TestSocketParams> {
35 private:
36 friend class base::RefCounted<TestSocketParams>;
37 ~TestSocketParams() {}
38};
[email protected]7fc5b09a2010-02-27 00:07:3839typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4940
[email protected]f6d1d6eb2009-06-24 20:16:0941class MockClientSocket : public ClientSocket {
42 public:
43 MockClientSocket() : connected_(false) {}
44
[email protected]ab838892009-06-30 18:49:0545 // Socket methods:
46 virtual int Read(
47 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
48 return ERR_UNEXPECTED;
49 }
50
51 virtual int Write(
52 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53 return ERR_UNEXPECTED;
54 }
[email protected]06650c52010-06-03 00:49:1755 virtual bool SetReceiveBufferSize(int32 size) { return true; }
56 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0557
[email protected]f6d1d6eb2009-06-24 20:16:0958 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0559
[email protected]a2006ece2010-04-23 16:44:0260 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0961 connected_ = true;
62 return OK;
63 }
[email protected]f6d1d6eb2009-06-24 20:16:0964
[email protected]ab838892009-06-30 18:49:0565 virtual void Disconnect() { connected_ = false; }
66 virtual bool IsConnected() const { return connected_; }
67 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0168
[email protected]ac9eec62010-02-20 18:50:3869 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1670 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0971 }
[email protected]f6d1d6eb2009-06-24 20:16:0972
[email protected]a2006ece2010-04-23 16:44:0273 virtual const BoundNetLog& NetLog() const {
74 return net_log_;
75 }
76
[email protected]f6d1d6eb2009-06-24 20:16:0977 private:
78 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0279 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0980
[email protected]ab838892009-06-30 18:49:0581 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0982};
83
[email protected]5fc08e32009-07-15 17:09:5784class TestConnectJob;
85
[email protected]f6d1d6eb2009-06-24 20:16:0986class MockClientSocketFactory : public ClientSocketFactory {
87 public:
[email protected]ab838892009-06-30 18:49:0588 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0989
[email protected]a2006ece2010-04-23 16:44:0290 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
91 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0992 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0593 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0994 }
95
96 virtual SSLClientSocket* CreateSSLClientSocket(
97 ClientSocket* transport_socket,
98 const std::string& hostname,
99 const SSLConfig& ssl_config) {
100 NOTIMPLEMENTED();
101 return NULL;
102 }
103
[email protected]5fc08e32009-07-15 17:09:57104 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
105 void SignalJobs();
106
[email protected]f6d1d6eb2009-06-24 20:16:09107 int allocation_count() const { return allocation_count_; }
108
[email protected]f6d1d6eb2009-06-24 20:16:09109 private:
110 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57111 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09112};
113
[email protected]ab838892009-06-30 18:49:05114class TestConnectJob : public ConnectJob {
115 public:
116 enum JobType {
117 kMockJob,
118 kMockFailingJob,
119 kMockPendingJob,
120 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57121 kMockWaitingJob,
122 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13123 kMockRecoverableJob,
124 kMockPendingRecoverableJob,
[email protected]ab838892009-06-30 18:49:05125 };
126
[email protected]994d4932010-07-12 17:55:13127 // The kMockPendingJob uses a slight delay before allowing the connect
128 // to complete.
129 static const int kPendingConnectDelay = 2;
130
[email protected]ab838892009-06-30 18:49:05131 TestConnectJob(JobType job_type,
132 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49133 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34134 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05135 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30136 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17137 NetLog* net_log)
138 : ConnectJob(group_name, timeout_duration, delegate,
139 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58140 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05141 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21142 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
143 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05144
[email protected]974ebd62009-08-03 23:14:34145 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13146 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34147 }
148
[email protected]46451352009-09-01 14:54:21149 virtual LoadState GetLoadState() const { return load_state_; }
150
[email protected]974ebd62009-08-03 23:14:34151 private:
[email protected]ab838892009-06-30 18:49:05152 // ConnectJob methods:
153
[email protected]974ebd62009-08-03 23:14:34154 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05155 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02156 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40157 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05158 switch (job_type_) {
159 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13160 return DoConnect(true /* successful */, false /* sync */,
161 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05162 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13163 return DoConnect(false /* error */, false /* sync */,
164 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05165 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57166 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47167
168 // Depending on execution timings, posting a delayed task can result
169 // in the task getting executed the at the earliest possible
170 // opportunity or only after returning once from the message loop and
171 // then a second call into the message loop. In order to make behavior
172 // more deterministic, we change the default delay to 2ms. This should
173 // always require us to wait for the second call into the message loop.
174 //
175 // N.B. The correct fix for this and similar timing problems is to
176 // abstract time for the purpose of unittests. Unfortunately, we have
177 // a lot of third-party components that directly call the various
178 // time functions, so this change would be rather invasive.
179 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05180 FROM_HERE,
181 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47182 &TestConnectJob::DoConnect,
183 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13184 true /* async */,
185 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13186 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05187 return ERR_IO_PENDING;
188 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57189 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47190 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05191 FROM_HERE,
192 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47193 &TestConnectJob::DoConnect,
194 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13195 true /* async */,
196 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47197 2);
[email protected]ab838892009-06-30 18:49:05198 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57199 case kMockWaitingJob:
200 client_socket_factory_->WaitForSignal(this);
201 waiting_success_ = true;
202 return ERR_IO_PENDING;
203 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46204 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57205 FROM_HERE,
206 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46207 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57208 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13209 case kMockRecoverableJob:
210 return DoConnect(false /* error */, false /* sync */,
211 true /* recoverable */);
212 case kMockPendingRecoverableJob:
213 set_load_state(LOAD_STATE_CONNECTING);
214 MessageLoop::current()->PostDelayedTask(
215 FROM_HERE,
216 method_factory_.NewRunnableMethod(
217 &TestConnectJob::DoConnect,
218 false /* error */,
219 true /* async */,
220 true /* recoverable */),
221 2);
222 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05223 default:
224 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40225 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05226 return ERR_FAILED;
227 }
228 }
229
[email protected]46451352009-09-01 14:54:21230 void set_load_state(LoadState load_state) { load_state_ = load_state; }
231
[email protected]e772db3f2010-07-12 18:11:13232 int DoConnect(bool succeed, bool was_async, bool recoverable) {
233 int result = OK;
[email protected]ab838892009-06-30 18:49:05234 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02235 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13236 } else if (recoverable) {
237 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40238 } else {
[email protected]e772db3f2010-07-12 18:11:13239 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40240 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05241 }
[email protected]2ab05b52009-07-01 23:57:58242
243 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30244 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05245 return result;
246 }
247
[email protected]cfa8228c2010-06-17 01:07:56248 // This function helps simulate the progress of load states on a ConnectJob.
249 // Each time it is called it advances the load state and posts a task to be
250 // called again. It stops at the last connecting load state (the one
251 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57252 void AdvanceLoadState(LoadState state) {
253 int tmp = state;
254 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56255 if (tmp < LOAD_STATE_SENDING_REQUEST) {
256 state = static_cast<LoadState>(tmp);
257 set_load_state(state);
258 MessageLoop::current()->PostTask(
259 FROM_HERE,
260 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
261 state));
262 }
[email protected]5fc08e32009-07-15 17:09:57263 }
264
265 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05266 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57267 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05268 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21269 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05270
271 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
272};
273
[email protected]d80a4322009-08-14 07:07:49274class TestConnectJobFactory
275 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05276 public:
[email protected]5fc08e32009-07-15 17:09:57277 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05278 : job_type_(TestConnectJob::kMockJob),
279 client_socket_factory_(client_socket_factory) {}
280
281 virtual ~TestConnectJobFactory() {}
282
283 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
284
[email protected]974ebd62009-08-03 23:14:34285 void set_timeout_duration(base::TimeDelta timeout_duration) {
286 timeout_duration_ = timeout_duration;
287 }
288
[email protected]ab838892009-06-30 18:49:05289 // ConnectJobFactory methods:
290
291 virtual ConnectJob* NewConnectJob(
292 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49293 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17294 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05295 return new TestConnectJob(job_type_,
296 group_name,
297 request,
[email protected]974ebd62009-08-03 23:14:34298 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05299 delegate,
[email protected]fd7b7c92009-08-20 19:38:30300 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17301 NULL);
[email protected]ab838892009-06-30 18:49:05302 }
303
[email protected]a796bcec2010-03-22 17:17:26304 virtual base::TimeDelta ConnectionTimeout() const {
305 return timeout_duration_;
306 }
307
[email protected]ab838892009-06-30 18:49:05308 private:
309 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34310 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57311 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05312
313 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
314};
315
316class TestClientSocketPool : public ClientSocketPool {
317 public:
318 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53319 int max_sockets,
[email protected]ab838892009-06-30 18:49:05320 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00321 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16322 base::TimeDelta unused_idle_socket_timeout,
323 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49324 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00325 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16326 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38327 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05328
329 virtual int RequestSocket(
330 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49331 const void* params,
[email protected]ac790b42009-12-02 04:31:31332 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05333 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46334 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53335 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21336 const scoped_refptr<TestSocketParams>* casted_socket_params =
337 static_cast<const scoped_refptr<TestSocketParams>*>(params);
338 return base_.RequestSocket(group_name, *casted_socket_params, priority,
339 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05340 }
341
342 virtual void CancelRequest(
343 const std::string& group_name,
344 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49345 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05346 }
347
348 virtual void ReleaseSocket(
349 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24350 ClientSocket* socket,
351 int id) {
352 base_.ReleaseSocket(group_name, socket, id);
353 }
354
355 virtual void Flush() {
356 base_.Flush();
[email protected]ab838892009-06-30 18:49:05357 }
358
359 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49360 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05361 }
362
[email protected]d80a4322009-08-14 07:07:49363 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05364
365 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49366 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05367 }
368
369 virtual LoadState GetLoadState(const std::string& group_name,
370 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49371 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05372 }
373
[email protected]a796bcec2010-03-22 17:17:26374 virtual base::TimeDelta ConnectionTimeout() const {
375 return base_.ConnectionTimeout();
376 }
377
[email protected]b89f7e42010-05-20 20:37:00378 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
379 return base_.histograms();
380 }
[email protected]a796bcec2010-03-22 17:17:26381
[email protected]d80a4322009-08-14 07:07:49382 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20383
[email protected]974ebd62009-08-03 23:14:34384 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49385 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34386 }
387
[email protected]9bf28db2009-08-29 01:35:16388 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
389
[email protected]43a21b82010-06-10 21:30:54390 void EnableBackupJobs() { base_.EnableBackupJobs(); }
391
[email protected]ab838892009-06-30 18:49:05392 private:
[email protected]5389bc72009-11-05 23:34:24393 ~TestClientSocketPool() {}
394
[email protected]d80a4322009-08-14 07:07:49395 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05396
397 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
398};
399
[email protected]a937a06d2009-08-19 21:19:24400} // namespace
401
[email protected]7fc5b09a2010-02-27 00:07:38402REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24403
404namespace {
405
[email protected]5fc08e32009-07-15 17:09:57406void MockClientSocketFactory::SignalJobs() {
407 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
408 it != waiting_jobs_.end(); ++it) {
409 (*it)->Signal();
410 }
411 waiting_jobs_.clear();
412}
413
[email protected]974ebd62009-08-03 23:14:34414class TestConnectJobDelegate : public ConnectJob::Delegate {
415 public:
416 TestConnectJobDelegate()
417 : have_result_(false), waiting_for_result_(false), result_(OK) {}
418 virtual ~TestConnectJobDelegate() {}
419
420 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
421 result_ = result;
[email protected]6e713f02009-08-06 02:56:40422 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07423 // socket.get() should be NULL iff result != OK
424 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34425 delete job;
426 have_result_ = true;
427 if (waiting_for_result_)
428 MessageLoop::current()->Quit();
429 }
430
431 int WaitForResult() {
432 DCHECK(!waiting_for_result_);
433 while (!have_result_) {
434 waiting_for_result_ = true;
435 MessageLoop::current()->Run();
436 waiting_for_result_ = false;
437 }
438 have_result_ = false; // auto-reset for next callback
439 return result_;
440 }
441
442 private:
443 bool have_result_;
444 bool waiting_for_result_;
445 int result_;
446};
447
[email protected]75439d3b2009-07-23 22:11:17448class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09449 protected:
[email protected]b89f7e42010-05-20 20:37:00450 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21451 : params_(new TestSocketParams()),
452 histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20453
[email protected]211d21722009-07-22 15:48:53454 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16455 CreatePoolWithIdleTimeouts(
456 max_sockets,
457 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00458 base::TimeDelta::FromSeconds(
459 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16460 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
461 }
462
463 void CreatePoolWithIdleTimeouts(
464 int max_sockets, int max_sockets_per_group,
465 base::TimeDelta unused_idle_socket_timeout,
466 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20467 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04468 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53469 pool_ = new TestClientSocketPool(max_sockets,
470 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00471 histograms_,
[email protected]9bf28db2009-08-29 01:35:16472 unused_idle_socket_timeout,
473 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20474 connect_job_factory_);
475 }
[email protected]f6d1d6eb2009-06-24 20:16:09476
[email protected]ac790b42009-12-02 04:31:31477 int StartRequest(const std::string& group_name,
478 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38479 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]df4b4ef2010-07-12 18:25:21480 pool_, group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09481 }
482
483 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47484 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
485 // actually become pending until 2ms after they have been created. In order
486 // to flush all tasks, we need to wait so that we know there are no
487 // soon-to-be-pending tasks waiting.
488 PlatformThread::Sleep(10);
489 MessageLoop::current()->RunAllPending();
490
[email protected]211d21722009-07-22 15:48:53491 // Need to delete |pool_| before we turn late binding back off. We also need
492 // to delete |requests_| because the pool is reference counted and requests
493 // keep reference to it.
494 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57495 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53496 requests_.reset();
497
[email protected]75439d3b2009-07-23 22:11:17498 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09499 }
500
[email protected]f6d1d6eb2009-06-24 20:16:09501 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04502 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21503 scoped_refptr<TestSocketParams> params_;
[email protected]c9d6a1d2009-07-14 16:15:20504 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00505 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09506};
507
[email protected]974ebd62009-08-03 23:14:34508// Even though a timeout is specified, it doesn't time out on a synchronous
509// completion.
510TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
511 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06512 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49513 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21514 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34515 scoped_ptr<TestConnectJob> job(
516 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12517 "a",
[email protected]974ebd62009-08-03 23:14:34518 request,
519 base::TimeDelta::FromMicroseconds(1),
520 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30521 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17522 NULL));
[email protected]974ebd62009-08-03 23:14:34523 EXPECT_EQ(OK, job->Connect());
524}
525
526TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
527 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06528 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17529 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53530
[email protected]d80a4322009-08-14 07:07:49531 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21532 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34533 // Deleted by TestConnectJobDelegate.
534 TestConnectJob* job =
535 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12536 "a",
[email protected]974ebd62009-08-03 23:14:34537 request,
538 base::TimeDelta::FromMicroseconds(1),
539 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30540 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17541 &log);
[email protected]974ebd62009-08-03 23:14:34542 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
543 PlatformThread::Sleep(1);
544 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30545
[email protected]06650c52010-06-03 00:49:17546 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46547 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53548 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17549 EXPECT_TRUE(LogContainsBeginEvent(
550 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46551 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17552 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
553 NetLog::PHASE_NONE));
554 EXPECT_TRUE(LogContainsEvent(
555 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53556 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46557 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17558 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
559 EXPECT_TRUE(LogContainsEndEvent(
560 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34561}
562
[email protected]5fc08e32009-07-15 17:09:57563TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53564 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20565
[email protected]f6d1d6eb2009-06-24 20:16:09566 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06567 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53568 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
569
[email protected]df4b4ef2010-07-12 18:25:21570 EXPECT_EQ(OK, handle.Init("a", params_, kDefaultPriority, &callback, pool_,
571 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09572 EXPECT_TRUE(handle.is_initialized());
573 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09574 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30575
[email protected]06650c52010-06-03 00:49:17576 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46577 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53578 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53579 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17580 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
581 NetLog::PHASE_NONE));
582 EXPECT_TRUE(LogContainsEvent(
583 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53584 NetLog::PHASE_NONE));
585 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17586 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09587}
588
[email protected]ab838892009-06-30 18:49:05589TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53590 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20591
[email protected]ab838892009-06-30 18:49:05592 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53593 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
594
[email protected]a512f5982009-08-18 16:01:06595 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:21596 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
597 kDefaultPriority, &req,
598 pool_, log.bound()));
[email protected]e772db3f2010-07-12 18:11:13599 EXPECT_FALSE(req.handle()->socket());
[email protected]fd7b7c92009-08-20 19:38:30600
[email protected]06650c52010-06-03 00:49:17601 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27602 EXPECT_TRUE(LogContainsBeginEvent(
603 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17604 EXPECT_TRUE(LogContainsEvent(
605 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
606 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02607 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17608 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09609}
610
[email protected]211d21722009-07-22 15:48:53611TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
612 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
613
[email protected]9e743cd2010-03-16 07:03:53614 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30615
[email protected]211d21722009-07-22 15:48:53616 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
617 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
618 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
619 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
620
621 EXPECT_EQ(static_cast<int>(requests_.size()),
622 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17623 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53624
625 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
626 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
627 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
628
[email protected]43a21b82010-06-10 21:30:54629 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53630
631 EXPECT_EQ(static_cast<int>(requests_.size()),
632 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17633 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53634
635 EXPECT_EQ(1, GetOrderOfRequest(1));
636 EXPECT_EQ(2, GetOrderOfRequest(2));
637 EXPECT_EQ(3, GetOrderOfRequest(3));
638 EXPECT_EQ(4, GetOrderOfRequest(4));
639 EXPECT_EQ(5, GetOrderOfRequest(5));
640 EXPECT_EQ(6, GetOrderOfRequest(6));
641 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17642
643 // Make sure we test order of all requests made.
644 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53645}
646
647TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
648 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
649
[email protected]9e743cd2010-03-16 07:03:53650 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30651
[email protected]211d21722009-07-22 15:48:53652 // Reach all limits: max total sockets, and max sockets per group.
653 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
654 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
655 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
656 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
657
658 EXPECT_EQ(static_cast<int>(requests_.size()),
659 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17660 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53661
662 // Now create a new group and verify that we don't starve it.
663 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
664
[email protected]43a21b82010-06-10 21:30:54665 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53666
667 EXPECT_EQ(static_cast<int>(requests_.size()),
668 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17669 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53670
671 EXPECT_EQ(1, GetOrderOfRequest(1));
672 EXPECT_EQ(2, GetOrderOfRequest(2));
673 EXPECT_EQ(3, GetOrderOfRequest(3));
674 EXPECT_EQ(4, GetOrderOfRequest(4));
675 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17676
677 // Make sure we test order of all requests made.
678 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53679}
680
681TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
682 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
683
[email protected]ac790b42009-12-02 04:31:31684 EXPECT_EQ(OK, StartRequest("b", LOWEST));
685 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
686 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
687 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53688
689 EXPECT_EQ(static_cast<int>(requests_.size()),
690 client_socket_factory_.allocation_count());
691
[email protected]ac790b42009-12-02 04:31:31692 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
693 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
694 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53695
[email protected]43a21b82010-06-10 21:30:54696 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53697
[email protected]75439d3b2009-07-23 22:11:17698 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53699
700 // First 4 requests don't have to wait, and finish in order.
701 EXPECT_EQ(1, GetOrderOfRequest(1));
702 EXPECT_EQ(2, GetOrderOfRequest(2));
703 EXPECT_EQ(3, GetOrderOfRequest(3));
704 EXPECT_EQ(4, GetOrderOfRequest(4));
705
[email protected]ac790b42009-12-02 04:31:31706 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
707 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53708 EXPECT_EQ(7, GetOrderOfRequest(5));
709 EXPECT_EQ(6, GetOrderOfRequest(6));
710 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17711
712 // Make sure we test order of all requests made.
713 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53714}
715
716TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
718
[email protected]ac790b42009-12-02 04:31:31719 EXPECT_EQ(OK, StartRequest("a", LOWEST));
720 EXPECT_EQ(OK, StartRequest("a", LOW));
721 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
722 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53723
724 EXPECT_EQ(static_cast<int>(requests_.size()),
725 client_socket_factory_.allocation_count());
726
[email protected]ac790b42009-12-02 04:31:31727 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
728 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
729 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53730
[email protected]43a21b82010-06-10 21:30:54731 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53732
[email protected]43a21b82010-06-10 21:30:54733 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53734 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17735 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53736
737 // First 4 requests don't have to wait, and finish in order.
738 EXPECT_EQ(1, GetOrderOfRequest(1));
739 EXPECT_EQ(2, GetOrderOfRequest(2));
740 EXPECT_EQ(3, GetOrderOfRequest(3));
741 EXPECT_EQ(4, GetOrderOfRequest(4));
742
743 // Request ("b", 7) has the highest priority, but we can't make new socket for
744 // group "b", because it has reached the per-group limit. Then we make
745 // socket for ("c", 6), because it has higher priority than ("a", 4),
746 // and we still can't make a socket for group "b".
747 EXPECT_EQ(5, GetOrderOfRequest(5));
748 EXPECT_EQ(6, GetOrderOfRequest(6));
749 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17750
751 // Make sure we test order of all requests made.
752 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53753}
754
755// Make sure that we count connecting sockets against the total limit.
756TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
757 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
758
759 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
760 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
761 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
762
763 // Create one asynchronous request.
764 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
765 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
766
[email protected]6b175382009-10-13 06:47:47767 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
768 // actually become pending until 2ms after they have been created. In order
769 // to flush all tasks, we need to wait so that we know there are no
770 // soon-to-be-pending tasks waiting.
771 PlatformThread::Sleep(10);
772 MessageLoop::current()->RunAllPending();
773
[email protected]211d21722009-07-22 15:48:53774 // The next synchronous request should wait for its turn.
775 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
776 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
777
[email protected]43a21b82010-06-10 21:30:54778 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53779
780 EXPECT_EQ(static_cast<int>(requests_.size()),
781 client_socket_factory_.allocation_count());
782
783 EXPECT_EQ(1, GetOrderOfRequest(1));
784 EXPECT_EQ(2, GetOrderOfRequest(2));
785 EXPECT_EQ(3, GetOrderOfRequest(3));
786 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17787 EXPECT_EQ(5, GetOrderOfRequest(5));
788
789 // Make sure we test order of all requests made.
790 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53791}
792
[email protected]6427fe22010-04-16 22:27:41793TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
794 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
795 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
796
797 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
798 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
799 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
800 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
801
802 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
803
804 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
805
806 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
807 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
808
809 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
810
811 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
812 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
813 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
814 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
815 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
816 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
817 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
818}
819
[email protected]d7027bb2010-05-10 18:58:54820TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
821 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
822 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
823
824 ClientSocketHandle handle;
825 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21826 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
827 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54828
829 ClientSocketHandle handles[4];
830 for (size_t i = 0; i < arraysize(handles); ++i) {
831 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21832 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init("b", params_, kDefaultPriority,
833 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54834 }
835
836 // One will be stalled, cancel all the handles now.
837 // This should hit the OnAvailableSocketSlot() code where we previously had
838 // stalled groups, but no longer have any.
839 for (size_t i = 0; i < arraysize(handles); ++i)
840 handles[i].Reset();
841}
842
[email protected]eb5a99382010-07-11 03:18:26843TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
845 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
846
[email protected]eb5a99382010-07-11 03:18:26847 {
848 ClientSocketHandle handles[kDefaultMaxSockets];
849 TestCompletionCallback callbacks[kDefaultMaxSockets];
850 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]df4b4ef2010-07-12 18:25:21851 EXPECT_EQ(OK, handles[i].Init(IntToString(i), params_, kDefaultPriority,
852 &callbacks[i], pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26853 }
854
855 // Force a stalled group.
856 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54857 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21858 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
859 kDefaultPriority, &callback,
860 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26861
862 // Cancel the stalled request.
863 stalled_handle.Reset();
864
865 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
866 EXPECT_EQ(0, pool_->IdleSocketCount());
867
868 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54869 }
870
[email protected]43a21b82010-06-10 21:30:54871 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
872 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26873}
[email protected]43a21b82010-06-10 21:30:54874
[email protected]eb5a99382010-07-11 03:18:26875TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
876 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
877 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
878
879 {
880 ClientSocketHandle handles[kDefaultMaxSockets];
881 for (int i = 0; i < kDefaultMaxSockets; ++i) {
882 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21883 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(IntToString(i), params_,
884 kDefaultPriority, &callback,
885 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26886 }
887
888 // Force a stalled group.
889 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
890 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54891 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21892 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
893 kDefaultPriority, &callback,
894 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26895
896 // Since it is stalled, it should have no connect jobs.
897 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
898
899 // Cancel the stalled request.
900 handles[0].Reset();
901
[email protected]994d4932010-07-12 17:55:13902 // Wait for the pending job to be guaranteed to complete.
903 PlatformThread::Sleep(TestConnectJob::kPendingConnectDelay * 2);
904
[email protected]eb5a99382010-07-11 03:18:26905 MessageLoop::current()->RunAllPending();
906
907 // Now we should have a connect job.
908 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
909
910 // The stalled socket should connect.
911 EXPECT_EQ(OK, callback.WaitForResult());
912
913 EXPECT_EQ(kDefaultMaxSockets + 1,
914 client_socket_factory_.allocation_count());
915 EXPECT_EQ(0, pool_->IdleSocketCount());
916 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
917
918 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54919 }
920
[email protected]eb5a99382010-07-11 03:18:26921 EXPECT_EQ(1, pool_->IdleSocketCount());
922}
[email protected]43a21b82010-06-10 21:30:54923
[email protected]eb5a99382010-07-11 03:18:26924TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
925 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
926 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54927
[email protected]eb5a99382010-07-11 03:18:26928 ClientSocketHandle stalled_handle;
929 TestCompletionCallback callback;
930 {
931 ClientSocketHandle handles[kDefaultMaxSockets];
932 for (int i = 0; i < kDefaultMaxSockets; ++i) {
933 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21934 EXPECT_EQ(OK, handles[i].Init(StringPrintf("Take 2: %d", i), params_,
935 kDefaultPriority, &callback, pool_,
936 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26937 }
938
939 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
940 EXPECT_EQ(0, pool_->IdleSocketCount());
941
942 // Now we will hit the socket limit.
[email protected]df4b4ef2010-07-12 18:25:21943 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
944 kDefaultPriority, &callback,
945 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26946
947 // Dropping out of scope will close all handles and return them to idle.
948 }
[email protected]43a21b82010-06-10 21:30:54949
950 // But if we wait for it, the released idle sockets will be closed in
951 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:10952 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:26953
954 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
955 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54956}
957
958// Regression test for http://crbug.com/40952.
959TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
961 pool_->EnableBackupJobs();
962 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
963
964 for (int i = 0; i < kDefaultMaxSockets; ++i) {
965 ClientSocketHandle handle;
966 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21967 EXPECT_EQ(OK, handle.Init(IntToString(i), params_, kDefaultPriority,
968 &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:54969 }
970
971 // Flush all the DoReleaseSocket tasks.
972 MessageLoop::current()->RunAllPending();
973
974 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
975 // reuse a socket.
976 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
977 ClientSocketHandle handle;
978 TestCompletionCallback callback;
979
980 // "0" is special here, since it should be the first entry in the sorted map,
981 // which is the one which we would close an idle socket for. We shouldn't
982 // close an idle socket though, since we should reuse the idle socket.
[email protected]df4b4ef2010-07-12 18:25:21983 EXPECT_EQ(OK, handle.Init("0", params_, kDefaultPriority, &callback, pool_,
984 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:54985
986 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
987 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
988}
989
[email protected]ab838892009-06-30 18:49:05990TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53991 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09992
[email protected]c9d6a1d2009-07-14 16:15:20993 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
994 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31995 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
996 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
997 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
998 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
999 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091000
[email protected]c9d6a1d2009-07-14 16:15:201001 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091002
[email protected]c9d6a1d2009-07-14 16:15:201003 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1004 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171005 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091006
[email protected]c9d6a1d2009-07-14 16:15:201007 EXPECT_EQ(1, GetOrderOfRequest(1));
1008 EXPECT_EQ(2, GetOrderOfRequest(2));
1009 EXPECT_EQ(6, GetOrderOfRequest(3));
1010 EXPECT_EQ(4, GetOrderOfRequest(4));
1011 EXPECT_EQ(3, GetOrderOfRequest(5));
1012 EXPECT_EQ(5, GetOrderOfRequest(6));
1013 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171014
1015 // Make sure we test order of all requests made.
1016 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091017}
1018
[email protected]ab838892009-06-30 18:49:051019TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091021
[email protected]c9d6a1d2009-07-14 16:15:201022 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1023 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311024 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1025 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1026 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1027 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1028 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091029
[email protected]c9d6a1d2009-07-14 16:15:201030 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091031
[email protected]c9d6a1d2009-07-14 16:15:201032 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1033 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1034
1035 EXPECT_EQ(static_cast<int>(requests_.size()),
1036 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171037 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091038}
1039
1040// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051041// The pending connect job will be cancelled and should not call back into
1042// ClientSocketPoolBase.
1043TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201045
[email protected]ab838892009-06-30 18:49:051046 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061047 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211048 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1049 &req, pool_, BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331050 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091051}
1052
[email protected]ab838892009-06-30 18:49:051053TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531054 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201055
[email protected]ab838892009-06-30 18:49:051056 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061057 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091058 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061059 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091060
[email protected]df4b4ef2010-07-12 18:25:211061 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1062 &callback, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091063
1064 handle.Reset();
1065
1066 TestCompletionCallback callback2;
[email protected]df4b4ef2010-07-12 18:25:211067 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1068 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091069
1070 EXPECT_EQ(OK, callback2.WaitForResult());
1071 EXPECT_FALSE(callback.have_result());
1072
1073 handle.Reset();
1074}
1075
[email protected]ab838892009-06-30 18:49:051076TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531077 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091078
[email protected]c9d6a1d2009-07-14 16:15:201079 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1080 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311081 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1082 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1083 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1084 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1085 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091086
1087 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201088 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331089 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1090 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091091
[email protected]c9d6a1d2009-07-14 16:15:201092 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091093
[email protected]c9d6a1d2009-07-14 16:15:201094 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1095 client_socket_factory_.allocation_count());
1096 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171097 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091098
[email protected]c9d6a1d2009-07-14 16:15:201099 EXPECT_EQ(1, GetOrderOfRequest(1));
1100 EXPECT_EQ(2, GetOrderOfRequest(2));
1101 EXPECT_EQ(5, GetOrderOfRequest(3));
1102 EXPECT_EQ(3, GetOrderOfRequest(4));
1103 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1104 EXPECT_EQ(4, GetOrderOfRequest(6));
1105 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171106
1107 // Make sure we test order of all requests made.
1108 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091109}
1110
1111class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1112 public:
[email protected]2ab05b52009-07-01 23:57:581113 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241114 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581115 TestConnectJobFactory* test_connect_job_factory,
1116 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091117 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061118 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581119 within_callback_(false),
1120 test_connect_job_factory_(test_connect_job_factory),
1121 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091122
1123 virtual void RunWithParams(const Tuple1<int>& params) {
1124 callback_.RunWithParams(params);
1125 ASSERT_EQ(OK, params.a);
1126
1127 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581128 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111129
1130 // Don't allow reuse of the socket. Disconnect it and then release it and
1131 // run through the MessageLoop once to get it completely released.
1132 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091133 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111134 {
1135 MessageLoop::ScopedNestableTaskAllower nestable(
1136 MessageLoop::current());
1137 MessageLoop::current()->RunAllPending();
1138 }
[email protected]f6d1d6eb2009-06-24 20:16:091139 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471140 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211141 scoped_refptr<TestSocketParams> params = new TestSocketParams();
1142 int rv = handle_->Init("a", params, kDefaultPriority, &next_job_callback,
1143 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581144 switch (next_job_type_) {
1145 case TestConnectJob::kMockJob:
1146 EXPECT_EQ(OK, rv);
1147 break;
1148 case TestConnectJob::kMockPendingJob:
1149 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471150
1151 // For pending jobs, wait for new socket to be created. This makes
1152 // sure there are no more pending operations nor any unclosed sockets
1153 // when the test finishes.
1154 // We need to give it a little bit of time to run, so that all the
1155 // operations that happen on timers (e.g. cleanup of idle
1156 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111157 {
1158 MessageLoop::ScopedNestableTaskAllower nestable(
1159 MessageLoop::current());
1160 PlatformThread::Sleep(10);
1161 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1162 }
[email protected]2ab05b52009-07-01 23:57:581163 break;
1164 default:
1165 FAIL() << "Unexpected job type: " << next_job_type_;
1166 break;
1167 }
[email protected]f6d1d6eb2009-06-24 20:16:091168 }
1169 }
1170
1171 int WaitForResult() {
1172 return callback_.WaitForResult();
1173 }
1174
1175 private:
1176 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241177 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091178 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581179 TestConnectJobFactory* const test_connect_job_factory_;
1180 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091181 TestCompletionCallback callback_;
1182};
1183
[email protected]2ab05b52009-07-01 23:57:581184TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531185 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201186
[email protected]0b7648c2009-07-06 20:14:011187 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061188 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581189 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061190 &handle, pool_.get(), connect_job_factory_,
1191 TestConnectJob::kMockPendingJob);
[email protected]df4b4ef2010-07-12 18:25:211192 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1193 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091194 ASSERT_EQ(ERR_IO_PENDING, rv);
1195
1196 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581197}
[email protected]f6d1d6eb2009-06-24 20:16:091198
[email protected]2ab05b52009-07-01 23:57:581199TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531200 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201201
[email protected]0b7648c2009-07-06 20:14:011202 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061203 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581204 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061205 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]df4b4ef2010-07-12 18:25:211206 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1207 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581208 ASSERT_EQ(ERR_IO_PENDING, rv);
1209
1210 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091211}
1212
1213// Make sure that pending requests get serviced after active requests get
1214// cancelled.
[email protected]ab838892009-06-30 18:49:051215TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531216 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201217
[email protected]0b7648c2009-07-06 20:14:011218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091219
[email protected]c9d6a1d2009-07-14 16:15:201220 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1221 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1222 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091227
[email protected]c9d6a1d2009-07-14 16:15:201228 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1229 // Let's cancel them.
1230 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331231 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1232 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091233 }
1234
[email protected]f6d1d6eb2009-06-24 20:16:091235 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201236 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1237 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331238 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091239 }
1240
[email protected]75439d3b2009-07-23 22:11:171241 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091242}
1243
1244// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051245TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531246 const size_t kMaxSockets = 5;
1247 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201248
[email protected]0b7648c2009-07-06 20:14:011249 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091250
[email protected]211d21722009-07-22 15:48:531251 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1252 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091253
1254 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531255 for (size_t i = 0; i < kNumberOfRequests; ++i)
1256 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091257
[email protected]211d21722009-07-22 15:48:531258 for (size_t i = 0; i < kNumberOfRequests; ++i)
1259 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091260}
1261
[email protected]5fc08e32009-07-15 17:09:571262TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531263 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571264
1265 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1266
[email protected]a512f5982009-08-18 16:01:061267 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211268 int rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1269 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571270 EXPECT_EQ(ERR_IO_PENDING, rv);
1271
1272 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331273 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571274
[email protected]df4b4ef2010-07-12 18:25:211275 rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1276 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571277 EXPECT_EQ(ERR_IO_PENDING, rv);
1278 EXPECT_EQ(OK, req.WaitForResult());
1279
[email protected]a6c59f62009-07-29 16:33:331280 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171281 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571282 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1283}
1284
[email protected]2b7523d2009-07-29 20:29:231285// Regression test for http://crbug.com/17985.
1286TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1287 const int kMaxSockets = 3;
1288 const int kMaxSocketsPerGroup = 2;
1289 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1290
[email protected]ac790b42009-12-02 04:31:311291 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231292
1293 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1294 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1295
1296 // This is going to be a pending request in an otherwise empty group.
1297 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1298
1299 // Reach the maximum socket limit.
1300 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1301
1302 // Create a stalled group with high priorities.
1303 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1304 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231305
[email protected]eb5a99382010-07-11 03:18:261306 // Release the first two sockets from "a". Because this is a keepalive,
1307 // the first release will unblock the pending request for "a". The
1308 // second release will unblock a request for "c", becaue it is the next
1309 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231310 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1311 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1312
1313 // Closing idle sockets should not get us into trouble, but in the bug
1314 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411315 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541316 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261317
1318 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231319}
1320
[email protected]4d3b05d2010-01-27 21:27:291321TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531322 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571323
1324 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061325 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531326 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211327 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571328 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331329 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571330 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331331 EXPECT_TRUE(req.handle()->is_initialized());
1332 EXPECT_TRUE(req.handle()->socket());
1333 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301334
[email protected]06650c52010-06-03 00:49:171335 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461336 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531337 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171338 EXPECT_TRUE(LogContainsEvent(
1339 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1340 NetLog::PHASE_NONE));
1341 EXPECT_TRUE(LogContainsEvent(
1342 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1343 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461344 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171345 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571346}
1347
[email protected]4d3b05d2010-01-27 21:27:291348TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571349 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571351
1352 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061353 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531354 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211355 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1356 &req, pool_, log.bound()));
[email protected]a6c59f62009-07-29 16:33:331357 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571358 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301359
[email protected]06650c52010-06-03 00:49:171360 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461361 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531362 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171363 EXPECT_TRUE(LogContainsEvent(
1364 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1365 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321366 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171367 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571368}
1369
[email protected]4d3b05d2010-01-27 21:27:291370TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101371 // TODO(eroman): Add back the log expectations! Removed them because the
1372 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531373 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571374
1375 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061376 TestSocketRequest req(&request_order_, &completion_count_);
1377 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571378
[email protected]df4b4ef2010-07-12 18:25:211379 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1380 &req, pool_, BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531381 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211382 EXPECT_EQ(ERR_IO_PENDING, req2.handle()->Init("a", params_, kDefaultPriority,
1383 &req2, pool_, BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571384
[email protected]a6c59f62009-07-29 16:33:331385 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571386
[email protected]fd7b7c92009-08-20 19:38:301387
1388 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301389
[email protected]5fc08e32009-07-15 17:09:571390 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331391 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301392
1393 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531394 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571395}
1396
[email protected]4d3b05d2010-01-27 21:27:291397TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341398 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1399
[email protected]17a0c6c2009-08-04 00:07:041400 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1401
[email protected]ac790b42009-12-02 04:31:311402 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1403 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1404 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1405 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341406
1407 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1408 requests_[2]->handle()->Reset();
1409 requests_[3]->handle()->Reset();
1410 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1411
1412 requests_[1]->handle()->Reset();
1413 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1414
1415 requests_[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261416 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341417}
1418
[email protected]5fc08e32009-07-15 17:09:571419// When requests and ConnectJobs are not coupled, the request will get serviced
1420// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291421TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531422 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571423
1424 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321425 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571426
[email protected]a512f5982009-08-18 16:01:061427 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211428 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1429 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571430 EXPECT_EQ(ERR_IO_PENDING, rv);
1431 EXPECT_EQ(OK, req1.WaitForResult());
1432
1433 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1434 // without a job.
1435 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1436
[email protected]a512f5982009-08-18 16:01:061437 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211438 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1439 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571440 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061441 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211442 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1443 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571444 EXPECT_EQ(ERR_IO_PENDING, rv);
1445
1446 // Both Requests 2 and 3 are pending. We release socket 1 which should
1447 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331448 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261449 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331450 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571451 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331452 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571453
1454 // Signal job 2, which should service request 3.
1455
1456 client_socket_factory_.SignalJobs();
1457 EXPECT_EQ(OK, req3.WaitForResult());
1458
1459 ASSERT_EQ(3U, request_order_.size());
1460 EXPECT_EQ(&req1, request_order_[0]);
1461 EXPECT_EQ(&req2, request_order_[1]);
1462 EXPECT_EQ(&req3, request_order_[2]);
1463 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1464}
1465
1466// The requests are not coupled to the jobs. So, the requests should finish in
1467// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291468TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531469 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571470 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321471 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571472
[email protected]a512f5982009-08-18 16:01:061473 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211474 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1475 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571476 EXPECT_EQ(ERR_IO_PENDING, rv);
1477
[email protected]a512f5982009-08-18 16:01:061478 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211479 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1480 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571481 EXPECT_EQ(ERR_IO_PENDING, rv);
1482
1483 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321484 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571485
[email protected]a512f5982009-08-18 16:01:061486 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211487 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1488 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571489 EXPECT_EQ(ERR_IO_PENDING, rv);
1490
1491 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1492 EXPECT_EQ(OK, req2.WaitForResult());
1493 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1494
1495 ASSERT_EQ(3U, request_order_.size());
1496 EXPECT_EQ(&req1, request_order_[0]);
1497 EXPECT_EQ(&req2, request_order_[1]);
1498 EXPECT_EQ(&req3, request_order_[2]);
1499}
1500
[email protected]e6ec67b2010-06-16 00:12:461501TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531502 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571503 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321504 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571505
[email protected]a512f5982009-08-18 16:01:061506 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211507 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1508 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571509 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331510 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571511
1512 MessageLoop::current()->RunAllPending();
1513
[email protected]a512f5982009-08-18 16:01:061514 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211515 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1516 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571517 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561518 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1519 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571520}
1521
[email protected]e772db3f2010-07-12 18:11:131522TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1523 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1524 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1525
1526 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211527 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.handle()->Init("a", params_,
1528 kDefaultPriority,
1529 &req, pool_,
1530 BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131531 EXPECT_TRUE(req.handle()->is_initialized());
1532 EXPECT_TRUE(req.handle()->socket());
1533 req.handle()->Reset();
1534}
1535
1536TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1537 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1538
1539 connect_job_factory_->set_job_type(
1540 TestConnectJob::kMockPendingRecoverableJob);
1541 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211542 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1543 &req, pool_, BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131544 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1545 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult());
1546 EXPECT_TRUE(req.handle()->is_initialized());
1547 EXPECT_TRUE(req.handle()->socket());
1548 req.handle()->Reset();
1549}
1550
[email protected]4d3b05d2010-01-27 21:27:291551TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161552 CreatePoolWithIdleTimeouts(
1553 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1554 base::TimeDelta(), // Time out unused sockets immediately.
1555 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1556
1557 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1558
1559 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1560
1561 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211562 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161563 EXPECT_EQ(ERR_IO_PENDING, rv);
1564 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1565
1566 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211567 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161568 EXPECT_EQ(ERR_IO_PENDING, rv);
1569 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1570
1571 // Cancel one of the requests. Wait for the other, which will get the first
1572 // job. Release the socket. Run the loop again to make sure the second
1573 // socket is sitting idle and the first one is released (since ReleaseSocket()
1574 // just posts a DoReleaseSocket() task).
1575
1576 req.handle()->Reset();
1577 EXPECT_EQ(OK, req2.WaitForResult());
1578 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471579
1580 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1581 // actually become pending until 2ms after they have been created. In order
1582 // to flush all tasks, we need to wait so that we know there are no
1583 // soon-to-be-pending tasks waiting.
1584 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161585 MessageLoop::current()->RunAllPending();
1586
1587 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041588
[email protected]9bf28db2009-08-29 01:35:161589 // Invoke the idle socket cleanup check. Only one socket should be left, the
1590 // used socket. Request it to make sure that it's used.
1591
1592 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531593 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211594 rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161595 EXPECT_EQ(OK, rv);
1596 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151597 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451598 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161599}
1600
[email protected]2041cf342010-02-19 03:15:591601// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161602// because of multiple releasing disconnected sockets.
1603TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1604 CreatePoolWithIdleTimeouts(
1605 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1606 base::TimeDelta(), // Time out unused sockets immediately.
1607 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1608
1609 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1610
1611 // Startup 4 connect jobs. Two of them will be pending.
1612
1613 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211614 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161615 EXPECT_EQ(OK, rv);
1616
1617 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211618 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161619 EXPECT_EQ(OK, rv);
1620
1621 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211622 rv = req3.handle()->Init("a", params_, LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161623 EXPECT_EQ(ERR_IO_PENDING, rv);
1624
1625 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211626 rv = req4.handle()->Init("a", params_, LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161627 EXPECT_EQ(ERR_IO_PENDING, rv);
1628
1629 // Release two disconnected sockets.
1630
1631 req.handle()->socket()->Disconnect();
1632 req.handle()->Reset();
1633 req2.handle()->socket()->Disconnect();
1634 req2.handle()->Reset();
1635
1636 EXPECT_EQ(OK, req3.WaitForResult());
1637 EXPECT_FALSE(req3.handle()->is_reused());
1638 EXPECT_EQ(OK, req4.WaitForResult());
1639 EXPECT_FALSE(req4.handle()->is_reused());
1640}
1641
[email protected]d7027bb2010-05-10 18:58:541642// Regression test for http://crbug.com/42267.
1643// When DoReleaseSocket() is processed for one socket, it is blocked because the
1644// other stalled groups all have releasing sockets, so no progress can be made.
1645TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1646 CreatePoolWithIdleTimeouts(
1647 4 /* socket limit */, 4 /* socket limit per group */,
1648 base::TimeDelta(), // Time out unused sockets immediately.
1649 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1650
1651 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1652
1653 // Max out the socket limit with 2 per group.
1654
1655 scoped_ptr<TestSocketRequest> req_a[4];
1656 scoped_ptr<TestSocketRequest> req_b[4];
1657
1658 for (int i = 0; i < 2; ++i) {
1659 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1660 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211661 EXPECT_EQ(OK, req_a[i]->handle()->Init("a", params_, LOWEST, req_a[i].get(),
1662 pool_, BoundNetLog()));
1663 EXPECT_EQ(OK, req_b[i]->handle()->Init("b", params_, LOWEST, req_b[i].get(),
1664 pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541665 }
[email protected]b89f7e42010-05-20 20:37:001666
[email protected]d7027bb2010-05-10 18:58:541667 // Make 4 pending requests, 2 per group.
1668
1669 for (int i = 2; i < 4; ++i) {
1670 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1671 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211672 EXPECT_EQ(ERR_IO_PENDING, req_a[i]->handle()->Init("a", params_, LOWEST,
1673 req_a[i].get(), pool_,
1674 BoundNetLog()));
1675 EXPECT_EQ(ERR_IO_PENDING, req_b[i]->handle()->Init("b", params_, LOWEST,
1676 req_b[i].get(), pool_,
1677 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541678 }
1679
1680 // Release b's socket first. The order is important, because in
1681 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1682 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1683 // first, which has a releasing socket, so it refuses to start up another
1684 // ConnectJob. So, we used to infinite loop on this.
1685 req_b[0]->handle()->socket()->Disconnect();
1686 req_b[0]->handle()->Reset();
1687 req_a[0]->handle()->socket()->Disconnect();
1688 req_a[0]->handle()->Reset();
1689
1690 // Used to get stuck here.
1691 MessageLoop::current()->RunAllPending();
1692
1693 req_b[1]->handle()->socket()->Disconnect();
1694 req_b[1]->handle()->Reset();
1695 req_a[1]->handle()->socket()->Disconnect();
1696 req_a[1]->handle()->Reset();
1697
1698 for (int i = 2; i < 4; ++i) {
1699 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1700 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1701 }
1702}
1703
[email protected]fd4fe0b2010-02-08 23:02:151704TEST_F(ClientSocketPoolBaseTest,
1705 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1706 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1707
1708 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1709
1710 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1711 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1712 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1713 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1714
1715 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1716 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1717 EXPECT_EQ(2u, completion_count_);
1718
1719 // Releases one connection.
1720 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1721 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1722
1723 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1724 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1725 EXPECT_EQ(4u, completion_count_);
1726
1727 EXPECT_EQ(1, GetOrderOfRequest(1));
1728 EXPECT_EQ(2, GetOrderOfRequest(2));
1729 EXPECT_EQ(3, GetOrderOfRequest(3));
1730 EXPECT_EQ(4, GetOrderOfRequest(4));
1731
1732 // Make sure we test order of all requests made.
1733 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1734}
1735
[email protected]4f1e4982010-03-02 18:31:041736class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1737 public:
1738 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1739 : pool_(pool) {}
1740
1741 ClientSocketHandle* handle() { return &handle_; }
1742
1743 int WaitForResult() {
1744 return callback_.WaitForResult();
1745 }
1746
1747 virtual void RunWithParams(const Tuple1<int>& params) {
1748 callback_.RunWithParams(params);
1749 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:211750 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
1751 EXPECT_EQ(ERR_IO_PENDING, handle2_.Init("a", con_params, kDefaultPriority,
1752 &callback2_, pool_, BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041753 }
1754
1755 private:
[email protected]df4b4ef2010-07-12 18:25:211756 scoped_refptr<TestClientSocketPool> pool_;
[email protected]4f1e4982010-03-02 18:31:041757 ClientSocketHandle handle_;
1758 ClientSocketHandle handle2_;
1759 TestCompletionCallback callback_;
1760 TestCompletionCallback callback2_;
1761};
1762
[email protected]b6501d3d2010-06-03 23:53:341763// http://crbug.com/44724 regression test.
1764// We start releasing the pool when we flush on network change. When that
1765// happens, the only active references are in the ClientSocketHandles. When a
1766// ConnectJob completes and calls back into the last ClientSocketHandle, that
1767// callback can release the last reference and delete the pool. After the
1768// callback finishes, we go back to the stack frame within the now-deleted pool.
1769// Executing any code that refers to members of the now-deleted pool can cause
1770// crashes.
1771TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1773 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1774
1775 ClientSocketHandle handle;
1776 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211777 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1778 &callback, pool_, BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:341779
1780 // Simulate flushing the pool.
1781 pool_ = NULL;
1782
1783 // We'll call back into this now.
1784 callback.WaitForResult();
1785}
1786
[email protected]a7e38572010-06-07 18:22:241787TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1788 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1789 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1790
1791 ClientSocketHandle handle;
1792 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211793 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1794 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241795 EXPECT_EQ(OK, callback.WaitForResult());
1796 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1797
1798 pool_->Flush();
1799
1800 handle.Reset();
1801 MessageLoop::current()->RunAllPending();
1802
[email protected]df4b4ef2010-07-12 18:25:211803 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1804 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241805 EXPECT_EQ(OK, callback.WaitForResult());
1806 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1807}
1808
[email protected]25eea382010-07-10 23:55:261809// Cancel a pending socket request while we're at max sockets,
1810// and verify that the backup socket firing doesn't cause a crash.
1811TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
1812 // Max 4 sockets globally, max 4 sockets per group.
1813 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1814 pool_->EnableBackupJobs();
1815
1816 // Create the first socket and set to ERR_IO_PENDING. This creates a
1817 // backup job.
1818 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1819 ClientSocketHandle handle;
1820 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211821 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
1822 &callback, pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261823
1824 // Start (MaxSockets - 1) connected sockets to reach max sockets.
1825 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1826 ClientSocketHandle handles[kDefaultMaxSockets];
1827 for (int i = 1; i < kDefaultMaxSockets; ++i) {
1828 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211829 EXPECT_EQ(OK, handles[i].Init("bar", params_, kDefaultPriority, &callback,
1830 pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261831 }
1832
1833 MessageLoop::current()->RunAllPending();
1834
1835 // Cancel the pending request.
1836 handle.Reset();
1837
1838 // Wait for the backup timer to fire (add some slop to ensure it fires)
1839 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
1840
1841 MessageLoop::current()->RunAllPending();
1842 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1843}
1844
[email protected]eb5a99382010-07-11 03:18:261845// Test delayed socket binding for the case where we have two connects,
1846// and while one is waiting on a connect, the other frees up.
1847// The socket waiting on a connect should switch immediately to the freed
1848// up socket.
1849TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
1850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1851 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1852
1853 ClientSocketHandle handle1;
1854 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211855 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
1856 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261857 EXPECT_EQ(OK, callback.WaitForResult());
1858
1859 // No idle sockets, no pending jobs.
1860 EXPECT_EQ(0, pool_->IdleSocketCount());
1861 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1862
1863 // Create a second socket to the same host, but this one will wait.
1864 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1865 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:211866 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
1867 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261868 // No idle sockets, and one connecting job.
1869 EXPECT_EQ(0, pool_->IdleSocketCount());
1870 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1871
1872 // Return the first handle to the pool. This will initiate the delayed
1873 // binding.
1874 handle1.Reset();
1875
1876 MessageLoop::current()->RunAllPending();
1877
1878 // Still no idle sockets, still one pending connect job.
1879 EXPECT_EQ(0, pool_->IdleSocketCount());
1880 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1881
1882 // The second socket connected, even though it was a Waiting Job.
1883 EXPECT_EQ(OK, callback.WaitForResult());
1884
1885 // And we can see there is still one job waiting.
1886 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1887
1888 // Finally, signal the waiting Connect.
1889 client_socket_factory_.SignalJobs();
1890 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1891
1892 MessageLoop::current()->RunAllPending();
1893}
1894
1895// Test delayed socket binding when a group is at capacity and one
1896// of the group's sockets frees up.
1897TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
1898 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1899 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1900
1901 ClientSocketHandle handle1;
1902 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211903 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
1904 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261905 EXPECT_EQ(OK, callback.WaitForResult());
1906
1907 // No idle sockets, no pending jobs.
1908 EXPECT_EQ(0, pool_->IdleSocketCount());
1909 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1910
1911 // Create a second socket to the same host, but this one will wait.
1912 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1913 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:211914 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
1915 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261916 // No idle sockets, and one connecting job.
1917 EXPECT_EQ(0, pool_->IdleSocketCount());
1918 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1919
1920 // Return the first handle to the pool. This will initiate the delayed
1921 // binding.
1922 handle1.Reset();
1923
1924 MessageLoop::current()->RunAllPending();
1925
1926 // Still no idle sockets, still one pending connect job.
1927 EXPECT_EQ(0, pool_->IdleSocketCount());
1928 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1929
1930 // The second socket connected, even though it was a Waiting Job.
1931 EXPECT_EQ(OK, callback.WaitForResult());
1932
1933 // And we can see there is still one job waiting.
1934 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1935
1936 // Finally, signal the waiting Connect.
1937 client_socket_factory_.SignalJobs();
1938 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1939
1940 MessageLoop::current()->RunAllPending();
1941}
1942
1943// Test out the case where we have one socket connected, one
1944// connecting, when the first socket finishes and goes idle.
1945// Although the second connection is pending, th second request
1946// should complete, by taking the first socket's idle socket.
1947TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
1948 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1950
1951 ClientSocketHandle handle1;
1952 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211953 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
1954 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261955 EXPECT_EQ(OK, callback.WaitForResult());
1956
1957 // No idle sockets, no pending jobs.
1958 EXPECT_EQ(0, pool_->IdleSocketCount());
1959 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1960
1961 // Create a second socket to the same host, but this one will wait.
1962 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1963 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:211964 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
1965 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261966 // No idle sockets, and one connecting job.
1967 EXPECT_EQ(0, pool_->IdleSocketCount());
1968 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1969
1970 // Return the first handle to the pool. This will initiate the delayed
1971 // binding.
1972 handle1.Reset();
1973
1974 MessageLoop::current()->RunAllPending();
1975
1976 // Still no idle sockets, still one pending connect job.
1977 EXPECT_EQ(0, pool_->IdleSocketCount());
1978 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1979
1980 // The second socket connected, even though it was a Waiting Job.
1981 EXPECT_EQ(OK, callback.WaitForResult());
1982
1983 // And we can see there is still one job waiting.
1984 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1985
1986 // Finally, signal the waiting Connect.
1987 client_socket_factory_.SignalJobs();
1988 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1989
1990 MessageLoop::current()->RunAllPending();
1991}
1992
[email protected]f6d1d6eb2009-06-24 20:16:091993} // namespace
1994
1995} // namespace net