blob: 1624a46f00c7cb5ffa914ac073d27005acd304c5 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]43a21b82010-06-10 21:30:5414#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0615#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5316#include "net/base/net_log.h"
17#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0926#include "testing/gtest/include/gtest/gtest.h"
27
28namespace net {
29
30namespace {
31
[email protected]211d21722009-07-22 15:48:5332const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2033const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5234const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0135
[email protected]df4b4ef2010-07-12 18:25:2136class TestSocketParams : public base::RefCounted<TestSocketParams> {
37 private:
38 friend class base::RefCounted<TestSocketParams>;
39 ~TestSocketParams() {}
40};
[email protected]7fc5b09a2010-02-27 00:07:3841typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4942
[email protected]f6d1d6eb2009-06-24 20:16:0943class MockClientSocket : public ClientSocket {
44 public:
[email protected]0f873e82010-09-02 16:09:0145 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0946
[email protected]ab838892009-06-30 18:49:0547 // Socket methods:
48 virtual int Read(
49 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
50 return ERR_UNEXPECTED;
51 }
52
53 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0154 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
55 was_used_to_convey_data_ = true;
56 return len;
[email protected]ab838892009-06-30 18:49:0557 }
[email protected]06650c52010-06-03 00:49:1758 virtual bool SetReceiveBufferSize(int32 size) { return true; }
59 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0560
[email protected]f6d1d6eb2009-06-24 20:16:0961 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0562
[email protected]a2006ece2010-04-23 16:44:0263 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0964 connected_ = true;
65 return OK;
66 }
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]ab838892009-06-30 18:49:0568 virtual void Disconnect() { connected_ = false; }
69 virtual bool IsConnected() const { return connected_; }
70 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0171
[email protected]ac9eec62010-02-20 18:50:3872 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1673 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0974 }
[email protected]f6d1d6eb2009-06-24 20:16:0975
[email protected]a2006ece2010-04-23 16:44:0276 virtual const BoundNetLog& NetLog() const {
77 return net_log_;
78 }
79
[email protected]9b5614a2010-08-25 20:29:4580 virtual void SetSubresourceSpeculation() {}
81 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0182 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]9b5614a2010-08-25 20:29:4583
[email protected]f6d1d6eb2009-06-24 20:16:0984 private:
85 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0286 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0187 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0988
[email protected]ab838892009-06-30 18:49:0589 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0990};
91
[email protected]5fc08e32009-07-15 17:09:5792class TestConnectJob;
93
[email protected]f6d1d6eb2009-06-24 20:16:0994class MockClientSocketFactory : public ClientSocketFactory {
95 public:
[email protected]ab838892009-06-30 18:49:0596 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0997
[email protected]0a0b7682010-08-25 17:08:0798 virtual ClientSocket* CreateTCPClientSocket(
99 const AddressList& addresses,
100 NetLog* /* net_log */,
101 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09102 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05103 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09104 }
105
106 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18107 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:09108 const std::string& hostname,
109 const SSLConfig& ssl_config) {
110 NOTIMPLEMENTED();
111 return NULL;
112 }
113
[email protected]5fc08e32009-07-15 17:09:57114 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
115 void SignalJobs();
116
[email protected]f6d1d6eb2009-06-24 20:16:09117 int allocation_count() const { return allocation_count_; }
118
[email protected]f6d1d6eb2009-06-24 20:16:09119 private:
120 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57121 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09122};
123
[email protected]ab838892009-06-30 18:49:05124class TestConnectJob : public ConnectJob {
125 public:
126 enum JobType {
127 kMockJob,
128 kMockFailingJob,
129 kMockPendingJob,
130 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57131 kMockWaitingJob,
132 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13133 kMockRecoverableJob,
134 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18135 kMockAdditionalErrorStateJob,
136 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05137 };
138
[email protected]994d4932010-07-12 17:55:13139 // The kMockPendingJob uses a slight delay before allowing the connect
140 // to complete.
141 static const int kPendingConnectDelay = 2;
142
[email protected]ab838892009-06-30 18:49:05143 TestConnectJob(JobType job_type,
144 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49145 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34146 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05147 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30148 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17149 NetLog* net_log)
150 : ConnectJob(group_name, timeout_duration, delegate,
151 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58152 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05153 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21154 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18155 load_state_(LOAD_STATE_IDLE),
156 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05157
[email protected]974ebd62009-08-03 23:14:34158 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13159 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34160 }
161
[email protected]46451352009-09-01 14:54:21162 virtual LoadState GetLoadState() const { return load_state_; }
163
[email protected]e60e47a2010-07-14 03:37:18164 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
165 if (store_additional_error_state_) {
166 // Set all of the additional error state fields in some way.
167 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43168 HttpResponseInfo info;
169 info.headers = new HttpResponseHeaders("");
170 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18171 }
172 }
173
[email protected]974ebd62009-08-03 23:14:34174 private:
[email protected]ab838892009-06-30 18:49:05175 // ConnectJob methods:
176
[email protected]974ebd62009-08-03 23:14:34177 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05178 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07179 client_socket_factory_->CreateTCPClientSocket(
180 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40181 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05182 switch (job_type_) {
183 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13184 return DoConnect(true /* successful */, false /* sync */,
185 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05186 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13187 return DoConnect(false /* error */, false /* sync */,
188 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05189 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57190 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47191
192 // Depending on execution timings, posting a delayed task can result
193 // in the task getting executed the at the earliest possible
194 // opportunity or only after returning once from the message loop and
195 // then a second call into the message loop. In order to make behavior
196 // more deterministic, we change the default delay to 2ms. This should
197 // always require us to wait for the second call into the message loop.
198 //
199 // N.B. The correct fix for this and similar timing problems is to
200 // abstract time for the purpose of unittests. Unfortunately, we have
201 // a lot of third-party components that directly call the various
202 // time functions, so this change would be rather invasive.
203 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05204 FROM_HERE,
205 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47206 &TestConnectJob::DoConnect,
207 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13208 true /* async */,
209 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13210 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05211 return ERR_IO_PENDING;
212 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57213 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47214 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05215 FROM_HERE,
216 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47217 &TestConnectJob::DoConnect,
218 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13219 true /* async */,
220 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47221 2);
[email protected]ab838892009-06-30 18:49:05222 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57223 case kMockWaitingJob:
224 client_socket_factory_->WaitForSignal(this);
225 waiting_success_ = true;
226 return ERR_IO_PENDING;
227 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46228 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57229 FROM_HERE,
230 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46231 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57232 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13233 case kMockRecoverableJob:
234 return DoConnect(false /* error */, false /* sync */,
235 true /* recoverable */);
236 case kMockPendingRecoverableJob:
237 set_load_state(LOAD_STATE_CONNECTING);
238 MessageLoop::current()->PostDelayedTask(
239 FROM_HERE,
240 method_factory_.NewRunnableMethod(
241 &TestConnectJob::DoConnect,
242 false /* error */,
243 true /* async */,
244 true /* recoverable */),
245 2);
246 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18247 case kMockAdditionalErrorStateJob:
248 store_additional_error_state_ = true;
249 return DoConnect(false /* error */, false /* sync */,
250 false /* recoverable */);
251 case kMockPendingAdditionalErrorStateJob:
252 set_load_state(LOAD_STATE_CONNECTING);
253 store_additional_error_state_ = true;
254 MessageLoop::current()->PostDelayedTask(
255 FROM_HERE,
256 method_factory_.NewRunnableMethod(
257 &TestConnectJob::DoConnect,
258 false /* error */,
259 true /* async */,
260 false /* recoverable */),
261 2);
262 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05263 default:
264 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40265 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05266 return ERR_FAILED;
267 }
268 }
269
[email protected]46451352009-09-01 14:54:21270 void set_load_state(LoadState load_state) { load_state_ = load_state; }
271
[email protected]e772db3f2010-07-12 18:11:13272 int DoConnect(bool succeed, bool was_async, bool recoverable) {
273 int result = OK;
[email protected]ab838892009-06-30 18:49:05274 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02275 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13276 } else if (recoverable) {
277 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40278 } else {
[email protected]e772db3f2010-07-12 18:11:13279 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40280 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05281 }
[email protected]2ab05b52009-07-01 23:57:58282
283 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30284 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05285 return result;
286 }
287
[email protected]cfa8228c2010-06-17 01:07:56288 // This function helps simulate the progress of load states on a ConnectJob.
289 // Each time it is called it advances the load state and posts a task to be
290 // called again. It stops at the last connecting load state (the one
291 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57292 void AdvanceLoadState(LoadState state) {
293 int tmp = state;
294 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56295 if (tmp < LOAD_STATE_SENDING_REQUEST) {
296 state = static_cast<LoadState>(tmp);
297 set_load_state(state);
298 MessageLoop::current()->PostTask(
299 FROM_HERE,
300 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
301 state));
302 }
[email protected]5fc08e32009-07-15 17:09:57303 }
304
305 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05306 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57307 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05308 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21309 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18310 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05311
312 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
313};
314
[email protected]d80a4322009-08-14 07:07:49315class TestConnectJobFactory
316 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05317 public:
[email protected]5fc08e32009-07-15 17:09:57318 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05319 : job_type_(TestConnectJob::kMockJob),
320 client_socket_factory_(client_socket_factory) {}
321
322 virtual ~TestConnectJobFactory() {}
323
324 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
325
[email protected]974ebd62009-08-03 23:14:34326 void set_timeout_duration(base::TimeDelta timeout_duration) {
327 timeout_duration_ = timeout_duration;
328 }
329
[email protected]ab838892009-06-30 18:49:05330 // ConnectJobFactory methods:
331
332 virtual ConnectJob* NewConnectJob(
333 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49334 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17335 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05336 return new TestConnectJob(job_type_,
337 group_name,
338 request,
[email protected]974ebd62009-08-03 23:14:34339 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05340 delegate,
[email protected]fd7b7c92009-08-20 19:38:30341 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17342 NULL);
[email protected]ab838892009-06-30 18:49:05343 }
344
[email protected]a796bcec2010-03-22 17:17:26345 virtual base::TimeDelta ConnectionTimeout() const {
346 return timeout_duration_;
347 }
348
[email protected]ab838892009-06-30 18:49:05349 private:
350 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34351 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57352 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05353
354 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
355};
356
357class TestClientSocketPool : public ClientSocketPool {
358 public:
359 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53360 int max_sockets,
[email protected]ab838892009-06-30 18:49:05361 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13362 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16363 base::TimeDelta unused_idle_socket_timeout,
364 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49365 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00366 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16367 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38368 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05369
[email protected]2431756e2010-09-29 20:26:13370 virtual ~TestClientSocketPool() {}
371
[email protected]ab838892009-06-30 18:49:05372 virtual int RequestSocket(
373 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49374 const void* params,
[email protected]ac790b42009-12-02 04:31:31375 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05376 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46377 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53378 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21379 const scoped_refptr<TestSocketParams>* casted_socket_params =
380 static_cast<const scoped_refptr<TestSocketParams>*>(params);
381 return base_.RequestSocket(group_name, *casted_socket_params, priority,
382 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05383 }
384
385 virtual void CancelRequest(
386 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21387 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49388 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05389 }
390
391 virtual void ReleaseSocket(
392 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24393 ClientSocket* socket,
394 int id) {
395 base_.ReleaseSocket(group_name, socket, id);
396 }
397
398 virtual void Flush() {
399 base_.Flush();
[email protected]ab838892009-06-30 18:49:05400 }
401
402 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49403 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05404 }
405
[email protected]d80a4322009-08-14 07:07:49406 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05407
408 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49409 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05410 }
411
412 virtual LoadState GetLoadState(const std::string& group_name,
413 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49414 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05415 }
416
[email protected]ba00b492010-09-08 14:53:38417 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
418 const std::string& type,
419 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27420 return base_.GetInfoAsValue(name, type);
421 }
422
[email protected]a796bcec2010-03-22 17:17:26423 virtual base::TimeDelta ConnectionTimeout() const {
424 return base_.ConnectionTimeout();
425 }
426
[email protected]2431756e2010-09-29 20:26:13427 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00428 return base_.histograms();
429 }
[email protected]a796bcec2010-03-22 17:17:26430
[email protected]d80a4322009-08-14 07:07:49431 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20432
[email protected]974ebd62009-08-03 23:14:34433 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49434 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34435 }
436
[email protected]2abfe90a2010-08-25 17:49:51437 bool HasGroup(const std::string& group_name) const {
438 return base_.HasGroup(group_name);
439 }
440
[email protected]9bf28db2009-08-29 01:35:16441 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
442
[email protected]06d94042010-08-25 01:45:22443 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54444
[email protected]ab838892009-06-30 18:49:05445 private:
[email protected]d80a4322009-08-14 07:07:49446 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05447
448 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
449};
450
[email protected]a937a06d2009-08-19 21:19:24451} // namespace
452
[email protected]7fc5b09a2010-02-27 00:07:38453REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24454
455namespace {
456
[email protected]5fc08e32009-07-15 17:09:57457void MockClientSocketFactory::SignalJobs() {
458 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
459 it != waiting_jobs_.end(); ++it) {
460 (*it)->Signal();
461 }
462 waiting_jobs_.clear();
463}
464
[email protected]974ebd62009-08-03 23:14:34465class TestConnectJobDelegate : public ConnectJob::Delegate {
466 public:
467 TestConnectJobDelegate()
468 : have_result_(false), waiting_for_result_(false), result_(OK) {}
469 virtual ~TestConnectJobDelegate() {}
470
471 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
472 result_ = result;
[email protected]6e713f02009-08-06 02:56:40473 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07474 // socket.get() should be NULL iff result != OK
475 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34476 delete job;
477 have_result_ = true;
478 if (waiting_for_result_)
479 MessageLoop::current()->Quit();
480 }
481
482 int WaitForResult() {
483 DCHECK(!waiting_for_result_);
484 while (!have_result_) {
485 waiting_for_result_ = true;
486 MessageLoop::current()->Run();
487 waiting_for_result_ = false;
488 }
489 have_result_ = false; // auto-reset for next callback
490 return result_;
491 }
492
493 private:
494 bool have_result_;
495 bool waiting_for_result_;
496 int result_;
497};
498
[email protected]2431756e2010-09-29 20:26:13499class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09500 protected:
[email protected]b89f7e42010-05-20 20:37:00501 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21502 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13503 histograms_("ClientSocketPoolTest") {}
504
505 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20506
[email protected]211d21722009-07-22 15:48:53507 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16508 CreatePoolWithIdleTimeouts(
509 max_sockets,
510 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00511 base::TimeDelta::FromSeconds(
512 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16513 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
514 }
515
516 void CreatePoolWithIdleTimeouts(
517 int max_sockets, int max_sockets_per_group,
518 base::TimeDelta unused_idle_socket_timeout,
519 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20520 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04521 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13522 pool_.reset(new TestClientSocketPool(max_sockets,
523 max_sockets_per_group,
524 &histograms_,
525 unused_idle_socket_timeout,
526 used_idle_socket_timeout,
527 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20528 }
[email protected]f6d1d6eb2009-06-24 20:16:09529
[email protected]ac790b42009-12-02 04:31:31530 int StartRequest(const std::string& group_name,
531 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13532 return test_base_.StartRequestUsingPool<
533 TestClientSocketPool, TestSocketParams>(
534 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09535 }
536
[email protected]2431756e2010-09-29 20:26:13537 int GetOrderOfRequest(size_t index) const {
538 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09539 }
540
[email protected]2431756e2010-09-29 20:26:13541 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
542 return test_base_.ReleaseOneConnection(keep_alive);
543 }
544
545 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
546 test_base_.ReleaseAllConnections(keep_alive);
547 }
548
549 TestSocketRequest* request(int i) { return test_base_.request(i); }
550 size_t requests_size() const { return test_base_.requests_size(); }
551 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
552 size_t completion_count() const { return test_base_.completion_count(); }
553
[email protected]f6d1d6eb2009-06-24 20:16:09554 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04555 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21556 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13557 ClientSocketPoolHistograms histograms_;
558 scoped_ptr<TestClientSocketPool> pool_;
559 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09560};
561
[email protected]974ebd62009-08-03 23:14:34562// Even though a timeout is specified, it doesn't time out on a synchronous
563// completion.
564TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
565 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06566 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49567 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21568 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34569 scoped_ptr<TestConnectJob> job(
570 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12571 "a",
[email protected]974ebd62009-08-03 23:14:34572 request,
573 base::TimeDelta::FromMicroseconds(1),
574 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30575 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17576 NULL));
[email protected]974ebd62009-08-03 23:14:34577 EXPECT_EQ(OK, job->Connect());
578}
579
580TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
581 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06582 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17583 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53584
[email protected]d80a4322009-08-14 07:07:49585 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21586 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34587 // Deleted by TestConnectJobDelegate.
588 TestConnectJob* job =
589 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12590 "a",
[email protected]974ebd62009-08-03 23:14:34591 request,
592 base::TimeDelta::FromMicroseconds(1),
593 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30594 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17595 &log);
[email protected]974ebd62009-08-03 23:14:34596 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
597 PlatformThread::Sleep(1);
598 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30599
[email protected]06650c52010-06-03 00:49:17600 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46601 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53602 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17603 EXPECT_TRUE(LogContainsBeginEvent(
604 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46605 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17606 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
607 NetLog::PHASE_NONE));
608 EXPECT_TRUE(LogContainsEvent(
609 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53610 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46611 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17612 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
613 EXPECT_TRUE(LogContainsEndEvent(
614 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34615}
616
[email protected]5fc08e32009-07-15 17:09:57617TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53618 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20619
[email protected]f6d1d6eb2009-06-24 20:16:09620 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06621 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53622 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
623
[email protected]2431756e2010-09-29 20:26:13624 EXPECT_EQ(OK,
625 handle.Init("a",
626 params_,
627 kDefaultPriority,
628 &callback,
629 pool_.get(),
630 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09631 EXPECT_TRUE(handle.is_initialized());
632 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09633 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30634
[email protected]06650c52010-06-03 00:49:17635 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46636 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53637 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53638 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17639 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
640 NetLog::PHASE_NONE));
641 EXPECT_TRUE(LogContainsEvent(
642 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53643 NetLog::PHASE_NONE));
644 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17645 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09646}
647
[email protected]ab838892009-06-30 18:49:05648TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53649 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20650
[email protected]ab838892009-06-30 18:49:05651 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53652 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
653
[email protected]2431756e2010-09-29 20:26:13654 ClientSocketHandle handle;
655 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18656 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13657 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43658 HttpResponseInfo info;
659 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13660 handle.set_ssl_error_response_info(info);
661 EXPECT_EQ(ERR_CONNECTION_FAILED,
662 handle.Init("a",
663 params_,
664 kDefaultPriority,
665 &callback,
666 pool_.get(),
667 log.bound()));
668 EXPECT_FALSE(handle.socket());
669 EXPECT_FALSE(handle.is_ssl_error());
670 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30671
[email protected]06650c52010-06-03 00:49:17672 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27673 EXPECT_TRUE(LogContainsBeginEvent(
674 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17675 EXPECT_TRUE(LogContainsEvent(
676 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
677 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02678 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17679 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09680}
681
[email protected]211d21722009-07-22 15:48:53682TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
683 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
684
[email protected]9e743cd2010-03-16 07:03:53685 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30686
[email protected]211d21722009-07-22 15:48:53687 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
688 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
689 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
690 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
691
[email protected]2431756e2010-09-29 20:26:13692 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53693 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13694 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53695
696 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
697 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
698 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
699
[email protected]2431756e2010-09-29 20:26:13700 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53701
[email protected]2431756e2010-09-29 20:26:13702 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53703 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13704 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(1, GetOrderOfRequest(1));
707 EXPECT_EQ(2, GetOrderOfRequest(2));
708 EXPECT_EQ(3, GetOrderOfRequest(3));
709 EXPECT_EQ(4, GetOrderOfRequest(4));
710 EXPECT_EQ(5, GetOrderOfRequest(5));
711 EXPECT_EQ(6, GetOrderOfRequest(6));
712 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17713
714 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13715 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53716}
717
718TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
719 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
720
[email protected]9e743cd2010-03-16 07:03:53721 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30722
[email protected]211d21722009-07-22 15:48:53723 // Reach all limits: max total sockets, and max sockets per group.
724 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
725 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
726 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
727 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
728
[email protected]2431756e2010-09-29 20:26:13729 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53730 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13731 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53732
733 // Now create a new group and verify that we don't starve it.
734 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
735
[email protected]2431756e2010-09-29 20:26:13736 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53737
[email protected]2431756e2010-09-29 20:26:13738 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53739 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13740 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53741
742 EXPECT_EQ(1, GetOrderOfRequest(1));
743 EXPECT_EQ(2, GetOrderOfRequest(2));
744 EXPECT_EQ(3, GetOrderOfRequest(3));
745 EXPECT_EQ(4, GetOrderOfRequest(4));
746 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17747
748 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13749 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53750}
751
752TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
753 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
754
[email protected]ac790b42009-12-02 04:31:31755 EXPECT_EQ(OK, StartRequest("b", LOWEST));
756 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
757 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
758 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53759
[email protected]2431756e2010-09-29 20:26:13760 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53761 client_socket_factory_.allocation_count());
762
[email protected]ac790b42009-12-02 04:31:31763 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
764 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
765 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53766
[email protected]2431756e2010-09-29 20:26:13767 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53768
[email protected]2431756e2010-09-29 20:26:13769 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53770
771 // First 4 requests don't have to wait, and finish in order.
772 EXPECT_EQ(1, GetOrderOfRequest(1));
773 EXPECT_EQ(2, GetOrderOfRequest(2));
774 EXPECT_EQ(3, GetOrderOfRequest(3));
775 EXPECT_EQ(4, GetOrderOfRequest(4));
776
[email protected]ac790b42009-12-02 04:31:31777 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
778 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53779 EXPECT_EQ(7, GetOrderOfRequest(5));
780 EXPECT_EQ(6, GetOrderOfRequest(6));
781 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17782
783 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13784 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53785}
786
787TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
788 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
789
[email protected]ac790b42009-12-02 04:31:31790 EXPECT_EQ(OK, StartRequest("a", LOWEST));
791 EXPECT_EQ(OK, StartRequest("a", LOW));
792 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
793 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53794
[email protected]2431756e2010-09-29 20:26:13795 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53796 client_socket_factory_.allocation_count());
797
[email protected]ac790b42009-12-02 04:31:31798 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
799 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
800 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53801
[email protected]2431756e2010-09-29 20:26:13802 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53803
[email protected]2431756e2010-09-29 20:26:13804 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53805 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13806 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53807
808 // First 4 requests don't have to wait, and finish in order.
809 EXPECT_EQ(1, GetOrderOfRequest(1));
810 EXPECT_EQ(2, GetOrderOfRequest(2));
811 EXPECT_EQ(3, GetOrderOfRequest(3));
812 EXPECT_EQ(4, GetOrderOfRequest(4));
813
814 // Request ("b", 7) has the highest priority, but we can't make new socket for
815 // group "b", because it has reached the per-group limit. Then we make
816 // socket for ("c", 6), because it has higher priority than ("a", 4),
817 // and we still can't make a socket for group "b".
818 EXPECT_EQ(5, GetOrderOfRequest(5));
819 EXPECT_EQ(6, GetOrderOfRequest(6));
820 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17821
822 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13823 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53824}
825
826// Make sure that we count connecting sockets against the total limit.
827TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
829
830 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
831 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
832 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
833
834 // Create one asynchronous request.
835 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
836 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
837
[email protected]6b175382009-10-13 06:47:47838 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
839 // actually become pending until 2ms after they have been created. In order
840 // to flush all tasks, we need to wait so that we know there are no
841 // soon-to-be-pending tasks waiting.
842 PlatformThread::Sleep(10);
843 MessageLoop::current()->RunAllPending();
844
[email protected]211d21722009-07-22 15:48:53845 // The next synchronous request should wait for its turn.
846 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
847 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
848
[email protected]2431756e2010-09-29 20:26:13849 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53850
[email protected]2431756e2010-09-29 20:26:13851 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53852 client_socket_factory_.allocation_count());
853
854 EXPECT_EQ(1, GetOrderOfRequest(1));
855 EXPECT_EQ(2, GetOrderOfRequest(2));
856 EXPECT_EQ(3, GetOrderOfRequest(3));
857 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17858 EXPECT_EQ(5, GetOrderOfRequest(5));
859
860 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13861 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53862}
863
[email protected]6427fe22010-04-16 22:27:41864TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
865 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
866 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
867
868 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
869 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
870 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
871 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
872
873 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
874
875 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
876
877 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
878 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
879
880 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
881
[email protected]2431756e2010-09-29 20:26:13882 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41883 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41885 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13886 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
887 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41888 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
889}
890
[email protected]d7027bb2010-05-10 18:58:54891TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
892 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
893 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
894
895 ClientSocketHandle handle;
896 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13897 EXPECT_EQ(ERR_IO_PENDING,
898 handle.Init("a",
899 params_,
900 kDefaultPriority,
901 &callback,
902 pool_.get(),
903 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54904
905 ClientSocketHandle handles[4];
906 for (size_t i = 0; i < arraysize(handles); ++i) {
907 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13908 EXPECT_EQ(ERR_IO_PENDING,
909 handles[i].Init("b",
910 params_,
911 kDefaultPriority,
912 &callback,
913 pool_.get(),
914 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54915 }
916
917 // One will be stalled, cancel all the handles now.
918 // This should hit the OnAvailableSocketSlot() code where we previously had
919 // stalled groups, but no longer have any.
920 for (size_t i = 0; i < arraysize(handles); ++i)
921 handles[i].Reset();
922}
923
[email protected]eb5a99382010-07-11 03:18:26924TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54925 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
926 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
927
[email protected]eb5a99382010-07-11 03:18:26928 {
929 ClientSocketHandle handles[kDefaultMaxSockets];
930 TestCompletionCallback callbacks[kDefaultMaxSockets];
931 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13932 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
933 params_,
[email protected]e83326f2010-07-31 17:29:25934 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13935 &callbacks[i],
936 pool_.get(),
937 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26938 }
939
940 // Force a stalled group.
941 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54942 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13943 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
944 params_,
945 kDefaultPriority,
946 &callback,
947 pool_.get(),
948 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26949
950 // Cancel the stalled request.
951 stalled_handle.Reset();
952
953 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
954 EXPECT_EQ(0, pool_->IdleSocketCount());
955
956 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54957 }
958
[email protected]43a21b82010-06-10 21:30:54959 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
960 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26961}
[email protected]43a21b82010-06-10 21:30:54962
[email protected]eb5a99382010-07-11 03:18:26963TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
964 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
965 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
966
967 {
968 ClientSocketHandle handles[kDefaultMaxSockets];
969 for (int i = 0; i < kDefaultMaxSockets; ++i) {
970 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13971 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
972 params_,
973 kDefaultPriority,
974 &callback,
975 pool_.get(),
976 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26977 }
978
979 // Force a stalled group.
980 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
981 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54982 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13983 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
984 params_,
985 kDefaultPriority,
986 &callback,
987 pool_.get(),
988 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26989
990 // Since it is stalled, it should have no connect jobs.
991 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
992
993 // Cancel the stalled request.
994 handles[0].Reset();
995
[email protected]eb5a99382010-07-11 03:18:26996 // Now we should have a connect job.
997 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
998
999 // The stalled socket should connect.
1000 EXPECT_EQ(OK, callback.WaitForResult());
1001
1002 EXPECT_EQ(kDefaultMaxSockets + 1,
1003 client_socket_factory_.allocation_count());
1004 EXPECT_EQ(0, pool_->IdleSocketCount());
1005 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1006
1007 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541008 }
1009
[email protected]eb5a99382010-07-11 03:18:261010 EXPECT_EQ(1, pool_->IdleSocketCount());
1011}
[email protected]43a21b82010-06-10 21:30:541012
[email protected]eb5a99382010-07-11 03:18:261013TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1014 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1015 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541016
[email protected]eb5a99382010-07-11 03:18:261017 ClientSocketHandle stalled_handle;
1018 TestCompletionCallback callback;
1019 {
1020 ClientSocketHandle handles[kDefaultMaxSockets];
1021 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1022 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061023 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131024 params_,
1025 kDefaultPriority,
1026 &callback,
1027 pool_.get(),
1028 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261029 }
1030
1031 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1032 EXPECT_EQ(0, pool_->IdleSocketCount());
1033
1034 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131035 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1036 params_,
1037 kDefaultPriority,
1038 &callback,
1039 pool_.get(),
1040 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261041
1042 // Dropping out of scope will close all handles and return them to idle.
1043 }
[email protected]43a21b82010-06-10 21:30:541044
1045 // But if we wait for it, the released idle sockets will be closed in
1046 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101047 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261048
1049 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1050 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541051}
1052
1053// Regression test for http://crbug.com/40952.
1054TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221056 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541057 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1058
1059 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1060 ClientSocketHandle handle;
1061 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131062 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1063 params_,
1064 kDefaultPriority,
1065 &callback,
1066 pool_.get(),
1067 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541068 }
1069
1070 // Flush all the DoReleaseSocket tasks.
1071 MessageLoop::current()->RunAllPending();
1072
1073 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1074 // reuse a socket.
1075 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1076 ClientSocketHandle handle;
1077 TestCompletionCallback callback;
1078
1079 // "0" is special here, since it should be the first entry in the sorted map,
1080 // which is the one which we would close an idle socket for. We shouldn't
1081 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131082 EXPECT_EQ(OK, handle.Init("0",
1083 params_,
1084 kDefaultPriority,
1085 &callback,
1086 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211087 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541088
1089 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1090 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1091}
1092
[email protected]ab838892009-06-30 18:49:051093TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531094 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091095
[email protected]c9d6a1d2009-07-14 16:15:201096 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1097 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031098 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311099 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1100 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1101 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1102 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1103 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091104
[email protected]2431756e2010-09-29 20:26:131105 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091106
[email protected]c9d6a1d2009-07-14 16:15:201107 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1108 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131109 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1110 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091111
[email protected]c9d6a1d2009-07-14 16:15:201112 EXPECT_EQ(1, GetOrderOfRequest(1));
1113 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031114 EXPECT_EQ(8, GetOrderOfRequest(3));
1115 EXPECT_EQ(6, GetOrderOfRequest(4));
1116 EXPECT_EQ(4, GetOrderOfRequest(5));
1117 EXPECT_EQ(3, GetOrderOfRequest(6));
1118 EXPECT_EQ(5, GetOrderOfRequest(7));
1119 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171120
1121 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131122 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091123}
1124
[email protected]ab838892009-06-30 18:49:051125TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531126 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]c9d6a1d2009-07-14 16:15:201128 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1129 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311130 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1131 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1132 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1133 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1134 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091135
[email protected]2431756e2010-09-29 20:26:131136 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091137
[email protected]2431756e2010-09-29 20:26:131138 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1139 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201140
[email protected]2431756e2010-09-29 20:26:131141 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201142 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131143 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1144 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091145}
1146
1147// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051148// The pending connect job will be cancelled and should not call back into
1149// ClientSocketPoolBase.
1150TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531151 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201152
[email protected]ab838892009-06-30 18:49:051153 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131154 ClientSocketHandle handle;
1155 TestCompletionCallback callback;
1156 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1157 params_,
1158 kDefaultPriority,
1159 &callback,
1160 pool_.get(),
1161 BoundNetLog()));
1162 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091163}
1164
[email protected]ab838892009-06-30 18:49:051165TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531166 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201167
[email protected]ab838892009-06-30 18:49:051168 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061169 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091170 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091171
[email protected]2431756e2010-09-29 20:26:131172 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1173 params_,
1174 kDefaultPriority,
1175 &callback,
1176 pool_.get(),
1177 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091178
1179 handle.Reset();
1180
1181 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131182 EXPECT_EQ(ERR_IO_PENDING,
1183 handle.Init("a",
1184 params_,
1185 kDefaultPriority,
1186 &callback2,
1187 pool_.get(),
1188 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091189
1190 EXPECT_EQ(OK, callback2.WaitForResult());
1191 EXPECT_FALSE(callback.have_result());
1192
1193 handle.Reset();
1194}
1195
[email protected]ab838892009-06-30 18:49:051196TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531197 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091198
[email protected]c9d6a1d2009-07-14 16:15:201199 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1200 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311201 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1202 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1203 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1204 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1205 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091206
1207 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201208 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131209 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1210 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091211
[email protected]2431756e2010-09-29 20:26:131212 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091213
[email protected]c9d6a1d2009-07-14 16:15:201214 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1215 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131216 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1217 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091218
[email protected]c9d6a1d2009-07-14 16:15:201219 EXPECT_EQ(1, GetOrderOfRequest(1));
1220 EXPECT_EQ(2, GetOrderOfRequest(2));
1221 EXPECT_EQ(5, GetOrderOfRequest(3));
1222 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131223 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1224 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201225 EXPECT_EQ(4, GetOrderOfRequest(6));
1226 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171227
1228 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131229 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091230}
1231
1232class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1233 public:
[email protected]2ab05b52009-07-01 23:57:581234 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241235 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581236 TestConnectJobFactory* test_connect_job_factory,
1237 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091238 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061239 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581240 within_callback_(false),
1241 test_connect_job_factory_(test_connect_job_factory),
1242 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091243
1244 virtual void RunWithParams(const Tuple1<int>& params) {
1245 callback_.RunWithParams(params);
1246 ASSERT_EQ(OK, params.a);
1247
1248 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581249 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111250
1251 // Don't allow reuse of the socket. Disconnect it and then release it and
1252 // run through the MessageLoop once to get it completely released.
1253 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091254 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111255 {
1256 MessageLoop::ScopedNestableTaskAllower nestable(
1257 MessageLoop::current());
1258 MessageLoop::current()->RunAllPending();
1259 }
[email protected]f6d1d6eb2009-06-24 20:16:091260 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471261 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211262 scoped_refptr<TestSocketParams> params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:131263 int rv = handle_->Init("a",
1264 params,
1265 kDefaultPriority,
1266 &next_job_callback,
1267 pool_,
1268 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581269 switch (next_job_type_) {
1270 case TestConnectJob::kMockJob:
1271 EXPECT_EQ(OK, rv);
1272 break;
1273 case TestConnectJob::kMockPendingJob:
1274 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471275
1276 // For pending jobs, wait for new socket to be created. This makes
1277 // sure there are no more pending operations nor any unclosed sockets
1278 // when the test finishes.
1279 // We need to give it a little bit of time to run, so that all the
1280 // operations that happen on timers (e.g. cleanup of idle
1281 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111282 {
1283 MessageLoop::ScopedNestableTaskAllower nestable(
1284 MessageLoop::current());
1285 PlatformThread::Sleep(10);
1286 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1287 }
[email protected]2ab05b52009-07-01 23:57:581288 break;
1289 default:
1290 FAIL() << "Unexpected job type: " << next_job_type_;
1291 break;
1292 }
[email protected]f6d1d6eb2009-06-24 20:16:091293 }
1294 }
1295
1296 int WaitForResult() {
1297 return callback_.WaitForResult();
1298 }
1299
1300 private:
1301 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131302 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091303 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581304 TestConnectJobFactory* const test_connect_job_factory_;
1305 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091306 TestCompletionCallback callback_;
1307};
1308
[email protected]2ab05b52009-07-01 23:57:581309TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531310 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201311
[email protected]0b7648c2009-07-06 20:14:011312 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061313 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581314 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061315 &handle, pool_.get(), connect_job_factory_,
1316 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131317 int rv = handle.Init("a",
1318 params_,
1319 kDefaultPriority,
1320 &callback,
1321 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211322 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091323 ASSERT_EQ(ERR_IO_PENDING, rv);
1324
1325 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581326}
[email protected]f6d1d6eb2009-06-24 20:16:091327
[email protected]2ab05b52009-07-01 23:57:581328TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531329 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201330
[email protected]0b7648c2009-07-06 20:14:011331 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061332 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581333 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061334 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131335 int rv = handle.Init("a",
1336 params_,
1337 kDefaultPriority,
1338 &callback,
1339 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211340 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581341 ASSERT_EQ(ERR_IO_PENDING, rv);
1342
1343 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091344}
1345
1346// Make sure that pending requests get serviced after active requests get
1347// cancelled.
[email protected]ab838892009-06-30 18:49:051348TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531349 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201350
[email protected]0b7648c2009-07-06 20:14:011351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091352
[email protected]c9d6a1d2009-07-14 16:15:201353 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1354 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1355 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1356 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1357 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1358 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1359 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091360
[email protected]c9d6a1d2009-07-14 16:15:201361 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1362 // Let's cancel them.
1363 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131364 ASSERT_FALSE(request(i)->handle()->is_initialized());
1365 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091366 }
1367
[email protected]f6d1d6eb2009-06-24 20:16:091368 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131369 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1370 EXPECT_EQ(OK, request(i)->WaitForResult());
1371 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091372 }
1373
[email protected]2431756e2010-09-29 20:26:131374 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1375 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091376}
1377
1378// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051379TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531380 const size_t kMaxSockets = 5;
1381 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201382
[email protected]0b7648c2009-07-06 20:14:011383 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091384
[email protected]211d21722009-07-22 15:48:531385 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1386 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091387
1388 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531389 for (size_t i = 0; i < kNumberOfRequests; ++i)
1390 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091391
[email protected]211d21722009-07-22 15:48:531392 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131393 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091394}
1395
[email protected]5fc08e32009-07-15 17:09:571396TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531397 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571398
1399 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1400
[email protected]2431756e2010-09-29 20:26:131401 ClientSocketHandle handle;
1402 TestCompletionCallback callback;
1403 int rv = handle.Init("a",
1404 params_,
1405 kDefaultPriority,
1406 &callback,
1407 pool_.get(),
1408 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571409 EXPECT_EQ(ERR_IO_PENDING, rv);
1410
1411 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131412 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571413
[email protected]2431756e2010-09-29 20:26:131414 rv = handle.Init("a",
1415 params_,
1416 kDefaultPriority,
1417 &callback,
1418 pool_.get(),
1419 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571420 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131421 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571422
[email protected]2431756e2010-09-29 20:26:131423 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571424 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1425}
1426
[email protected]2b7523d2009-07-29 20:29:231427// Regression test for http://crbug.com/17985.
1428TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1429 const int kMaxSockets = 3;
1430 const int kMaxSocketsPerGroup = 2;
1431 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1432
[email protected]ac790b42009-12-02 04:31:311433 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231434
1435 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1436 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1437
1438 // This is going to be a pending request in an otherwise empty group.
1439 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1440
1441 // Reach the maximum socket limit.
1442 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1443
1444 // Create a stalled group with high priorities.
1445 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1446 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231447
[email protected]eb5a99382010-07-11 03:18:261448 // Release the first two sockets from "a". Because this is a keepalive,
1449 // the first release will unblock the pending request for "a". The
1450 // second release will unblock a request for "c", becaue it is the next
1451 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131452 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1453 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231454
1455 // Closing idle sockets should not get us into trouble, but in the bug
1456 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411457 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541458 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261459
1460 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231461}
1462
[email protected]4d3b05d2010-01-27 21:27:291463TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531464 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571465
1466 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131467 ClientSocketHandle handle;
1468 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531469 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131470 int rv = handle.Init("a",
1471 params_,
1472 LOWEST,
1473 &callback,
1474 pool_.get(),
1475 log.bound());
[email protected]5fc08e32009-07-15 17:09:571476 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131477 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1478 EXPECT_EQ(OK, callback.WaitForResult());
1479 EXPECT_TRUE(handle.is_initialized());
1480 EXPECT_TRUE(handle.socket());
1481 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301482
[email protected]06650c52010-06-03 00:49:171483 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461484 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531485 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171486 EXPECT_TRUE(LogContainsEvent(
1487 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1488 NetLog::PHASE_NONE));
1489 EXPECT_TRUE(LogContainsEvent(
1490 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1491 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461492 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171493 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571494}
1495
[email protected]4d3b05d2010-01-27 21:27:291496TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571497 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571499
1500 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131501 ClientSocketHandle handle;
1502 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531503 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181504 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131505 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431506 HttpResponseInfo info;
1507 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131508 handle.set_ssl_error_response_info(info);
1509 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1510 params_,
1511 kDefaultPriority,
1512 &callback,
1513 pool_.get(),
1514 log.bound()));
1515 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1516 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1517 EXPECT_FALSE(handle.is_ssl_error());
1518 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301519
[email protected]06650c52010-06-03 00:49:171520 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461521 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531522 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171523 EXPECT_TRUE(LogContainsEvent(
1524 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1525 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321526 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171527 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571528}
1529
[email protected]4d3b05d2010-01-27 21:27:291530TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101531 // TODO(eroman): Add back the log expectations! Removed them because the
1532 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571534
1535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131536 ClientSocketHandle handle;
1537 TestCompletionCallback callback;
1538 ClientSocketHandle handle2;
1539 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571540
[email protected]2431756e2010-09-29 20:26:131541 EXPECT_EQ(ERR_IO_PENDING,
1542 handle.Init("a",
1543 params_,
1544 kDefaultPriority,
1545 &callback,
1546 pool_.get(),
1547 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531548 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131549 EXPECT_EQ(ERR_IO_PENDING,
1550 handle2.Init("a",
1551 params_,
1552 kDefaultPriority,
1553 &callback2,
1554 pool_.get(),
1555 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571556
[email protected]2431756e2010-09-29 20:26:131557 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571558
[email protected]fd7b7c92009-08-20 19:38:301559
1560 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301561
[email protected]2431756e2010-09-29 20:26:131562 EXPECT_EQ(OK, callback2.WaitForResult());
1563 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301564
1565 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531566 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571567}
1568
[email protected]4d3b05d2010-01-27 21:27:291569TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341570 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1571
[email protected]17a0c6c2009-08-04 00:07:041572 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1573
[email protected]ac790b42009-12-02 04:31:311574 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1575 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1576 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1577 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341578
1579 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131580 (*requests())[2]->handle()->Reset();
1581 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341582 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1583
[email protected]2431756e2010-09-29 20:26:131584 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341585 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1586
[email protected]2431756e2010-09-29 20:26:131587 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261588 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341589}
1590
[email protected]5fc08e32009-07-15 17:09:571591// When requests and ConnectJobs are not coupled, the request will get serviced
1592// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291593TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531594 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571595
1596 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571598
[email protected]2431756e2010-09-29 20:26:131599 std::vector<TestSocketRequest*> request_order;
1600 size_t completion_count; // unused
1601 TestSocketRequest req1(&request_order, &completion_count);
1602 int rv = req1.handle()->Init("a",
1603 params_,
1604 kDefaultPriority,
1605 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211606 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571607 EXPECT_EQ(ERR_IO_PENDING, rv);
1608 EXPECT_EQ(OK, req1.WaitForResult());
1609
1610 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1611 // without a job.
1612 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1613
[email protected]2431756e2010-09-29 20:26:131614 TestSocketRequest req2(&request_order, &completion_count);
1615 rv = req2.handle()->Init("a",
1616 params_,
1617 kDefaultPriority,
1618 &req2,
1619 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211620 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571621 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131622 TestSocketRequest req3(&request_order, &completion_count);
1623 rv = req3.handle()->Init("a",
1624 params_,
1625 kDefaultPriority,
1626 &req3,
1627 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211628 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571629 EXPECT_EQ(ERR_IO_PENDING, rv);
1630
1631 // Both Requests 2 and 3 are pending. We release socket 1 which should
1632 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331633 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261634 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331635 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571636 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331637 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571638
1639 // Signal job 2, which should service request 3.
1640
1641 client_socket_factory_.SignalJobs();
1642 EXPECT_EQ(OK, req3.WaitForResult());
1643
[email protected]2431756e2010-09-29 20:26:131644 ASSERT_EQ(3U, request_order.size());
1645 EXPECT_EQ(&req1, request_order[0]);
1646 EXPECT_EQ(&req2, request_order[1]);
1647 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571648 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1649}
1650
1651// The requests are not coupled to the jobs. So, the requests should finish in
1652// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291653TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531654 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571655 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321656 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571657
[email protected]2431756e2010-09-29 20:26:131658 std::vector<TestSocketRequest*> request_order;
1659 size_t completion_count; // unused
1660 TestSocketRequest req1(&request_order, &completion_count);
1661 int rv = req1.handle()->Init("a",
1662 params_,
1663 kDefaultPriority,
1664 &req1,
1665 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211666 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571667 EXPECT_EQ(ERR_IO_PENDING, rv);
1668
[email protected]2431756e2010-09-29 20:26:131669 TestSocketRequest req2(&request_order, &completion_count);
1670 rv = req2.handle()->Init("a",
1671 params_,
1672 kDefaultPriority,
1673 &req2,
1674 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211675 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571676 EXPECT_EQ(ERR_IO_PENDING, rv);
1677
1678 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321679 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571680
[email protected]2431756e2010-09-29 20:26:131681 TestSocketRequest req3(&request_order, &completion_count);
1682 rv = req3.handle()->Init("a",
1683 params_,
1684 kDefaultPriority,
1685 &req3,
1686 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211687 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(ERR_IO_PENDING, rv);
1689
1690 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1691 EXPECT_EQ(OK, req2.WaitForResult());
1692 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1693
[email protected]2431756e2010-09-29 20:26:131694 ASSERT_EQ(3U, request_order.size());
1695 EXPECT_EQ(&req1, request_order[0]);
1696 EXPECT_EQ(&req2, request_order[1]);
1697 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571698}
1699
[email protected]e6ec67b2010-06-16 00:12:461700TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531701 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571702 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321703 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571704
[email protected]2431756e2010-09-29 20:26:131705 ClientSocketHandle handle;
1706 TestCompletionCallback callback;
1707 int rv = handle.Init("a",
1708 params_,
1709 kDefaultPriority,
1710 &callback,
1711 pool_.get(),
1712 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571713 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131714 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571715
1716 MessageLoop::current()->RunAllPending();
1717
[email protected]2431756e2010-09-29 20:26:131718 ClientSocketHandle handle2;
1719 TestCompletionCallback callback2;
1720 rv = handle2.Init("a",
1721 params_,
1722 kDefaultPriority,
1723 &callback2, pool_.get(),
1724 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571725 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131726 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1727 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571728}
1729
[email protected]e772db3f2010-07-12 18:11:131730TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1731 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1732 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1733
[email protected]2431756e2010-09-29 20:26:131734 ClientSocketHandle handle;
1735 TestCompletionCallback callback;
1736 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1737 params_,
1738 kDefaultPriority,
1739 &callback, pool_.get(),
1740 BoundNetLog()));
1741 EXPECT_TRUE(handle.is_initialized());
1742 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131743}
1744
1745TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1746 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1747
1748 connect_job_factory_->set_job_type(
1749 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131750 ClientSocketHandle handle;
1751 TestCompletionCallback callback;
1752 EXPECT_EQ(ERR_IO_PENDING,
1753 handle.Init("a",
1754 params_,
1755 kDefaultPriority,
1756 &callback,
1757 pool_.get(),
1758 BoundNetLog()));
1759 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1760 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1761 EXPECT_TRUE(handle.is_initialized());
1762 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131763}
1764
[email protected]e60e47a2010-07-14 03:37:181765TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1767 connect_job_factory_->set_job_type(
1768 TestConnectJob::kMockAdditionalErrorStateJob);
1769
[email protected]2431756e2010-09-29 20:26:131770 ClientSocketHandle handle;
1771 TestCompletionCallback callback;
1772 EXPECT_EQ(ERR_CONNECTION_FAILED,
1773 handle.Init("a",
1774 params_,
1775 kDefaultPriority,
1776 &callback,
1777 pool_.get(),
1778 BoundNetLog()));
1779 EXPECT_FALSE(handle.is_initialized());
1780 EXPECT_FALSE(handle.socket());
1781 EXPECT_TRUE(handle.is_ssl_error());
1782 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181783}
1784
1785TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1787
1788 connect_job_factory_->set_job_type(
1789 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131790 ClientSocketHandle handle;
1791 TestCompletionCallback callback;
1792 EXPECT_EQ(ERR_IO_PENDING,
1793 handle.Init("a",
1794 params_,
1795 kDefaultPriority,
1796 &callback,
1797 pool_.get(),
1798 BoundNetLog()));
1799 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1800 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1801 EXPECT_FALSE(handle.is_initialized());
1802 EXPECT_FALSE(handle.socket());
1803 EXPECT_TRUE(handle.is_ssl_error());
1804 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181805}
1806
[email protected]4d3b05d2010-01-27 21:27:291807TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161808 CreatePoolWithIdleTimeouts(
1809 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1810 base::TimeDelta(), // Time out unused sockets immediately.
1811 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1812
1813 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1814
1815 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1816
[email protected]2431756e2010-09-29 20:26:131817 ClientSocketHandle handle;
1818 TestCompletionCallback callback;
1819 int rv = handle.Init("a",
1820 params_,
1821 LOWEST,
1822 &callback,
1823 pool_.get(),
1824 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161825 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131826 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161827
[email protected]2431756e2010-09-29 20:26:131828 ClientSocketHandle handle2;
1829 TestCompletionCallback callback2;
1830 rv = handle2.Init("a",
1831 params_,
1832 LOWEST,
1833 &callback2,
1834 pool_.get(),
1835 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161836 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131837 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161838
1839 // Cancel one of the requests. Wait for the other, which will get the first
1840 // job. Release the socket. Run the loop again to make sure the second
1841 // socket is sitting idle and the first one is released (since ReleaseSocket()
1842 // just posts a DoReleaseSocket() task).
1843
[email protected]2431756e2010-09-29 20:26:131844 handle.Reset();
1845 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011846 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131847 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1848 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471849
1850 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1851 // actually become pending until 2ms after they have been created. In order
1852 // to flush all tasks, we need to wait so that we know there are no
1853 // soon-to-be-pending tasks waiting.
1854 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161855 MessageLoop::current()->RunAllPending();
1856
1857 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041858
[email protected]9bf28db2009-08-29 01:35:161859 // Invoke the idle socket cleanup check. Only one socket should be left, the
1860 // used socket. Request it to make sure that it's used.
1861
1862 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531863 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131864 rv = handle.Init("a",
1865 params_,
1866 LOWEST,
1867 &callback,
1868 pool_.get(),
1869 log.bound());
[email protected]9bf28db2009-08-29 01:35:161870 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131871 EXPECT_TRUE(handle.is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151872 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451873 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161874}
1875
[email protected]2041cf342010-02-19 03:15:591876// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161877// because of multiple releasing disconnected sockets.
1878TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1879 CreatePoolWithIdleTimeouts(
1880 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1881 base::TimeDelta(), // Time out unused sockets immediately.
1882 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1883
1884 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1885
1886 // Startup 4 connect jobs. Two of them will be pending.
1887
[email protected]2431756e2010-09-29 20:26:131888 ClientSocketHandle handle;
1889 TestCompletionCallback callback;
1890 int rv = handle.Init("a",
1891 params_,
1892 LOWEST,
1893 &callback,
1894 pool_.get(),
1895 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161896 EXPECT_EQ(OK, rv);
1897
[email protected]2431756e2010-09-29 20:26:131898 ClientSocketHandle handle2;
1899 TestCompletionCallback callback2;
1900 rv = handle2.Init("a",
1901 params_,
1902 LOWEST,
1903 &callback2,
1904 pool_.get(),
1905 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161906 EXPECT_EQ(OK, rv);
1907
[email protected]2431756e2010-09-29 20:26:131908 ClientSocketHandle handle3;
1909 TestCompletionCallback callback3;
1910 rv = handle3.Init("a",
1911 params_,
1912 LOWEST,
1913 &callback3,
1914 pool_.get(),
1915 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161916 EXPECT_EQ(ERR_IO_PENDING, rv);
1917
[email protected]2431756e2010-09-29 20:26:131918 ClientSocketHandle handle4;
1919 TestCompletionCallback callback4;
1920 rv = handle4.Init("a",
1921 params_,
1922 LOWEST,
1923 &callback4,
1924 pool_.get(),
1925 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161926 EXPECT_EQ(ERR_IO_PENDING, rv);
1927
1928 // Release two disconnected sockets.
1929
[email protected]2431756e2010-09-29 20:26:131930 handle.socket()->Disconnect();
1931 handle.Reset();
1932 handle2.socket()->Disconnect();
1933 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161934
[email protected]2431756e2010-09-29 20:26:131935 EXPECT_EQ(OK, callback3.WaitForResult());
1936 EXPECT_FALSE(handle3.is_reused());
1937 EXPECT_EQ(OK, callback4.WaitForResult());
1938 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161939}
1940
[email protected]d7027bb2010-05-10 18:58:541941// Regression test for http://crbug.com/42267.
1942// When DoReleaseSocket() is processed for one socket, it is blocked because the
1943// other stalled groups all have releasing sockets, so no progress can be made.
1944TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1945 CreatePoolWithIdleTimeouts(
1946 4 /* socket limit */, 4 /* socket limit per group */,
1947 base::TimeDelta(), // Time out unused sockets immediately.
1948 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1949
1950 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1951
1952 // Max out the socket limit with 2 per group.
1953
[email protected]2431756e2010-09-29 20:26:131954 ClientSocketHandle handle_a[4];
1955 TestCompletionCallback callback_a[4];
1956 ClientSocketHandle handle_b[4];
1957 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541958
1959 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:131960 EXPECT_EQ(OK, handle_a[i].Init("a",
1961 params_,
1962 LOWEST,
1963 &callback_a[i],
1964 pool_.get(),
1965 BoundNetLog()));
1966 EXPECT_EQ(OK, handle_b[i].Init("b",
1967 params_,
1968 LOWEST,
1969 &callback_b[i],
1970 pool_.get(),
1971 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541972 }
[email protected]b89f7e42010-05-20 20:37:001973
[email protected]d7027bb2010-05-10 18:58:541974 // Make 4 pending requests, 2 per group.
1975
1976 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:131977 EXPECT_EQ(ERR_IO_PENDING,
1978 handle_a[i].Init("a",
1979 params_,
1980 LOWEST,
1981 &callback_a[i],
1982 pool_.get(),
1983 BoundNetLog()));
1984 EXPECT_EQ(ERR_IO_PENDING,
1985 handle_b[i].Init("b",
1986 params_,
1987 LOWEST,
1988 &callback_b[i],
1989 pool_.get(),
1990 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541991 }
1992
1993 // Release b's socket first. The order is important, because in
1994 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1995 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1996 // first, which has a releasing socket, so it refuses to start up another
1997 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:131998 handle_b[0].socket()->Disconnect();
1999 handle_b[0].Reset();
2000 handle_a[0].socket()->Disconnect();
2001 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542002
2003 // Used to get stuck here.
2004 MessageLoop::current()->RunAllPending();
2005
[email protected]2431756e2010-09-29 20:26:132006 handle_b[1].socket()->Disconnect();
2007 handle_b[1].Reset();
2008 handle_a[1].socket()->Disconnect();
2009 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542010
2011 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132012 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2013 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542014 }
2015}
2016
[email protected]fd4fe0b2010-02-08 23:02:152017TEST_F(ClientSocketPoolBaseTest,
2018 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2019 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2020
2021 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2022
2023 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2024 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2025 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2026 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2027
[email protected]2431756e2010-09-29 20:26:132028 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2029 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2030 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152031
2032 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132033 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2034 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152035
[email protected]2431756e2010-09-29 20:26:132036 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2037 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2038 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152039
2040 EXPECT_EQ(1, GetOrderOfRequest(1));
2041 EXPECT_EQ(2, GetOrderOfRequest(2));
2042 EXPECT_EQ(3, GetOrderOfRequest(3));
2043 EXPECT_EQ(4, GetOrderOfRequest(4));
2044
2045 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132046 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152047}
2048
[email protected]4f1e4982010-03-02 18:31:042049class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2050 public:
[email protected]2431756e2010-09-29 20:26:132051 TestReleasingSocketRequest(TestClientSocketPool* pool,
2052 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182053 bool reset_releasing_handle)
2054 : pool_(pool),
2055 expected_result_(expected_result),
2056 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042057
2058 ClientSocketHandle* handle() { return &handle_; }
2059
2060 int WaitForResult() {
2061 return callback_.WaitForResult();
2062 }
2063
2064 virtual void RunWithParams(const Tuple1<int>& params) {
2065 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182066 if (reset_releasing_handle_)
2067 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:212068 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]2431756e2010-09-29 20:26:132069 EXPECT_EQ(expected_result_, handle2_.Init("a",
2070 con_params,
2071 kDefaultPriority,
2072 &callback2_,
2073 pool_,
[email protected]e60e47a2010-07-14 03:37:182074 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042075 }
2076
2077 private:
[email protected]2431756e2010-09-29 20:26:132078 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182079 int expected_result_;
2080 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042081 ClientSocketHandle handle_;
2082 ClientSocketHandle handle2_;
2083 TestCompletionCallback callback_;
2084 TestCompletionCallback callback2_;
2085};
2086
[email protected]e60e47a2010-07-14 03:37:182087
2088TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2089 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2090
2091 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2092 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2093 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2094
[email protected]2431756e2010-09-29 20:26:132095 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182096 client_socket_factory_.allocation_count());
2097
2098 connect_job_factory_->set_job_type(
2099 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2100 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132101 EXPECT_EQ(ERR_IO_PENDING,
2102 req.handle()->Init("a",
2103 params_,
2104 kDefaultPriority,
2105 &req,
2106 pool_.get(),
2107 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182108 // The next job should complete synchronously
2109 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2110
2111 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2112 EXPECT_FALSE(req.handle()->is_initialized());
2113 EXPECT_FALSE(req.handle()->socket());
2114 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432115 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182116}
2117
[email protected]b6501d3d2010-06-03 23:53:342118// http://crbug.com/44724 regression test.
2119// We start releasing the pool when we flush on network change. When that
2120// happens, the only active references are in the ClientSocketHandles. When a
2121// ConnectJob completes and calls back into the last ClientSocketHandle, that
2122// callback can release the last reference and delete the pool. After the
2123// callback finishes, we go back to the stack frame within the now-deleted pool.
2124// Executing any code that refers to members of the now-deleted pool can cause
2125// crashes.
2126TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2127 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2128 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2129
2130 ClientSocketHandle handle;
2131 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132132 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2133 params_,
2134 kDefaultPriority,
2135 &callback,
2136 pool_.get(),
2137 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342138
[email protected]2431756e2010-09-29 20:26:132139 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342140
2141 // We'll call back into this now.
2142 callback.WaitForResult();
2143}
2144
[email protected]a7e38572010-06-07 18:22:242145TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2146 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2147 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2148
2149 ClientSocketHandle handle;
2150 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132151 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2152 params_,
2153 kDefaultPriority,
2154 &callback,
2155 pool_.get(),
2156 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242157 EXPECT_EQ(OK, callback.WaitForResult());
2158 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2159
2160 pool_->Flush();
2161
2162 handle.Reset();
2163 MessageLoop::current()->RunAllPending();
2164
[email protected]2431756e2010-09-29 20:26:132165 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2166 params_,
2167 kDefaultPriority,
2168 &callback,
2169 pool_.get(),
2170 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242171 EXPECT_EQ(OK, callback.WaitForResult());
2172 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2173}
2174
[email protected]06f92462010-08-31 19:24:142175class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2176 public:
2177 ConnectWithinCallback(
2178 const std::string& group_name,
2179 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132180 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142181 : group_name_(group_name), params_(params), pool_(pool) {}
2182
2183 ~ConnectWithinCallback() {}
2184
2185 virtual void RunWithParams(const Tuple1<int>& params) {
2186 callback_.RunWithParams(params);
2187 EXPECT_EQ(ERR_IO_PENDING,
2188 handle_.Init(group_name_,
2189 params_,
2190 kDefaultPriority,
2191 &nested_callback_,
2192 pool_,
2193 BoundNetLog()));
2194 }
2195
2196 int WaitForResult() {
2197 return callback_.WaitForResult();
2198 }
2199
2200 int WaitForNestedResult() {
2201 return nested_callback_.WaitForResult();
2202 }
2203
2204 private:
2205 const std::string group_name_;
2206 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132207 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142208 ClientSocketHandle handle_;
2209 TestCompletionCallback callback_;
2210 TestCompletionCallback nested_callback_;
2211};
2212
2213TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2214 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2215
2216 // First job will be waiting until it gets aborted.
2217 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2218
2219 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132220 ConnectWithinCallback callback("a", params_, pool_.get());
2221 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2222 params_,
2223 kDefaultPriority,
2224 &callback,
2225 pool_.get(),
2226 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142227
2228 // Second job will be started during the first callback, and will
2229 // asynchronously complete with OK.
2230 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2231 pool_->Flush();
2232 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2233 EXPECT_EQ(OK, callback.WaitForNestedResult());
2234}
2235
[email protected]25eea382010-07-10 23:55:262236// Cancel a pending socket request while we're at max sockets,
2237// and verify that the backup socket firing doesn't cause a crash.
2238TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2239 // Max 4 sockets globally, max 4 sockets per group.
2240 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222241 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262242
[email protected]4baaf9d2010-08-31 15:15:442243 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2244 // timer.
[email protected]25eea382010-07-10 23:55:262245 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2246 ClientSocketHandle handle;
2247 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132248 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2249 params_,
2250 kDefaultPriority,
2251 &callback,
2252 pool_.get(),
2253 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262254
2255 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2256 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2257 ClientSocketHandle handles[kDefaultMaxSockets];
2258 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2259 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132260 EXPECT_EQ(OK, handles[i].Init("bar",
2261 params_,
2262 kDefaultPriority,
2263 &callback,
2264 pool_.get(),
2265 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262266 }
2267
2268 MessageLoop::current()->RunAllPending();
2269
2270 // Cancel the pending request.
2271 handle.Reset();
2272
2273 // Wait for the backup timer to fire (add some slop to ensure it fires)
2274 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2275
2276 MessageLoop::current()->RunAllPending();
2277 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2278}
2279
[email protected]3f00be82010-09-27 19:50:022280TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442281 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2282 pool_->EnableConnectBackupJobs();
2283
2284 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2285 // timer.
2286 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2287 ClientSocketHandle handle;
2288 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132289 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2290 params_,
2291 kDefaultPriority,
2292 &callback,
2293 pool_.get(),
2294 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442295 ASSERT_TRUE(pool_->HasGroup("bar"));
2296 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2297
2298 // Cancel the socket request. This should cancel the backup timer. Wait for
2299 // the backup time to see if it indeed got canceled.
2300 handle.Reset();
2301 // Wait for the backup timer to fire (add some slop to ensure it fires)
2302 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2303 MessageLoop::current()->RunAllPending();
2304 ASSERT_TRUE(pool_->HasGroup("bar"));
2305 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2306}
2307
[email protected]3f00be82010-09-27 19:50:022308TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2309 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2310 pool_->EnableConnectBackupJobs();
2311
2312 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2313 // timer.
2314 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2315 ClientSocketHandle handle;
2316 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132317 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2318 params_,
2319 kDefaultPriority,
2320 &callback,
2321 pool_.get(),
2322 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022323 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2324 ClientSocketHandle handle2;
2325 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132326 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2327 params_,
2328 kDefaultPriority,
2329 &callback2,
2330 pool_.get(),
2331 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022332 ASSERT_TRUE(pool_->HasGroup("bar"));
2333 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2334
2335 // Cancel request 1 and then complete request 2. With the requests finished,
2336 // the backup timer should be cancelled.
2337 handle.Reset();
2338 EXPECT_EQ(OK, callback2.WaitForResult());
2339 // Wait for the backup timer to fire (add some slop to ensure it fires)
2340 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2341 MessageLoop::current()->RunAllPending();
2342}
2343
[email protected]eb5a99382010-07-11 03:18:262344// Test delayed socket binding for the case where we have two connects,
2345// and while one is waiting on a connect, the other frees up.
2346// The socket waiting on a connect should switch immediately to the freed
2347// up socket.
2348TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2349 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2350 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2351
2352 ClientSocketHandle handle1;
2353 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132354 EXPECT_EQ(ERR_IO_PENDING,
2355 handle1.Init("a",
2356 params_,
2357 kDefaultPriority,
2358 &callback,
2359 pool_.get(),
2360 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262361 EXPECT_EQ(OK, callback.WaitForResult());
2362
2363 // No idle sockets, no pending jobs.
2364 EXPECT_EQ(0, pool_->IdleSocketCount());
2365 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2366
2367 // Create a second socket to the same host, but this one will wait.
2368 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2369 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132370 EXPECT_EQ(ERR_IO_PENDING,
2371 handle2.Init("a",
2372 params_,
2373 kDefaultPriority,
2374 &callback,
2375 pool_.get(),
2376 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262377 // No idle sockets, and one connecting job.
2378 EXPECT_EQ(0, pool_->IdleSocketCount());
2379 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2380
2381 // Return the first handle to the pool. This will initiate the delayed
2382 // binding.
2383 handle1.Reset();
2384
2385 MessageLoop::current()->RunAllPending();
2386
2387 // Still no idle sockets, still one pending connect job.
2388 EXPECT_EQ(0, pool_->IdleSocketCount());
2389 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2390
2391 // The second socket connected, even though it was a Waiting Job.
2392 EXPECT_EQ(OK, callback.WaitForResult());
2393
2394 // And we can see there is still one job waiting.
2395 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2396
2397 // Finally, signal the waiting Connect.
2398 client_socket_factory_.SignalJobs();
2399 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2400
2401 MessageLoop::current()->RunAllPending();
2402}
2403
2404// Test delayed socket binding when a group is at capacity and one
2405// of the group's sockets frees up.
2406TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2407 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2408 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2409
2410 ClientSocketHandle handle1;
2411 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132412 EXPECT_EQ(ERR_IO_PENDING,
2413 handle1.Init("a",
2414 params_,
2415 kDefaultPriority,
2416 &callback,
2417 pool_.get(),
2418 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262419 EXPECT_EQ(OK, callback.WaitForResult());
2420
2421 // No idle sockets, no pending jobs.
2422 EXPECT_EQ(0, pool_->IdleSocketCount());
2423 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2424
2425 // Create a second socket to the same host, but this one will wait.
2426 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2427 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132428 EXPECT_EQ(ERR_IO_PENDING,
2429 handle2.Init("a",
2430 params_,
2431 kDefaultPriority,
2432 &callback,
2433 pool_.get(),
2434 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262435 // No idle sockets, and one connecting job.
2436 EXPECT_EQ(0, pool_->IdleSocketCount());
2437 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2438
2439 // Return the first handle to the pool. This will initiate the delayed
2440 // binding.
2441 handle1.Reset();
2442
2443 MessageLoop::current()->RunAllPending();
2444
2445 // Still no idle sockets, still one pending connect job.
2446 EXPECT_EQ(0, pool_->IdleSocketCount());
2447 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2448
2449 // The second socket connected, even though it was a Waiting Job.
2450 EXPECT_EQ(OK, callback.WaitForResult());
2451
2452 // And we can see there is still one job waiting.
2453 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2454
2455 // Finally, signal the waiting Connect.
2456 client_socket_factory_.SignalJobs();
2457 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2458
2459 MessageLoop::current()->RunAllPending();
2460}
2461
2462// Test out the case where we have one socket connected, one
2463// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512464// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262465// should complete, by taking the first socket's idle socket.
2466TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2467 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2469
2470 ClientSocketHandle handle1;
2471 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132472 EXPECT_EQ(ERR_IO_PENDING,
2473 handle1.Init("a",
2474 params_,
2475 kDefaultPriority,
2476 &callback,
2477 pool_.get(),
2478 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262479 EXPECT_EQ(OK, callback.WaitForResult());
2480
2481 // No idle sockets, no pending jobs.
2482 EXPECT_EQ(0, pool_->IdleSocketCount());
2483 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2484
2485 // Create a second socket to the same host, but this one will wait.
2486 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2487 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132488 EXPECT_EQ(ERR_IO_PENDING,
2489 handle2.Init("a",
2490 params_,
2491 kDefaultPriority,
2492 &callback,
2493 pool_.get(),
2494 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262495 // No idle sockets, and one connecting job.
2496 EXPECT_EQ(0, pool_->IdleSocketCount());
2497 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2498
2499 // Return the first handle to the pool. This will initiate the delayed
2500 // binding.
2501 handle1.Reset();
2502
2503 MessageLoop::current()->RunAllPending();
2504
2505 // Still no idle sockets, still one pending connect job.
2506 EXPECT_EQ(0, pool_->IdleSocketCount());
2507 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2508
2509 // The second socket connected, even though it was a Waiting Job.
2510 EXPECT_EQ(OK, callback.WaitForResult());
2511
2512 // And we can see there is still one job waiting.
2513 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2514
2515 // Finally, signal the waiting Connect.
2516 client_socket_factory_.SignalJobs();
2517 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2518
2519 MessageLoop::current()->RunAllPending();
2520}
2521
[email protected]2abfe90a2010-08-25 17:49:512522// Cover the case where on an available socket slot, we have one pending
2523// request that completes synchronously, thereby making the Group empty.
2524TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2525 const int kUnlimitedSockets = 100;
2526 const int kOneSocketPerGroup = 1;
2527 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2528
2529 // Make the first request asynchronous fail.
2530 // This will free up a socket slot later.
2531 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2532
2533 ClientSocketHandle handle1;
2534 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132535 EXPECT_EQ(ERR_IO_PENDING,
2536 handle1.Init("a",
2537 params_,
2538 kDefaultPriority,
2539 &callback1,
2540 pool_.get(),
2541 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512542 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2543
2544 // Make the second request synchronously fail. This should make the Group
2545 // empty.
2546 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2547 ClientSocketHandle handle2;
2548 TestCompletionCallback callback2;
2549 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2550 // when created.
[email protected]2431756e2010-09-29 20:26:132551 EXPECT_EQ(ERR_IO_PENDING,
2552 handle2.Init("a",
2553 params_,
2554 kDefaultPriority,
2555 &callback2,
2556 pool_.get(),
2557 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512558
2559 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2560
2561 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2562 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2563 EXPECT_FALSE(pool_->HasGroup("a"));
2564}
2565
[email protected]f6d1d6eb2009-06-24 20:16:092566} // namespace
2567
2568} // namespace net