blob: bc3669d88768123cd2846fd24d0e41f64ba0d048 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]43a21b82010-06-10 21:30:5413#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5314#include "net/base/net_log.h"
15#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3117#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0918#include "net/base/test_completion_callback.h"
19#include "net/socket/client_socket.h"
20#include "net/socket/client_socket_factory.h"
21#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0022#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1723#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0924#include "testing/gtest/include/gtest/gtest.h"
25
26namespace net {
27
28namespace {
29
[email protected]211d21722009-07-22 15:48:5330const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2031const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5232const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0133
[email protected]df4b4ef2010-07-12 18:25:2134class TestSocketParams : public base::RefCounted<TestSocketParams> {
35 private:
36 friend class base::RefCounted<TestSocketParams>;
37 ~TestSocketParams() {}
38};
[email protected]7fc5b09a2010-02-27 00:07:3839typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4940
[email protected]f6d1d6eb2009-06-24 20:16:0941class MockClientSocket : public ClientSocket {
42 public:
43 MockClientSocket() : connected_(false) {}
44
[email protected]ab838892009-06-30 18:49:0545 // Socket methods:
46 virtual int Read(
47 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
48 return ERR_UNEXPECTED;
49 }
50
51 virtual int Write(
52 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53 return ERR_UNEXPECTED;
54 }
[email protected]06650c52010-06-03 00:49:1755 virtual bool SetReceiveBufferSize(int32 size) { return true; }
56 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0557
[email protected]f6d1d6eb2009-06-24 20:16:0958 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0559
[email protected]a2006ece2010-04-23 16:44:0260 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0961 connected_ = true;
62 return OK;
63 }
[email protected]f6d1d6eb2009-06-24 20:16:0964
[email protected]ab838892009-06-30 18:49:0565 virtual void Disconnect() { connected_ = false; }
66 virtual bool IsConnected() const { return connected_; }
67 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0168
[email protected]ac9eec62010-02-20 18:50:3869 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1670 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0971 }
[email protected]f6d1d6eb2009-06-24 20:16:0972
[email protected]a2006ece2010-04-23 16:44:0273 virtual const BoundNetLog& NetLog() const {
74 return net_log_;
75 }
76
[email protected]f6d1d6eb2009-06-24 20:16:0977 private:
78 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0279 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0980
[email protected]ab838892009-06-30 18:49:0581 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0982};
83
[email protected]5fc08e32009-07-15 17:09:5784class TestConnectJob;
85
[email protected]f6d1d6eb2009-06-24 20:16:0986class MockClientSocketFactory : public ClientSocketFactory {
87 public:
[email protected]ab838892009-06-30 18:49:0588 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0989
[email protected]a2006ece2010-04-23 16:44:0290 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
91 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0992 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0593 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0994 }
95
96 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:1897 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:0998 const std::string& hostname,
99 const SSLConfig& ssl_config) {
100 NOTIMPLEMENTED();
101 return NULL;
102 }
103
[email protected]5fc08e32009-07-15 17:09:57104 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
105 void SignalJobs();
106
[email protected]f6d1d6eb2009-06-24 20:16:09107 int allocation_count() const { return allocation_count_; }
108
[email protected]f6d1d6eb2009-06-24 20:16:09109 private:
110 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57111 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09112};
113
[email protected]ab838892009-06-30 18:49:05114class TestConnectJob : public ConnectJob {
115 public:
116 enum JobType {
117 kMockJob,
118 kMockFailingJob,
119 kMockPendingJob,
120 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57121 kMockWaitingJob,
122 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13123 kMockRecoverableJob,
124 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18125 kMockAdditionalErrorStateJob,
126 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05127 };
128
[email protected]994d4932010-07-12 17:55:13129 // The kMockPendingJob uses a slight delay before allowing the connect
130 // to complete.
131 static const int kPendingConnectDelay = 2;
132
[email protected]ab838892009-06-30 18:49:05133 TestConnectJob(JobType job_type,
134 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49135 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34136 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05137 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30138 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17139 NetLog* net_log)
140 : ConnectJob(group_name, timeout_duration, delegate,
141 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58142 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05143 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21144 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18145 load_state_(LOAD_STATE_IDLE),
146 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05147
[email protected]974ebd62009-08-03 23:14:34148 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13149 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34150 }
151
[email protected]46451352009-09-01 14:54:21152 virtual LoadState GetLoadState() const { return load_state_; }
153
[email protected]e60e47a2010-07-14 03:37:18154 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
155 if (store_additional_error_state_) {
156 // Set all of the additional error state fields in some way.
157 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43158 HttpResponseInfo info;
159 info.headers = new HttpResponseHeaders("");
160 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18161 }
162 }
163
[email protected]974ebd62009-08-03 23:14:34164 private:
[email protected]ab838892009-06-30 18:49:05165 // ConnectJob methods:
166
[email protected]974ebd62009-08-03 23:14:34167 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05168 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02169 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40170 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05171 switch (job_type_) {
172 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13173 return DoConnect(true /* successful */, false /* sync */,
174 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05175 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13176 return DoConnect(false /* error */, false /* sync */,
177 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05178 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57179 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47180
181 // Depending on execution timings, posting a delayed task can result
182 // in the task getting executed the at the earliest possible
183 // opportunity or only after returning once from the message loop and
184 // then a second call into the message loop. In order to make behavior
185 // more deterministic, we change the default delay to 2ms. This should
186 // always require us to wait for the second call into the message loop.
187 //
188 // N.B. The correct fix for this and similar timing problems is to
189 // abstract time for the purpose of unittests. Unfortunately, we have
190 // a lot of third-party components that directly call the various
191 // time functions, so this change would be rather invasive.
192 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05193 FROM_HERE,
194 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47195 &TestConnectJob::DoConnect,
196 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13197 true /* async */,
198 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13199 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05200 return ERR_IO_PENDING;
201 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57202 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47203 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 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13208 true /* async */,
209 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47210 2);
[email protected]ab838892009-06-30 18:49:05211 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57212 case kMockWaitingJob:
213 client_socket_factory_->WaitForSignal(this);
214 waiting_success_ = true;
215 return ERR_IO_PENDING;
216 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46217 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57218 FROM_HERE,
219 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46220 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57221 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13222 case kMockRecoverableJob:
223 return DoConnect(false /* error */, false /* sync */,
224 true /* recoverable */);
225 case kMockPendingRecoverableJob:
226 set_load_state(LOAD_STATE_CONNECTING);
227 MessageLoop::current()->PostDelayedTask(
228 FROM_HERE,
229 method_factory_.NewRunnableMethod(
230 &TestConnectJob::DoConnect,
231 false /* error */,
232 true /* async */,
233 true /* recoverable */),
234 2);
235 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18236 case kMockAdditionalErrorStateJob:
237 store_additional_error_state_ = true;
238 return DoConnect(false /* error */, false /* sync */,
239 false /* recoverable */);
240 case kMockPendingAdditionalErrorStateJob:
241 set_load_state(LOAD_STATE_CONNECTING);
242 store_additional_error_state_ = true;
243 MessageLoop::current()->PostDelayedTask(
244 FROM_HERE,
245 method_factory_.NewRunnableMethod(
246 &TestConnectJob::DoConnect,
247 false /* error */,
248 true /* async */,
249 false /* recoverable */),
250 2);
251 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05252 default:
253 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40254 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05255 return ERR_FAILED;
256 }
257 }
258
[email protected]46451352009-09-01 14:54:21259 void set_load_state(LoadState load_state) { load_state_ = load_state; }
260
[email protected]e772db3f2010-07-12 18:11:13261 int DoConnect(bool succeed, bool was_async, bool recoverable) {
262 int result = OK;
[email protected]ab838892009-06-30 18:49:05263 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02264 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13265 } else if (recoverable) {
266 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40267 } else {
[email protected]e772db3f2010-07-12 18:11:13268 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40269 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05270 }
[email protected]2ab05b52009-07-01 23:57:58271
272 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30273 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05274 return result;
275 }
276
[email protected]cfa8228c2010-06-17 01:07:56277 // This function helps simulate the progress of load states on a ConnectJob.
278 // Each time it is called it advances the load state and posts a task to be
279 // called again. It stops at the last connecting load state (the one
280 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57281 void AdvanceLoadState(LoadState state) {
282 int tmp = state;
283 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56284 if (tmp < LOAD_STATE_SENDING_REQUEST) {
285 state = static_cast<LoadState>(tmp);
286 set_load_state(state);
287 MessageLoop::current()->PostTask(
288 FROM_HERE,
289 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
290 state));
291 }
[email protected]5fc08e32009-07-15 17:09:57292 }
293
294 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05295 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57296 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05297 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21298 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18299 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05300
301 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
302};
303
[email protected]d80a4322009-08-14 07:07:49304class TestConnectJobFactory
305 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05306 public:
[email protected]5fc08e32009-07-15 17:09:57307 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05308 : job_type_(TestConnectJob::kMockJob),
309 client_socket_factory_(client_socket_factory) {}
310
311 virtual ~TestConnectJobFactory() {}
312
313 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
314
[email protected]974ebd62009-08-03 23:14:34315 void set_timeout_duration(base::TimeDelta timeout_duration) {
316 timeout_duration_ = timeout_duration;
317 }
318
[email protected]ab838892009-06-30 18:49:05319 // ConnectJobFactory methods:
320
321 virtual ConnectJob* NewConnectJob(
322 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49323 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17324 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05325 return new TestConnectJob(job_type_,
326 group_name,
327 request,
[email protected]974ebd62009-08-03 23:14:34328 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05329 delegate,
[email protected]fd7b7c92009-08-20 19:38:30330 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17331 NULL);
[email protected]ab838892009-06-30 18:49:05332 }
333
[email protected]a796bcec2010-03-22 17:17:26334 virtual base::TimeDelta ConnectionTimeout() const {
335 return timeout_duration_;
336 }
337
[email protected]ab838892009-06-30 18:49:05338 private:
339 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34340 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57341 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05342
343 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
344};
345
346class TestClientSocketPool : public ClientSocketPool {
347 public:
348 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53349 int max_sockets,
[email protected]ab838892009-06-30 18:49:05350 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00351 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16352 base::TimeDelta unused_idle_socket_timeout,
353 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49354 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00355 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16356 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38357 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05358
359 virtual int RequestSocket(
360 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49361 const void* params,
[email protected]ac790b42009-12-02 04:31:31362 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05363 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46364 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53365 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21366 const scoped_refptr<TestSocketParams>* casted_socket_params =
367 static_cast<const scoped_refptr<TestSocketParams>*>(params);
368 return base_.RequestSocket(group_name, *casted_socket_params, priority,
369 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05370 }
371
372 virtual void CancelRequest(
373 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21374 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49375 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05376 }
377
378 virtual void ReleaseSocket(
379 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24380 ClientSocket* socket,
381 int id) {
382 base_.ReleaseSocket(group_name, socket, id);
383 }
384
385 virtual void Flush() {
386 base_.Flush();
[email protected]ab838892009-06-30 18:49:05387 }
388
389 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49390 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05391 }
392
[email protected]d80a4322009-08-14 07:07:49393 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05394
395 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49396 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05397 }
398
399 virtual LoadState GetLoadState(const std::string& group_name,
400 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49401 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05402 }
403
[email protected]a796bcec2010-03-22 17:17:26404 virtual base::TimeDelta ConnectionTimeout() const {
405 return base_.ConnectionTimeout();
406 }
407
[email protected]b89f7e42010-05-20 20:37:00408 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
409 return base_.histograms();
410 }
[email protected]a796bcec2010-03-22 17:17:26411
[email protected]d80a4322009-08-14 07:07:49412 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20413
[email protected]974ebd62009-08-03 23:14:34414 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49415 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34416 }
417
[email protected]9bf28db2009-08-29 01:35:16418 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
419
[email protected]43a21b82010-06-10 21:30:54420 void EnableBackupJobs() { base_.EnableBackupJobs(); }
421
[email protected]ab838892009-06-30 18:49:05422 private:
[email protected]5389bc72009-11-05 23:34:24423 ~TestClientSocketPool() {}
424
[email protected]d80a4322009-08-14 07:07:49425 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05426
427 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
428};
429
[email protected]a937a06d2009-08-19 21:19:24430} // namespace
431
[email protected]7fc5b09a2010-02-27 00:07:38432REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24433
434namespace {
435
[email protected]5fc08e32009-07-15 17:09:57436void MockClientSocketFactory::SignalJobs() {
437 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
438 it != waiting_jobs_.end(); ++it) {
439 (*it)->Signal();
440 }
441 waiting_jobs_.clear();
442}
443
[email protected]974ebd62009-08-03 23:14:34444class TestConnectJobDelegate : public ConnectJob::Delegate {
445 public:
446 TestConnectJobDelegate()
447 : have_result_(false), waiting_for_result_(false), result_(OK) {}
448 virtual ~TestConnectJobDelegate() {}
449
450 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
451 result_ = result;
[email protected]6e713f02009-08-06 02:56:40452 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07453 // socket.get() should be NULL iff result != OK
454 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34455 delete job;
456 have_result_ = true;
457 if (waiting_for_result_)
458 MessageLoop::current()->Quit();
459 }
460
461 int WaitForResult() {
462 DCHECK(!waiting_for_result_);
463 while (!have_result_) {
464 waiting_for_result_ = true;
465 MessageLoop::current()->Run();
466 waiting_for_result_ = false;
467 }
468 have_result_ = false; // auto-reset for next callback
469 return result_;
470 }
471
472 private:
473 bool have_result_;
474 bool waiting_for_result_;
475 int result_;
476};
477
[email protected]75439d3b2009-07-23 22:11:17478class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09479 protected:
[email protected]b89f7e42010-05-20 20:37:00480 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21481 : params_(new TestSocketParams()),
482 histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20483
[email protected]211d21722009-07-22 15:48:53484 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16485 CreatePoolWithIdleTimeouts(
486 max_sockets,
487 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00488 base::TimeDelta::FromSeconds(
489 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16490 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
491 }
492
493 void CreatePoolWithIdleTimeouts(
494 int max_sockets, int max_sockets_per_group,
495 base::TimeDelta unused_idle_socket_timeout,
496 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20497 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04498 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53499 pool_ = new TestClientSocketPool(max_sockets,
500 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00501 histograms_,
[email protected]9bf28db2009-08-29 01:35:16502 unused_idle_socket_timeout,
503 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20504 connect_job_factory_);
505 }
[email protected]f6d1d6eb2009-06-24 20:16:09506
[email protected]ac790b42009-12-02 04:31:31507 int StartRequest(const std::string& group_name,
508 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38509 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]df4b4ef2010-07-12 18:25:21510 pool_, group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09511 }
512
513 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47514 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
515 // actually become pending until 2ms after they have been created. In order
516 // to flush all tasks, we need to wait so that we know there are no
517 // soon-to-be-pending tasks waiting.
518 PlatformThread::Sleep(10);
519 MessageLoop::current()->RunAllPending();
520
[email protected]211d21722009-07-22 15:48:53521 // Need to delete |pool_| before we turn late binding back off. We also need
522 // to delete |requests_| because the pool is reference counted and requests
523 // keep reference to it.
524 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]05ea9ff2010-07-15 19:08:21525 TestClientSocketPool* pool = pool_.get();
[email protected]5fc08e32009-07-15 17:09:57526 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53527 requests_.reset();
[email protected]05ea9ff2010-07-15 19:08:21528 pool = NULL;
[email protected]211d21722009-07-22 15:48:53529
[email protected]75439d3b2009-07-23 22:11:17530 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09531 }
532
[email protected]f6d1d6eb2009-06-24 20:16:09533 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04534 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21535 scoped_refptr<TestSocketParams> params_;
[email protected]c9d6a1d2009-07-14 16:15:20536 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00537 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09538};
539
[email protected]974ebd62009-08-03 23:14:34540// Even though a timeout is specified, it doesn't time out on a synchronous
541// completion.
542TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
543 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06544 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49545 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21546 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34547 scoped_ptr<TestConnectJob> job(
548 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12549 "a",
[email protected]974ebd62009-08-03 23:14:34550 request,
551 base::TimeDelta::FromMicroseconds(1),
552 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30553 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17554 NULL));
[email protected]974ebd62009-08-03 23:14:34555 EXPECT_EQ(OK, job->Connect());
556}
557
558TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
559 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06560 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17561 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53562
[email protected]d80a4322009-08-14 07:07:49563 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21564 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34565 // Deleted by TestConnectJobDelegate.
566 TestConnectJob* job =
567 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12568 "a",
[email protected]974ebd62009-08-03 23:14:34569 request,
570 base::TimeDelta::FromMicroseconds(1),
571 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30572 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17573 &log);
[email protected]974ebd62009-08-03 23:14:34574 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
575 PlatformThread::Sleep(1);
576 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30577
[email protected]06650c52010-06-03 00:49:17578 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46579 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53580 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17581 EXPECT_TRUE(LogContainsBeginEvent(
582 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46583 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17584 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
585 NetLog::PHASE_NONE));
586 EXPECT_TRUE(LogContainsEvent(
587 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53588 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46589 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17590 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
591 EXPECT_TRUE(LogContainsEndEvent(
592 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34593}
594
[email protected]5fc08e32009-07-15 17:09:57595TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53596 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20597
[email protected]f6d1d6eb2009-06-24 20:16:09598 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06599 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53600 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
601
[email protected]df4b4ef2010-07-12 18:25:21602 EXPECT_EQ(OK, handle.Init("a", params_, kDefaultPriority, &callback, pool_,
603 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09604 EXPECT_TRUE(handle.is_initialized());
605 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09606 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30607
[email protected]06650c52010-06-03 00:49:17608 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46609 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53610 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53611 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17612 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
613 NetLog::PHASE_NONE));
614 EXPECT_TRUE(LogContainsEvent(
615 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53616 NetLog::PHASE_NONE));
617 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17618 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09619}
620
[email protected]ab838892009-06-30 18:49:05621TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53622 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20623
[email protected]ab838892009-06-30 18:49:05624 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53625 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
626
[email protected]a512f5982009-08-18 16:01:06627 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]e60e47a2010-07-14 03:37:18628 // Set the additional error state members to ensure that they get cleared.
629 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43630 HttpResponseInfo info;
631 info.headers = new HttpResponseHeaders("");
632 req.handle()->set_ssl_error_response_info(info);
[email protected]df4b4ef2010-07-12 18:25:21633 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
634 kDefaultPriority, &req,
635 pool_, log.bound()));
[email protected]e772db3f2010-07-12 18:11:13636 EXPECT_FALSE(req.handle()->socket());
[email protected]e60e47a2010-07-14 03:37:18637 EXPECT_FALSE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:43638 EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30639
[email protected]06650c52010-06-03 00:49:17640 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27641 EXPECT_TRUE(LogContainsBeginEvent(
642 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17643 EXPECT_TRUE(LogContainsEvent(
644 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
645 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02646 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17647 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09648}
649
[email protected]211d21722009-07-22 15:48:53650TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
651 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
652
[email protected]9e743cd2010-03-16 07:03:53653 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30654
[email protected]211d21722009-07-22 15:48:53655 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
656 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
657 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
658 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
659
660 EXPECT_EQ(static_cast<int>(requests_.size()),
661 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17662 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53663
664 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
666 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
667
[email protected]43a21b82010-06-10 21:30:54668 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53669
670 EXPECT_EQ(static_cast<int>(requests_.size()),
671 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17672 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53673
674 EXPECT_EQ(1, GetOrderOfRequest(1));
675 EXPECT_EQ(2, GetOrderOfRequest(2));
676 EXPECT_EQ(3, GetOrderOfRequest(3));
677 EXPECT_EQ(4, GetOrderOfRequest(4));
678 EXPECT_EQ(5, GetOrderOfRequest(5));
679 EXPECT_EQ(6, GetOrderOfRequest(6));
680 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17681
682 // Make sure we test order of all requests made.
683 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53684}
685
686TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
687 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
688
[email protected]9e743cd2010-03-16 07:03:53689 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30690
[email protected]211d21722009-07-22 15:48:53691 // Reach all limits: max total sockets, and max sockets per group.
692 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
693 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
694 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
695 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
696
697 EXPECT_EQ(static_cast<int>(requests_.size()),
698 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17699 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53700
701 // Now create a new group and verify that we don't starve it.
702 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
703
[email protected]43a21b82010-06-10 21:30:54704 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(static_cast<int>(requests_.size()),
707 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17708 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53709
710 EXPECT_EQ(1, GetOrderOfRequest(1));
711 EXPECT_EQ(2, GetOrderOfRequest(2));
712 EXPECT_EQ(3, GetOrderOfRequest(3));
713 EXPECT_EQ(4, GetOrderOfRequest(4));
714 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17715
716 // Make sure we test order of all requests made.
717 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53718}
719
720TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
722
[email protected]ac790b42009-12-02 04:31:31723 EXPECT_EQ(OK, StartRequest("b", LOWEST));
724 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
725 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
726 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53727
728 EXPECT_EQ(static_cast<int>(requests_.size()),
729 client_socket_factory_.allocation_count());
730
[email protected]ac790b42009-12-02 04:31:31731 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
732 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
733 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53734
[email protected]43a21b82010-06-10 21:30:54735 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53736
[email protected]75439d3b2009-07-23 22:11:17737 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53738
739 // First 4 requests don't have to wait, and finish in order.
740 EXPECT_EQ(1, GetOrderOfRequest(1));
741 EXPECT_EQ(2, GetOrderOfRequest(2));
742 EXPECT_EQ(3, GetOrderOfRequest(3));
743 EXPECT_EQ(4, GetOrderOfRequest(4));
744
[email protected]ac790b42009-12-02 04:31:31745 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
746 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53747 EXPECT_EQ(7, GetOrderOfRequest(5));
748 EXPECT_EQ(6, GetOrderOfRequest(6));
749 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17750
751 // Make sure we test order of all requests made.
[email protected]c9c6f5c2010-07-31 01:30:03752 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53753}
754
755TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
756 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
757
[email protected]ac790b42009-12-02 04:31:31758 EXPECT_EQ(OK, StartRequest("a", LOWEST));
759 EXPECT_EQ(OK, StartRequest("a", LOW));
760 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
761 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53762
763 EXPECT_EQ(static_cast<int>(requests_.size()),
764 client_socket_factory_.allocation_count());
765
[email protected]ac790b42009-12-02 04:31:31766 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
767 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
768 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53769
[email protected]43a21b82010-06-10 21:30:54770 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53771
[email protected]43a21b82010-06-10 21:30:54772 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53773 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17774 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53775
776 // First 4 requests don't have to wait, and finish in order.
777 EXPECT_EQ(1, GetOrderOfRequest(1));
778 EXPECT_EQ(2, GetOrderOfRequest(2));
779 EXPECT_EQ(3, GetOrderOfRequest(3));
780 EXPECT_EQ(4, GetOrderOfRequest(4));
781
782 // Request ("b", 7) has the highest priority, but we can't make new socket for
783 // group "b", because it has reached the per-group limit. Then we make
784 // socket for ("c", 6), because it has higher priority than ("a", 4),
785 // and we still can't make a socket for group "b".
786 EXPECT_EQ(5, GetOrderOfRequest(5));
787 EXPECT_EQ(6, GetOrderOfRequest(6));
788 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17789
790 // Make sure we test order of all requests made.
791 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53792}
793
794// Make sure that we count connecting sockets against the total limit.
795TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
797
798 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
799 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
800 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
801
802 // Create one asynchronous request.
803 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
805
[email protected]6b175382009-10-13 06:47:47806 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
807 // actually become pending until 2ms after they have been created. In order
808 // to flush all tasks, we need to wait so that we know there are no
809 // soon-to-be-pending tasks waiting.
810 PlatformThread::Sleep(10);
811 MessageLoop::current()->RunAllPending();
812
[email protected]211d21722009-07-22 15:48:53813 // The next synchronous request should wait for its turn.
814 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
815 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
816
[email protected]43a21b82010-06-10 21:30:54817 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53818
819 EXPECT_EQ(static_cast<int>(requests_.size()),
820 client_socket_factory_.allocation_count());
821
822 EXPECT_EQ(1, GetOrderOfRequest(1));
823 EXPECT_EQ(2, GetOrderOfRequest(2));
824 EXPECT_EQ(3, GetOrderOfRequest(3));
825 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17826 EXPECT_EQ(5, GetOrderOfRequest(5));
827
828 // Make sure we test order of all requests made.
829 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53830}
831
[email protected]6427fe22010-04-16 22:27:41832TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
833 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
834 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
835
836 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
837 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
838 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
839 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
840
841 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
842
843 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
844
845 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
846 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
847
848 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
849
850 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
851 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
852 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
853 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
854 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
855 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
856 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
857}
858
[email protected]d7027bb2010-05-10 18:58:54859TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
860 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
861 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
862
863 ClientSocketHandle handle;
864 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21865 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
866 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54867
868 ClientSocketHandle handles[4];
869 for (size_t i = 0; i < arraysize(handles); ++i) {
870 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21871 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init("b", params_, kDefaultPriority,
872 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54873 }
874
875 // One will be stalled, cancel all the handles now.
876 // This should hit the OnAvailableSocketSlot() code where we previously had
877 // stalled groups, but no longer have any.
878 for (size_t i = 0; i < arraysize(handles); ++i)
879 handles[i].Reset();
880}
881
[email protected]eb5a99382010-07-11 03:18:26882TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54883 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
884 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
885
[email protected]eb5a99382010-07-11 03:18:26886 {
887 ClientSocketHandle handles[kDefaultMaxSockets];
888 TestCompletionCallback callbacks[kDefaultMaxSockets];
889 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]df4b4ef2010-07-12 18:25:21890 EXPECT_EQ(OK, handles[i].Init(IntToString(i), params_, kDefaultPriority,
891 &callbacks[i], pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26892 }
893
894 // Force a stalled group.
895 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54896 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21897 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
898 kDefaultPriority, &callback,
899 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26900
901 // Cancel the stalled request.
902 stalled_handle.Reset();
903
904 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
905 EXPECT_EQ(0, pool_->IdleSocketCount());
906
907 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54908 }
909
[email protected]43a21b82010-06-10 21:30:54910 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
911 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26912}
[email protected]43a21b82010-06-10 21:30:54913
[email protected]eb5a99382010-07-11 03:18:26914TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
916 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
917
918 {
919 ClientSocketHandle handles[kDefaultMaxSockets];
920 for (int i = 0; i < kDefaultMaxSockets; ++i) {
921 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21922 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(IntToString(i), params_,
923 kDefaultPriority, &callback,
924 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26925 }
926
927 // Force a stalled group.
928 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
929 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54930 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21931 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
932 kDefaultPriority, &callback,
933 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26934
935 // Since it is stalled, it should have no connect jobs.
936 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
937
938 // Cancel the stalled request.
939 handles[0].Reset();
940
[email protected]eb5a99382010-07-11 03:18:26941 // Now we should have a connect job.
942 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
943
944 // The stalled socket should connect.
945 EXPECT_EQ(OK, callback.WaitForResult());
946
947 EXPECT_EQ(kDefaultMaxSockets + 1,
948 client_socket_factory_.allocation_count());
949 EXPECT_EQ(0, pool_->IdleSocketCount());
950 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
951
952 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54953 }
954
[email protected]eb5a99382010-07-11 03:18:26955 EXPECT_EQ(1, pool_->IdleSocketCount());
956}
[email protected]43a21b82010-06-10 21:30:54957
[email protected]eb5a99382010-07-11 03:18:26958TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
959 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
960 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54961
[email protected]eb5a99382010-07-11 03:18:26962 ClientSocketHandle stalled_handle;
963 TestCompletionCallback callback;
964 {
965 ClientSocketHandle handles[kDefaultMaxSockets];
966 for (int i = 0; i < kDefaultMaxSockets; ++i) {
967 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21968 EXPECT_EQ(OK, handles[i].Init(StringPrintf("Take 2: %d", i), params_,
969 kDefaultPriority, &callback, pool_,
970 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26971 }
972
973 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
974 EXPECT_EQ(0, pool_->IdleSocketCount());
975
976 // Now we will hit the socket limit.
[email protected]df4b4ef2010-07-12 18:25:21977 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
978 kDefaultPriority, &callback,
979 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26980
981 // Dropping out of scope will close all handles and return them to idle.
982 }
[email protected]43a21b82010-06-10 21:30:54983
984 // But if we wait for it, the released idle sockets will be closed in
985 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:10986 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:26987
988 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
989 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54990}
991
992// Regression test for http://crbug.com/40952.
993TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
994 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
995 pool_->EnableBackupJobs();
996 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
997
998 for (int i = 0; i < kDefaultMaxSockets; ++i) {
999 ClientSocketHandle handle;
1000 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211001 EXPECT_EQ(OK, handle.Init(IntToString(i), params_, kDefaultPriority,
1002 &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541003 }
1004
1005 // Flush all the DoReleaseSocket tasks.
1006 MessageLoop::current()->RunAllPending();
1007
1008 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1009 // reuse a socket.
1010 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1011 ClientSocketHandle handle;
1012 TestCompletionCallback callback;
1013
1014 // "0" is special here, since it should be the first entry in the sorted map,
1015 // which is the one which we would close an idle socket for. We shouldn't
1016 // close an idle socket though, since we should reuse the idle socket.
[email protected]df4b4ef2010-07-12 18:25:211017 EXPECT_EQ(OK, handle.Init("0", params_, kDefaultPriority, &callback, pool_,
1018 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541019
1020 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1021 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1022}
1023
[email protected]ab838892009-06-30 18:49:051024TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531025 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091026
[email protected]c9d6a1d2009-07-14 16:15:201027 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1028 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031029 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311030 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1031 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1032 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1033 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1034 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091035
[email protected]c9d6a1d2009-07-14 16:15:201036 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091037
[email protected]c9d6a1d2009-07-14 16:15:201038 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1039 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171040 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091041
[email protected]c9d6a1d2009-07-14 16:15:201042 EXPECT_EQ(1, GetOrderOfRequest(1));
1043 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031044 EXPECT_EQ(8, GetOrderOfRequest(3));
1045 EXPECT_EQ(6, GetOrderOfRequest(4));
1046 EXPECT_EQ(4, GetOrderOfRequest(5));
1047 EXPECT_EQ(3, GetOrderOfRequest(6));
1048 EXPECT_EQ(5, GetOrderOfRequest(7));
1049 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171050
1051 // Make sure we test order of all requests made.
[email protected]c9c6f5c2010-07-31 01:30:031052 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091053}
1054
[email protected]ab838892009-06-30 18:49:051055TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531056 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091057
[email protected]c9d6a1d2009-07-14 16:15:201058 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1059 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1063 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1064 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091065
[email protected]c9d6a1d2009-07-14 16:15:201066 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091067
[email protected]c9d6a1d2009-07-14 16:15:201068 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1069 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1070
1071 EXPECT_EQ(static_cast<int>(requests_.size()),
1072 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171073 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091074}
1075
1076// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051077// The pending connect job will be cancelled and should not call back into
1078// ClientSocketPoolBase.
1079TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531080 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201081
[email protected]ab838892009-06-30 18:49:051082 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061083 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211084 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1085 &req, pool_, BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331086 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091087}
1088
[email protected]ab838892009-06-30 18:49:051089TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531090 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201091
[email protected]ab838892009-06-30 18:49:051092 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061093 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091094 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061095 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091096
[email protected]df4b4ef2010-07-12 18:25:211097 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1098 &callback, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091099
1100 handle.Reset();
1101
1102 TestCompletionCallback callback2;
[email protected]df4b4ef2010-07-12 18:25:211103 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1104 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091105
1106 EXPECT_EQ(OK, callback2.WaitForResult());
1107 EXPECT_FALSE(callback.have_result());
1108
1109 handle.Reset();
1110}
1111
[email protected]ab838892009-06-30 18:49:051112TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531113 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091114
[email protected]c9d6a1d2009-07-14 16:15:201115 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1116 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311117 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1118 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1120 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1121 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091122
1123 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201124 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331125 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1126 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]c9d6a1d2009-07-14 16:15:201128 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091129
[email protected]c9d6a1d2009-07-14 16:15:201130 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1131 client_socket_factory_.allocation_count());
1132 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171133 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091134
[email protected]c9d6a1d2009-07-14 16:15:201135 EXPECT_EQ(1, GetOrderOfRequest(1));
1136 EXPECT_EQ(2, GetOrderOfRequest(2));
1137 EXPECT_EQ(5, GetOrderOfRequest(3));
1138 EXPECT_EQ(3, GetOrderOfRequest(4));
1139 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1140 EXPECT_EQ(4, GetOrderOfRequest(6));
1141 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171142
1143 // Make sure we test order of all requests made.
1144 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091145}
1146
1147class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1148 public:
[email protected]2ab05b52009-07-01 23:57:581149 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241150 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581151 TestConnectJobFactory* test_connect_job_factory,
1152 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091153 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061154 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581155 within_callback_(false),
1156 test_connect_job_factory_(test_connect_job_factory),
1157 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091158
1159 virtual void RunWithParams(const Tuple1<int>& params) {
1160 callback_.RunWithParams(params);
1161 ASSERT_EQ(OK, params.a);
1162
1163 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581164 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111165
1166 // Don't allow reuse of the socket. Disconnect it and then release it and
1167 // run through the MessageLoop once to get it completely released.
1168 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091169 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111170 {
1171 MessageLoop::ScopedNestableTaskAllower nestable(
1172 MessageLoop::current());
1173 MessageLoop::current()->RunAllPending();
1174 }
[email protected]f6d1d6eb2009-06-24 20:16:091175 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471176 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211177 scoped_refptr<TestSocketParams> params = new TestSocketParams();
1178 int rv = handle_->Init("a", params, kDefaultPriority, &next_job_callback,
1179 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581180 switch (next_job_type_) {
1181 case TestConnectJob::kMockJob:
1182 EXPECT_EQ(OK, rv);
1183 break;
1184 case TestConnectJob::kMockPendingJob:
1185 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471186
1187 // For pending jobs, wait for new socket to be created. This makes
1188 // sure there are no more pending operations nor any unclosed sockets
1189 // when the test finishes.
1190 // We need to give it a little bit of time to run, so that all the
1191 // operations that happen on timers (e.g. cleanup of idle
1192 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111193 {
1194 MessageLoop::ScopedNestableTaskAllower nestable(
1195 MessageLoop::current());
1196 PlatformThread::Sleep(10);
1197 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1198 }
[email protected]2ab05b52009-07-01 23:57:581199 break;
1200 default:
1201 FAIL() << "Unexpected job type: " << next_job_type_;
1202 break;
1203 }
[email protected]f6d1d6eb2009-06-24 20:16:091204 }
1205 }
1206
1207 int WaitForResult() {
1208 return callback_.WaitForResult();
1209 }
1210
1211 private:
1212 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241213 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091214 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581215 TestConnectJobFactory* const test_connect_job_factory_;
1216 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091217 TestCompletionCallback callback_;
1218};
1219
[email protected]2ab05b52009-07-01 23:57:581220TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531221 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201222
[email protected]0b7648c2009-07-06 20:14:011223 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061224 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581225 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061226 &handle, pool_.get(), connect_job_factory_,
1227 TestConnectJob::kMockPendingJob);
[email protected]df4b4ef2010-07-12 18:25:211228 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1229 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091230 ASSERT_EQ(ERR_IO_PENDING, rv);
1231
1232 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581233}
[email protected]f6d1d6eb2009-06-24 20:16:091234
[email protected]2ab05b52009-07-01 23:57:581235TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201237
[email protected]0b7648c2009-07-06 20:14:011238 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061239 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581240 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061241 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]df4b4ef2010-07-12 18:25:211242 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1243 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581244 ASSERT_EQ(ERR_IO_PENDING, rv);
1245
1246 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091247}
1248
1249// Make sure that pending requests get serviced after active requests get
1250// cancelled.
[email protected]ab838892009-06-30 18:49:051251TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531252 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201253
[email protected]0b7648c2009-07-06 20:14:011254 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091255
[email protected]c9d6a1d2009-07-14 16:15:201256 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1257 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1258 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1259 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1260 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1261 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1262 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091263
[email protected]c9d6a1d2009-07-14 16:15:201264 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1265 // Let's cancel them.
1266 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331267 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1268 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091269 }
1270
[email protected]f6d1d6eb2009-06-24 20:16:091271 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201272 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1273 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331274 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091275 }
1276
[email protected]75439d3b2009-07-23 22:11:171277 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091278}
1279
1280// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051281TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531282 const size_t kMaxSockets = 5;
1283 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201284
[email protected]0b7648c2009-07-06 20:14:011285 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091286
[email protected]211d21722009-07-22 15:48:531287 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1288 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091289
1290 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531291 for (size_t i = 0; i < kNumberOfRequests; ++i)
1292 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091293
[email protected]211d21722009-07-22 15:48:531294 for (size_t i = 0; i < kNumberOfRequests; ++i)
1295 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091296}
1297
[email protected]5fc08e32009-07-15 17:09:571298TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531299 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571300
1301 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1302
[email protected]a512f5982009-08-18 16:01:061303 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211304 int rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1305 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571306 EXPECT_EQ(ERR_IO_PENDING, rv);
1307
1308 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331309 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571310
[email protected]df4b4ef2010-07-12 18:25:211311 rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1312 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571313 EXPECT_EQ(ERR_IO_PENDING, rv);
1314 EXPECT_EQ(OK, req.WaitForResult());
1315
[email protected]a6c59f62009-07-29 16:33:331316 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171317 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571318 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1319}
1320
[email protected]2b7523d2009-07-29 20:29:231321// Regression test for http://crbug.com/17985.
1322TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1323 const int kMaxSockets = 3;
1324 const int kMaxSocketsPerGroup = 2;
1325 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1326
[email protected]ac790b42009-12-02 04:31:311327 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231328
1329 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1330 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1331
1332 // This is going to be a pending request in an otherwise empty group.
1333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1334
1335 // Reach the maximum socket limit.
1336 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1337
1338 // Create a stalled group with high priorities.
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1340 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231341
[email protected]eb5a99382010-07-11 03:18:261342 // Release the first two sockets from "a". Because this is a keepalive,
1343 // the first release will unblock the pending request for "a". The
1344 // second release will unblock a request for "c", becaue it is the next
1345 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231346 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1347 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1348
1349 // Closing idle sockets should not get us into trouble, but in the bug
1350 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411351 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541352 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261353
1354 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231355}
1356
[email protected]4d3b05d2010-01-27 21:27:291357TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571359
1360 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061361 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531362 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211363 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571364 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331365 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571366 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331367 EXPECT_TRUE(req.handle()->is_initialized());
1368 EXPECT_TRUE(req.handle()->socket());
1369 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301370
[email protected]06650c52010-06-03 00:49:171371 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461372 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531373 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171374 EXPECT_TRUE(LogContainsEvent(
1375 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1376 NetLog::PHASE_NONE));
1377 EXPECT_TRUE(LogContainsEvent(
1378 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1379 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461380 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171381 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571382}
1383
[email protected]4d3b05d2010-01-27 21:27:291384TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571385 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531386 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571387
1388 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061389 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531390 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181391 // Set the additional error state members to ensure that they get cleared.
1392 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431393 HttpResponseInfo info;
1394 info.headers = new HttpResponseHeaders("");
1395 req.handle()->set_ssl_error_response_info(info);
[email protected]df4b4ef2010-07-12 18:25:211396 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1397 &req, pool_, log.bound()));
[email protected]a6c59f62009-07-29 16:33:331398 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571399 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]e60e47a2010-07-14 03:37:181400 EXPECT_FALSE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431401 EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301402
[email protected]06650c52010-06-03 00:49:171403 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461404 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531405 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171406 EXPECT_TRUE(LogContainsEvent(
1407 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1408 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321409 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171410 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571411}
1412
[email protected]4d3b05d2010-01-27 21:27:291413TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101414 // TODO(eroman): Add back the log expectations! Removed them because the
1415 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531416 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571417
1418 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061419 TestSocketRequest req(&request_order_, &completion_count_);
1420 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571421
[email protected]df4b4ef2010-07-12 18:25:211422 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1423 &req, pool_, BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531424 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211425 EXPECT_EQ(ERR_IO_PENDING, req2.handle()->Init("a", params_, kDefaultPriority,
1426 &req2, pool_, BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571427
[email protected]a6c59f62009-07-29 16:33:331428 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571429
[email protected]fd7b7c92009-08-20 19:38:301430
1431 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301432
[email protected]5fc08e32009-07-15 17:09:571433 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331434 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301435
1436 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531437 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571438}
1439
[email protected]4d3b05d2010-01-27 21:27:291440TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341441 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1442
[email protected]17a0c6c2009-08-04 00:07:041443 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1444
[email protected]ac790b42009-12-02 04:31:311445 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1446 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1447 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1448 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341449
1450 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1451 requests_[2]->handle()->Reset();
1452 requests_[3]->handle()->Reset();
1453 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1454
1455 requests_[1]->handle()->Reset();
1456 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1457
1458 requests_[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261459 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341460}
1461
[email protected]5fc08e32009-07-15 17:09:571462// When requests and ConnectJobs are not coupled, the request will get serviced
1463// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291464TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531465 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571466
1467 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571469
[email protected]a512f5982009-08-18 16:01:061470 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211471 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1472 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571473 EXPECT_EQ(ERR_IO_PENDING, rv);
1474 EXPECT_EQ(OK, req1.WaitForResult());
1475
1476 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1477 // without a job.
1478 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1479
[email protected]a512f5982009-08-18 16:01:061480 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211481 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1482 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571483 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061484 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211485 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1486 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571487 EXPECT_EQ(ERR_IO_PENDING, rv);
1488
1489 // Both Requests 2 and 3 are pending. We release socket 1 which should
1490 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331491 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261492 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331493 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571494 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331495 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571496
1497 // Signal job 2, which should service request 3.
1498
1499 client_socket_factory_.SignalJobs();
1500 EXPECT_EQ(OK, req3.WaitForResult());
1501
1502 ASSERT_EQ(3U, request_order_.size());
1503 EXPECT_EQ(&req1, request_order_[0]);
1504 EXPECT_EQ(&req2, request_order_[1]);
1505 EXPECT_EQ(&req3, request_order_[2]);
1506 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1507}
1508
1509// The requests are not coupled to the jobs. So, the requests should finish in
1510// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291511TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571513 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321514 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571515
[email protected]a512f5982009-08-18 16:01:061516 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211517 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1518 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571519 EXPECT_EQ(ERR_IO_PENDING, rv);
1520
[email protected]a512f5982009-08-18 16:01:061521 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211522 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1523 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571524 EXPECT_EQ(ERR_IO_PENDING, rv);
1525
1526 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321527 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571528
[email protected]a512f5982009-08-18 16:01:061529 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211530 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1531 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571532 EXPECT_EQ(ERR_IO_PENDING, rv);
1533
1534 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1535 EXPECT_EQ(OK, req2.WaitForResult());
1536 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1537
1538 ASSERT_EQ(3U, request_order_.size());
1539 EXPECT_EQ(&req1, request_order_[0]);
1540 EXPECT_EQ(&req2, request_order_[1]);
1541 EXPECT_EQ(&req3, request_order_[2]);
1542}
1543
[email protected]e6ec67b2010-06-16 00:12:461544TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531545 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571546 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321547 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571548
[email protected]a512f5982009-08-18 16:01:061549 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211550 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1551 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571552 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331553 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571554
1555 MessageLoop::current()->RunAllPending();
1556
[email protected]a512f5982009-08-18 16:01:061557 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211558 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1559 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571560 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561561 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1562 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571563}
1564
[email protected]e772db3f2010-07-12 18:11:131565TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1566 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1567 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1568
1569 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211570 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.handle()->Init("a", params_,
1571 kDefaultPriority,
1572 &req, pool_,
1573 BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131574 EXPECT_TRUE(req.handle()->is_initialized());
1575 EXPECT_TRUE(req.handle()->socket());
1576 req.handle()->Reset();
1577}
1578
1579TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1580 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1581
1582 connect_job_factory_->set_job_type(
1583 TestConnectJob::kMockPendingRecoverableJob);
1584 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211585 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1586 &req, pool_, BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131587 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1588 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult());
1589 EXPECT_TRUE(req.handle()->is_initialized());
1590 EXPECT_TRUE(req.handle()->socket());
1591 req.handle()->Reset();
1592}
1593
[email protected]e60e47a2010-07-14 03:37:181594TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1595 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1596 connect_job_factory_->set_job_type(
1597 TestConnectJob::kMockAdditionalErrorStateJob);
1598
1599 TestSocketRequest req(&request_order_, &completion_count_);
1600 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
1601 kDefaultPriority, &req,
1602 pool_, BoundNetLog()));
1603 EXPECT_FALSE(req.handle()->is_initialized());
1604 EXPECT_FALSE(req.handle()->socket());
1605 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431606 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181607 req.handle()->Reset();
1608}
1609
1610TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1611 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1612
1613 connect_job_factory_->set_job_type(
1614 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1615 TestSocketRequest req(&request_order_, &completion_count_);
1616 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1617 &req, pool_, BoundNetLog()));
1618 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1619 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1620 EXPECT_FALSE(req.handle()->is_initialized());
1621 EXPECT_FALSE(req.handle()->socket());
1622 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431623 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181624 req.handle()->Reset();
1625}
1626
[email protected]4d3b05d2010-01-27 21:27:291627TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161628 CreatePoolWithIdleTimeouts(
1629 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1630 base::TimeDelta(), // Time out unused sockets immediately.
1631 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1632
1633 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1634
1635 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1636
1637 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211638 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161639 EXPECT_EQ(ERR_IO_PENDING, rv);
1640 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1641
1642 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211643 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161644 EXPECT_EQ(ERR_IO_PENDING, rv);
1645 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1646
1647 // Cancel one of the requests. Wait for the other, which will get the first
1648 // job. Release the socket. Run the loop again to make sure the second
1649 // socket is sitting idle and the first one is released (since ReleaseSocket()
1650 // just posts a DoReleaseSocket() task).
1651
1652 req.handle()->Reset();
1653 EXPECT_EQ(OK, req2.WaitForResult());
1654 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471655
1656 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1657 // actually become pending until 2ms after they have been created. In order
1658 // to flush all tasks, we need to wait so that we know there are no
1659 // soon-to-be-pending tasks waiting.
1660 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161661 MessageLoop::current()->RunAllPending();
1662
1663 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041664
[email protected]9bf28db2009-08-29 01:35:161665 // Invoke the idle socket cleanup check. Only one socket should be left, the
1666 // used socket. Request it to make sure that it's used.
1667
1668 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531669 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211670 rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161671 EXPECT_EQ(OK, rv);
1672 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151673 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451674 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161675}
1676
[email protected]2041cf342010-02-19 03:15:591677// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161678// because of multiple releasing disconnected sockets.
1679TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1680 CreatePoolWithIdleTimeouts(
1681 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1682 base::TimeDelta(), // Time out unused sockets immediately.
1683 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1684
1685 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1686
1687 // Startup 4 connect jobs. Two of them will be pending.
1688
1689 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211690 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161691 EXPECT_EQ(OK, rv);
1692
1693 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211694 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161695 EXPECT_EQ(OK, rv);
1696
1697 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211698 rv = req3.handle()->Init("a", params_, LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161699 EXPECT_EQ(ERR_IO_PENDING, rv);
1700
1701 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211702 rv = req4.handle()->Init("a", params_, LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161703 EXPECT_EQ(ERR_IO_PENDING, rv);
1704
1705 // Release two disconnected sockets.
1706
1707 req.handle()->socket()->Disconnect();
1708 req.handle()->Reset();
1709 req2.handle()->socket()->Disconnect();
1710 req2.handle()->Reset();
1711
1712 EXPECT_EQ(OK, req3.WaitForResult());
1713 EXPECT_FALSE(req3.handle()->is_reused());
1714 EXPECT_EQ(OK, req4.WaitForResult());
1715 EXPECT_FALSE(req4.handle()->is_reused());
1716}
1717
[email protected]d7027bb2010-05-10 18:58:541718// Regression test for http://crbug.com/42267.
1719// When DoReleaseSocket() is processed for one socket, it is blocked because the
1720// other stalled groups all have releasing sockets, so no progress can be made.
1721TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1722 CreatePoolWithIdleTimeouts(
1723 4 /* socket limit */, 4 /* socket limit per group */,
1724 base::TimeDelta(), // Time out unused sockets immediately.
1725 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1726
1727 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1728
1729 // Max out the socket limit with 2 per group.
1730
1731 scoped_ptr<TestSocketRequest> req_a[4];
1732 scoped_ptr<TestSocketRequest> req_b[4];
1733
1734 for (int i = 0; i < 2; ++i) {
1735 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1736 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211737 EXPECT_EQ(OK, req_a[i]->handle()->Init("a", params_, LOWEST, req_a[i].get(),
1738 pool_, BoundNetLog()));
1739 EXPECT_EQ(OK, req_b[i]->handle()->Init("b", params_, LOWEST, req_b[i].get(),
1740 pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541741 }
[email protected]b89f7e42010-05-20 20:37:001742
[email protected]d7027bb2010-05-10 18:58:541743 // Make 4 pending requests, 2 per group.
1744
1745 for (int i = 2; i < 4; ++i) {
1746 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1747 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211748 EXPECT_EQ(ERR_IO_PENDING, req_a[i]->handle()->Init("a", params_, LOWEST,
1749 req_a[i].get(), pool_,
1750 BoundNetLog()));
1751 EXPECT_EQ(ERR_IO_PENDING, req_b[i]->handle()->Init("b", params_, LOWEST,
1752 req_b[i].get(), pool_,
1753 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541754 }
1755
1756 // Release b's socket first. The order is important, because in
1757 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1758 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1759 // first, which has a releasing socket, so it refuses to start up another
1760 // ConnectJob. So, we used to infinite loop on this.
1761 req_b[0]->handle()->socket()->Disconnect();
1762 req_b[0]->handle()->Reset();
1763 req_a[0]->handle()->socket()->Disconnect();
1764 req_a[0]->handle()->Reset();
1765
1766 // Used to get stuck here.
1767 MessageLoop::current()->RunAllPending();
1768
1769 req_b[1]->handle()->socket()->Disconnect();
1770 req_b[1]->handle()->Reset();
1771 req_a[1]->handle()->socket()->Disconnect();
1772 req_a[1]->handle()->Reset();
1773
1774 for (int i = 2; i < 4; ++i) {
1775 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1776 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1777 }
1778}
1779
[email protected]fd4fe0b2010-02-08 23:02:151780TEST_F(ClientSocketPoolBaseTest,
1781 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1782 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1783
1784 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1785
1786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1787 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1789 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1790
1791 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1792 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1793 EXPECT_EQ(2u, completion_count_);
1794
1795 // Releases one connection.
1796 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1797 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1798
1799 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1800 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1801 EXPECT_EQ(4u, completion_count_);
1802
1803 EXPECT_EQ(1, GetOrderOfRequest(1));
1804 EXPECT_EQ(2, GetOrderOfRequest(2));
1805 EXPECT_EQ(3, GetOrderOfRequest(3));
1806 EXPECT_EQ(4, GetOrderOfRequest(4));
1807
1808 // Make sure we test order of all requests made.
1809 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1810}
1811
[email protected]4f1e4982010-03-02 18:31:041812class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1813 public:
[email protected]e60e47a2010-07-14 03:37:181814 TestReleasingSocketRequest(TestClientSocketPool* pool, int expected_result,
1815 bool reset_releasing_handle)
1816 : pool_(pool),
1817 expected_result_(expected_result),
1818 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:041819
1820 ClientSocketHandle* handle() { return &handle_; }
1821
1822 int WaitForResult() {
1823 return callback_.WaitForResult();
1824 }
1825
1826 virtual void RunWithParams(const Tuple1<int>& params) {
1827 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:181828 if (reset_releasing_handle_)
1829 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:211830 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]e60e47a2010-07-14 03:37:181831 EXPECT_EQ(expected_result_, handle2_.Init("a", con_params, kDefaultPriority,
1832 &callback2_, pool_,
1833 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041834 }
1835
1836 private:
[email protected]df4b4ef2010-07-12 18:25:211837 scoped_refptr<TestClientSocketPool> pool_;
[email protected]e60e47a2010-07-14 03:37:181838 int expected_result_;
1839 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:041840 ClientSocketHandle handle_;
1841 ClientSocketHandle handle2_;
1842 TestCompletionCallback callback_;
1843 TestCompletionCallback callback2_;
1844};
1845
[email protected]e60e47a2010-07-14 03:37:181846
1847TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
1848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1849
1850 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1851 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1852 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1853
1854 EXPECT_EQ(static_cast<int>(requests_.size()),
1855 client_socket_factory_.allocation_count());
1856
1857 connect_job_factory_->set_job_type(
1858 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1859 TestReleasingSocketRequest req(pool_.get(), OK, false);
1860 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1861 &req, pool_, BoundNetLog()));
1862 // The next job should complete synchronously
1863 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1864
1865 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1866 EXPECT_FALSE(req.handle()->is_initialized());
1867 EXPECT_FALSE(req.handle()->socket());
1868 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:431869 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181870}
1871
[email protected]b6501d3d2010-06-03 23:53:341872// http://crbug.com/44724 regression test.
1873// We start releasing the pool when we flush on network change. When that
1874// happens, the only active references are in the ClientSocketHandles. When a
1875// ConnectJob completes and calls back into the last ClientSocketHandle, that
1876// callback can release the last reference and delete the pool. After the
1877// callback finishes, we go back to the stack frame within the now-deleted pool.
1878// Executing any code that refers to members of the now-deleted pool can cause
1879// crashes.
1880TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1881 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1882 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1883
1884 ClientSocketHandle handle;
1885 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211886 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1887 &callback, pool_, BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:341888
1889 // Simulate flushing the pool.
1890 pool_ = NULL;
1891
1892 // We'll call back into this now.
1893 callback.WaitForResult();
1894}
1895
[email protected]a7e38572010-06-07 18:22:241896TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1897 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1898 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1899
1900 ClientSocketHandle handle;
1901 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211902 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1903 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241904 EXPECT_EQ(OK, callback.WaitForResult());
1905 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1906
1907 pool_->Flush();
1908
1909 handle.Reset();
1910 MessageLoop::current()->RunAllPending();
1911
[email protected]df4b4ef2010-07-12 18:25:211912 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1913 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241914 EXPECT_EQ(OK, callback.WaitForResult());
1915 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1916}
1917
[email protected]25eea382010-07-10 23:55:261918// Cancel a pending socket request while we're at max sockets,
1919// and verify that the backup socket firing doesn't cause a crash.
1920TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
1921 // Max 4 sockets globally, max 4 sockets per group.
1922 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1923 pool_->EnableBackupJobs();
1924
1925 // Create the first socket and set to ERR_IO_PENDING. This creates a
1926 // backup job.
1927 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1928 ClientSocketHandle handle;
1929 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211930 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
1931 &callback, pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261932
1933 // Start (MaxSockets - 1) connected sockets to reach max sockets.
1934 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1935 ClientSocketHandle handles[kDefaultMaxSockets];
1936 for (int i = 1; i < kDefaultMaxSockets; ++i) {
1937 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211938 EXPECT_EQ(OK, handles[i].Init("bar", params_, kDefaultPriority, &callback,
1939 pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261940 }
1941
1942 MessageLoop::current()->RunAllPending();
1943
1944 // Cancel the pending request.
1945 handle.Reset();
1946
1947 // Wait for the backup timer to fire (add some slop to ensure it fires)
1948 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
1949
1950 MessageLoop::current()->RunAllPending();
1951 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1952}
1953
[email protected]eb5a99382010-07-11 03:18:261954// Test delayed socket binding for the case where we have two connects,
1955// and while one is waiting on a connect, the other frees up.
1956// The socket waiting on a connect should switch immediately to the freed
1957// up socket.
1958TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
1959 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1960 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1961
1962 ClientSocketHandle handle1;
1963 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211964 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
1965 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261966 EXPECT_EQ(OK, callback.WaitForResult());
1967
1968 // No idle sockets, no pending jobs.
1969 EXPECT_EQ(0, pool_->IdleSocketCount());
1970 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1971
1972 // Create a second socket to the same host, but this one will wait.
1973 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1974 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:211975 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
1976 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261977 // No idle sockets, and one connecting job.
1978 EXPECT_EQ(0, pool_->IdleSocketCount());
1979 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1980
1981 // Return the first handle to the pool. This will initiate the delayed
1982 // binding.
1983 handle1.Reset();
1984
1985 MessageLoop::current()->RunAllPending();
1986
1987 // Still no idle sockets, still one pending connect job.
1988 EXPECT_EQ(0, pool_->IdleSocketCount());
1989 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1990
1991 // The second socket connected, even though it was a Waiting Job.
1992 EXPECT_EQ(OK, callback.WaitForResult());
1993
1994 // And we can see there is still one job waiting.
1995 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1996
1997 // Finally, signal the waiting Connect.
1998 client_socket_factory_.SignalJobs();
1999 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2000
2001 MessageLoop::current()->RunAllPending();
2002}
2003
2004// Test delayed socket binding when a group is at capacity and one
2005// of the group's sockets frees up.
2006TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2007 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2008 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2009
2010 ClientSocketHandle handle1;
2011 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212012 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2013 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262014 EXPECT_EQ(OK, callback.WaitForResult());
2015
2016 // No idle sockets, no pending jobs.
2017 EXPECT_EQ(0, pool_->IdleSocketCount());
2018 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2019
2020 // Create a second socket to the same host, but this one will wait.
2021 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2022 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212023 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2024 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262025 // No idle sockets, and one connecting job.
2026 EXPECT_EQ(0, pool_->IdleSocketCount());
2027 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2028
2029 // Return the first handle to the pool. This will initiate the delayed
2030 // binding.
2031 handle1.Reset();
2032
2033 MessageLoop::current()->RunAllPending();
2034
2035 // Still no idle sockets, still one pending connect job.
2036 EXPECT_EQ(0, pool_->IdleSocketCount());
2037 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2038
2039 // The second socket connected, even though it was a Waiting Job.
2040 EXPECT_EQ(OK, callback.WaitForResult());
2041
2042 // And we can see there is still one job waiting.
2043 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2044
2045 // Finally, signal the waiting Connect.
2046 client_socket_factory_.SignalJobs();
2047 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2048
2049 MessageLoop::current()->RunAllPending();
2050}
2051
2052// Test out the case where we have one socket connected, one
2053// connecting, when the first socket finishes and goes idle.
2054// Although the second connection is pending, th second request
2055// should complete, by taking the first socket's idle socket.
2056TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2057 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2058 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2059
2060 ClientSocketHandle handle1;
2061 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212062 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2063 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262064 EXPECT_EQ(OK, callback.WaitForResult());
2065
2066 // No idle sockets, no pending jobs.
2067 EXPECT_EQ(0, pool_->IdleSocketCount());
2068 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2069
2070 // Create a second socket to the same host, but this one will wait.
2071 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2072 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212073 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2074 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262075 // No idle sockets, and one connecting job.
2076 EXPECT_EQ(0, pool_->IdleSocketCount());
2077 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2078
2079 // Return the first handle to the pool. This will initiate the delayed
2080 // binding.
2081 handle1.Reset();
2082
2083 MessageLoop::current()->RunAllPending();
2084
2085 // Still no idle sockets, still one pending connect job.
2086 EXPECT_EQ(0, pool_->IdleSocketCount());
2087 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2088
2089 // The second socket connected, even though it was a Waiting Job.
2090 EXPECT_EQ(OK, callback.WaitForResult());
2091
2092 // And we can see there is still one job waiting.
2093 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2094
2095 // Finally, signal the waiting Connect.
2096 client_socket_factory_.SignalJobs();
2097 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2098
2099 MessageLoop::current()->RunAllPending();
2100}
2101
[email protected]f6d1d6eb2009-06-24 20:16:092102} // namespace
2103
2104} // namespace net