blob: 53063bab0ee16c7d2e56d008ce347c34cb7bd8a3 [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);
158 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
159 handle->set_tunnel_auth_response_info(headers, NULL);
160 }
161 }
162
[email protected]974ebd62009-08-03 23:14:34163 private:
[email protected]ab838892009-06-30 18:49:05164 // ConnectJob methods:
165
[email protected]974ebd62009-08-03 23:14:34166 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05167 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02168 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40169 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05170 switch (job_type_) {
171 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13172 return DoConnect(true /* successful */, false /* sync */,
173 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05174 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13175 return DoConnect(false /* error */, false /* sync */,
176 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05177 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57178 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47179
180 // Depending on execution timings, posting a delayed task can result
181 // in the task getting executed the at the earliest possible
182 // opportunity or only after returning once from the message loop and
183 // then a second call into the message loop. In order to make behavior
184 // more deterministic, we change the default delay to 2ms. This should
185 // always require us to wait for the second call into the message loop.
186 //
187 // N.B. The correct fix for this and similar timing problems is to
188 // abstract time for the purpose of unittests. Unfortunately, we have
189 // a lot of third-party components that directly call the various
190 // time functions, so this change would be rather invasive.
191 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05192 FROM_HERE,
193 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47194 &TestConnectJob::DoConnect,
195 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13196 true /* async */,
197 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13198 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05199 return ERR_IO_PENDING;
200 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57201 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47202 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05203 FROM_HERE,
204 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47205 &TestConnectJob::DoConnect,
206 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13207 true /* async */,
208 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47209 2);
[email protected]ab838892009-06-30 18:49:05210 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57211 case kMockWaitingJob:
212 client_socket_factory_->WaitForSignal(this);
213 waiting_success_ = true;
214 return ERR_IO_PENDING;
215 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46216 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57217 FROM_HERE,
218 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46219 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57220 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13221 case kMockRecoverableJob:
222 return DoConnect(false /* error */, false /* sync */,
223 true /* recoverable */);
224 case kMockPendingRecoverableJob:
225 set_load_state(LOAD_STATE_CONNECTING);
226 MessageLoop::current()->PostDelayedTask(
227 FROM_HERE,
228 method_factory_.NewRunnableMethod(
229 &TestConnectJob::DoConnect,
230 false /* error */,
231 true /* async */,
232 true /* recoverable */),
233 2);
234 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18235 case kMockAdditionalErrorStateJob:
236 store_additional_error_state_ = true;
237 return DoConnect(false /* error */, false /* sync */,
238 false /* recoverable */);
239 case kMockPendingAdditionalErrorStateJob:
240 set_load_state(LOAD_STATE_CONNECTING);
241 store_additional_error_state_ = true;
242 MessageLoop::current()->PostDelayedTask(
243 FROM_HERE,
244 method_factory_.NewRunnableMethod(
245 &TestConnectJob::DoConnect,
246 false /* error */,
247 true /* async */,
248 false /* recoverable */),
249 2);
250 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05251 default:
252 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40253 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05254 return ERR_FAILED;
255 }
256 }
257
[email protected]46451352009-09-01 14:54:21258 void set_load_state(LoadState load_state) { load_state_ = load_state; }
259
[email protected]e772db3f2010-07-12 18:11:13260 int DoConnect(bool succeed, bool was_async, bool recoverable) {
261 int result = OK;
[email protected]ab838892009-06-30 18:49:05262 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02263 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13264 } else if (recoverable) {
265 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40266 } else {
[email protected]e772db3f2010-07-12 18:11:13267 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40268 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05269 }
[email protected]2ab05b52009-07-01 23:57:58270
271 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30272 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05273 return result;
274 }
275
[email protected]cfa8228c2010-06-17 01:07:56276 // This function helps simulate the progress of load states on a ConnectJob.
277 // Each time it is called it advances the load state and posts a task to be
278 // called again. It stops at the last connecting load state (the one
279 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57280 void AdvanceLoadState(LoadState state) {
281 int tmp = state;
282 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56283 if (tmp < LOAD_STATE_SENDING_REQUEST) {
284 state = static_cast<LoadState>(tmp);
285 set_load_state(state);
286 MessageLoop::current()->PostTask(
287 FROM_HERE,
288 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
289 state));
290 }
[email protected]5fc08e32009-07-15 17:09:57291 }
292
293 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05294 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57295 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05296 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21297 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18298 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05299
300 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
301};
302
[email protected]d80a4322009-08-14 07:07:49303class TestConnectJobFactory
304 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05305 public:
[email protected]5fc08e32009-07-15 17:09:57306 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05307 : job_type_(TestConnectJob::kMockJob),
308 client_socket_factory_(client_socket_factory) {}
309
310 virtual ~TestConnectJobFactory() {}
311
312 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
313
[email protected]974ebd62009-08-03 23:14:34314 void set_timeout_duration(base::TimeDelta timeout_duration) {
315 timeout_duration_ = timeout_duration;
316 }
317
[email protected]ab838892009-06-30 18:49:05318 // ConnectJobFactory methods:
319
320 virtual ConnectJob* NewConnectJob(
321 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49322 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17323 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05324 return new TestConnectJob(job_type_,
325 group_name,
326 request,
[email protected]974ebd62009-08-03 23:14:34327 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05328 delegate,
[email protected]fd7b7c92009-08-20 19:38:30329 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17330 NULL);
[email protected]ab838892009-06-30 18:49:05331 }
332
[email protected]a796bcec2010-03-22 17:17:26333 virtual base::TimeDelta ConnectionTimeout() const {
334 return timeout_duration_;
335 }
336
[email protected]ab838892009-06-30 18:49:05337 private:
338 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34339 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57340 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05341
342 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
343};
344
345class TestClientSocketPool : public ClientSocketPool {
346 public:
347 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53348 int max_sockets,
[email protected]ab838892009-06-30 18:49:05349 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00350 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16351 base::TimeDelta unused_idle_socket_timeout,
352 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49353 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00354 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16355 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38356 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05357
358 virtual int RequestSocket(
359 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49360 const void* params,
[email protected]ac790b42009-12-02 04:31:31361 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05362 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46363 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53364 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21365 const scoped_refptr<TestSocketParams>* casted_socket_params =
366 static_cast<const scoped_refptr<TestSocketParams>*>(params);
367 return base_.RequestSocket(group_name, *casted_socket_params, priority,
368 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05369 }
370
371 virtual void CancelRequest(
372 const std::string& group_name,
373 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49374 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05375 }
376
377 virtual void ReleaseSocket(
378 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24379 ClientSocket* socket,
380 int id) {
381 base_.ReleaseSocket(group_name, socket, id);
382 }
383
384 virtual void Flush() {
385 base_.Flush();
[email protected]ab838892009-06-30 18:49:05386 }
387
388 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49389 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05390 }
391
[email protected]d80a4322009-08-14 07:07:49392 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05393
394 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49395 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05396 }
397
398 virtual LoadState GetLoadState(const std::string& group_name,
399 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49400 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05401 }
402
[email protected]a796bcec2010-03-22 17:17:26403 virtual base::TimeDelta ConnectionTimeout() const {
404 return base_.ConnectionTimeout();
405 }
406
[email protected]b89f7e42010-05-20 20:37:00407 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
408 return base_.histograms();
409 }
[email protected]a796bcec2010-03-22 17:17:26410
[email protected]d80a4322009-08-14 07:07:49411 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20412
[email protected]974ebd62009-08-03 23:14:34413 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49414 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34415 }
416
[email protected]9bf28db2009-08-29 01:35:16417 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
418
[email protected]43a21b82010-06-10 21:30:54419 void EnableBackupJobs() { base_.EnableBackupJobs(); }
420
[email protected]ab838892009-06-30 18:49:05421 private:
[email protected]5389bc72009-11-05 23:34:24422 ~TestClientSocketPool() {}
423
[email protected]d80a4322009-08-14 07:07:49424 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05425
426 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
427};
428
[email protected]a937a06d2009-08-19 21:19:24429} // namespace
430
[email protected]7fc5b09a2010-02-27 00:07:38431REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24432
433namespace {
434
[email protected]5fc08e32009-07-15 17:09:57435void MockClientSocketFactory::SignalJobs() {
436 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
437 it != waiting_jobs_.end(); ++it) {
438 (*it)->Signal();
439 }
440 waiting_jobs_.clear();
441}
442
[email protected]974ebd62009-08-03 23:14:34443class TestConnectJobDelegate : public ConnectJob::Delegate {
444 public:
445 TestConnectJobDelegate()
446 : have_result_(false), waiting_for_result_(false), result_(OK) {}
447 virtual ~TestConnectJobDelegate() {}
448
449 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
450 result_ = result;
[email protected]6e713f02009-08-06 02:56:40451 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07452 // socket.get() should be NULL iff result != OK
453 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34454 delete job;
455 have_result_ = true;
456 if (waiting_for_result_)
457 MessageLoop::current()->Quit();
458 }
459
460 int WaitForResult() {
461 DCHECK(!waiting_for_result_);
462 while (!have_result_) {
463 waiting_for_result_ = true;
464 MessageLoop::current()->Run();
465 waiting_for_result_ = false;
466 }
467 have_result_ = false; // auto-reset for next callback
468 return result_;
469 }
470
471 private:
472 bool have_result_;
473 bool waiting_for_result_;
474 int result_;
475};
476
[email protected]75439d3b2009-07-23 22:11:17477class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09478 protected:
[email protected]b89f7e42010-05-20 20:37:00479 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21480 : params_(new TestSocketParams()),
481 histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20482
[email protected]211d21722009-07-22 15:48:53483 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16484 CreatePoolWithIdleTimeouts(
485 max_sockets,
486 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00487 base::TimeDelta::FromSeconds(
488 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16489 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
490 }
491
492 void CreatePoolWithIdleTimeouts(
493 int max_sockets, int max_sockets_per_group,
494 base::TimeDelta unused_idle_socket_timeout,
495 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20496 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04497 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53498 pool_ = new TestClientSocketPool(max_sockets,
499 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00500 histograms_,
[email protected]9bf28db2009-08-29 01:35:16501 unused_idle_socket_timeout,
502 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20503 connect_job_factory_);
504 }
[email protected]f6d1d6eb2009-06-24 20:16:09505
[email protected]ac790b42009-12-02 04:31:31506 int StartRequest(const std::string& group_name,
507 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38508 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]df4b4ef2010-07-12 18:25:21509 pool_, group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09510 }
511
512 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47513 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
514 // actually become pending until 2ms after they have been created. In order
515 // to flush all tasks, we need to wait so that we know there are no
516 // soon-to-be-pending tasks waiting.
517 PlatformThread::Sleep(10);
518 MessageLoop::current()->RunAllPending();
519
[email protected]211d21722009-07-22 15:48:53520 // Need to delete |pool_| before we turn late binding back off. We also need
521 // to delete |requests_| because the pool is reference counted and requests
522 // keep reference to it.
523 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57524 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53525 requests_.reset();
526
[email protected]75439d3b2009-07-23 22:11:17527 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09528 }
529
[email protected]f6d1d6eb2009-06-24 20:16:09530 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04531 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21532 scoped_refptr<TestSocketParams> params_;
[email protected]c9d6a1d2009-07-14 16:15:20533 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00534 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09535};
536
[email protected]974ebd62009-08-03 23:14:34537// Even though a timeout is specified, it doesn't time out on a synchronous
538// completion.
539TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
540 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06541 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49542 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21543 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34544 scoped_ptr<TestConnectJob> job(
545 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12546 "a",
[email protected]974ebd62009-08-03 23:14:34547 request,
548 base::TimeDelta::FromMicroseconds(1),
549 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30550 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17551 NULL));
[email protected]974ebd62009-08-03 23:14:34552 EXPECT_EQ(OK, job->Connect());
553}
554
555TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
556 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06557 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17558 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53559
[email protected]d80a4322009-08-14 07:07:49560 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21561 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34562 // Deleted by TestConnectJobDelegate.
563 TestConnectJob* job =
564 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12565 "a",
[email protected]974ebd62009-08-03 23:14:34566 request,
567 base::TimeDelta::FromMicroseconds(1),
568 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30569 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17570 &log);
[email protected]974ebd62009-08-03 23:14:34571 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
572 PlatformThread::Sleep(1);
573 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30574
[email protected]06650c52010-06-03 00:49:17575 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46576 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53577 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17578 EXPECT_TRUE(LogContainsBeginEvent(
579 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46580 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17581 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
582 NetLog::PHASE_NONE));
583 EXPECT_TRUE(LogContainsEvent(
584 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53585 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46586 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17587 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
588 EXPECT_TRUE(LogContainsEndEvent(
589 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34590}
591
[email protected]5fc08e32009-07-15 17:09:57592TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53593 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20594
[email protected]f6d1d6eb2009-06-24 20:16:09595 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06596 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53597 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
598
[email protected]df4b4ef2010-07-12 18:25:21599 EXPECT_EQ(OK, handle.Init("a", params_, kDefaultPriority, &callback, pool_,
600 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09601 EXPECT_TRUE(handle.is_initialized());
602 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09603 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30604
[email protected]06650c52010-06-03 00:49:17605 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46606 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53607 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53608 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17609 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
610 NetLog::PHASE_NONE));
611 EXPECT_TRUE(LogContainsEvent(
612 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53613 NetLog::PHASE_NONE));
614 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17615 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09616}
617
[email protected]ab838892009-06-30 18:49:05618TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53619 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20620
[email protected]ab838892009-06-30 18:49:05621 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53622 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
623
[email protected]a512f5982009-08-18 16:01:06624 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]e60e47a2010-07-14 03:37:18625 // Set the additional error state members to ensure that they get cleared.
626 req.handle()->set_is_ssl_error(true);
627 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
628 req.handle()->set_tunnel_auth_response_info(headers, NULL);
[email protected]df4b4ef2010-07-12 18:25:21629 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
630 kDefaultPriority, &req,
631 pool_, log.bound()));
[email protected]e772db3f2010-07-12 18:11:13632 EXPECT_FALSE(req.handle()->socket());
[email protected]e60e47a2010-07-14 03:37:18633 EXPECT_FALSE(req.handle()->is_ssl_error());
634 EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30635
[email protected]06650c52010-06-03 00:49:17636 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27637 EXPECT_TRUE(LogContainsBeginEvent(
638 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17639 EXPECT_TRUE(LogContainsEvent(
640 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
641 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02642 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17643 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09644}
645
[email protected]211d21722009-07-22 15:48:53646TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
647 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
648
[email protected]9e743cd2010-03-16 07:03:53649 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30650
[email protected]211d21722009-07-22 15:48:53651 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
652 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
653 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
654 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
655
656 EXPECT_EQ(static_cast<int>(requests_.size()),
657 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17658 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53659
660 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
662 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
663
[email protected]43a21b82010-06-10 21:30:54664 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53665
666 EXPECT_EQ(static_cast<int>(requests_.size()),
667 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17668 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53669
670 EXPECT_EQ(1, GetOrderOfRequest(1));
671 EXPECT_EQ(2, GetOrderOfRequest(2));
672 EXPECT_EQ(3, GetOrderOfRequest(3));
673 EXPECT_EQ(4, GetOrderOfRequest(4));
674 EXPECT_EQ(5, GetOrderOfRequest(5));
675 EXPECT_EQ(6, GetOrderOfRequest(6));
676 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17677
678 // Make sure we test order of all requests made.
679 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53680}
681
682TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
683 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
684
[email protected]9e743cd2010-03-16 07:03:53685 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30686
[email protected]211d21722009-07-22 15:48:53687 // Reach all limits: max total sockets, and max sockets per group.
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
690 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
691 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
692
693 EXPECT_EQ(static_cast<int>(requests_.size()),
694 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17695 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53696
697 // Now create a new group and verify that we don't starve it.
698 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
699
[email protected]43a21b82010-06-10 21:30:54700 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53701
702 EXPECT_EQ(static_cast<int>(requests_.size()),
703 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17704 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(1, GetOrderOfRequest(1));
707 EXPECT_EQ(2, GetOrderOfRequest(2));
708 EXPECT_EQ(3, GetOrderOfRequest(3));
709 EXPECT_EQ(4, GetOrderOfRequest(4));
710 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17711
712 // Make sure we test order of all requests made.
713 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53714}
715
716TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
718
[email protected]ac790b42009-12-02 04:31:31719 EXPECT_EQ(OK, StartRequest("b", LOWEST));
720 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
721 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
722 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53723
724 EXPECT_EQ(static_cast<int>(requests_.size()),
725 client_socket_factory_.allocation_count());
726
[email protected]ac790b42009-12-02 04:31:31727 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
728 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
729 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53730
[email protected]43a21b82010-06-10 21:30:54731 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53732
[email protected]75439d3b2009-07-23 22:11:17733 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53734
735 // First 4 requests don't have to wait, and finish in order.
736 EXPECT_EQ(1, GetOrderOfRequest(1));
737 EXPECT_EQ(2, GetOrderOfRequest(2));
738 EXPECT_EQ(3, GetOrderOfRequest(3));
739 EXPECT_EQ(4, GetOrderOfRequest(4));
740
[email protected]ac790b42009-12-02 04:31:31741 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
742 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53743 EXPECT_EQ(7, GetOrderOfRequest(5));
744 EXPECT_EQ(6, GetOrderOfRequest(6));
745 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17746
747 // Make sure we test order of all requests made.
748 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53749}
750
751TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
753
[email protected]ac790b42009-12-02 04:31:31754 EXPECT_EQ(OK, StartRequest("a", LOWEST));
755 EXPECT_EQ(OK, StartRequest("a", LOW));
756 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
757 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53758
759 EXPECT_EQ(static_cast<int>(requests_.size()),
760 client_socket_factory_.allocation_count());
761
[email protected]ac790b42009-12-02 04:31:31762 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
763 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
764 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53765
[email protected]43a21b82010-06-10 21:30:54766 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53767
[email protected]43a21b82010-06-10 21:30:54768 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53769 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17770 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53771
772 // First 4 requests don't have to wait, and finish in order.
773 EXPECT_EQ(1, GetOrderOfRequest(1));
774 EXPECT_EQ(2, GetOrderOfRequest(2));
775 EXPECT_EQ(3, GetOrderOfRequest(3));
776 EXPECT_EQ(4, GetOrderOfRequest(4));
777
778 // Request ("b", 7) has the highest priority, but we can't make new socket for
779 // group "b", because it has reached the per-group limit. Then we make
780 // socket for ("c", 6), because it has higher priority than ("a", 4),
781 // and we still can't make a socket for group "b".
782 EXPECT_EQ(5, GetOrderOfRequest(5));
783 EXPECT_EQ(6, GetOrderOfRequest(6));
784 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17785
786 // Make sure we test order of all requests made.
787 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53788}
789
790// Make sure that we count connecting sockets against the total limit.
791TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
792 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
793
794 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
795 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
796 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
797
798 // Create one asynchronous request.
799 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
800 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
801
[email protected]6b175382009-10-13 06:47:47802 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
803 // actually become pending until 2ms after they have been created. In order
804 // to flush all tasks, we need to wait so that we know there are no
805 // soon-to-be-pending tasks waiting.
806 PlatformThread::Sleep(10);
807 MessageLoop::current()->RunAllPending();
808
[email protected]211d21722009-07-22 15:48:53809 // The next synchronous request should wait for its turn.
810 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
812
[email protected]43a21b82010-06-10 21:30:54813 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53814
815 EXPECT_EQ(static_cast<int>(requests_.size()),
816 client_socket_factory_.allocation_count());
817
818 EXPECT_EQ(1, GetOrderOfRequest(1));
819 EXPECT_EQ(2, GetOrderOfRequest(2));
820 EXPECT_EQ(3, GetOrderOfRequest(3));
821 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17822 EXPECT_EQ(5, GetOrderOfRequest(5));
823
824 // Make sure we test order of all requests made.
825 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53826}
827
[email protected]6427fe22010-04-16 22:27:41828TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
829 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
830 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
831
832 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
833 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
834 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
835 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
836
837 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
838
839 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
840
841 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
842 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
843
844 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
845
846 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
847 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
848 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
849 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
850 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
851 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
852 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
853}
854
[email protected]d7027bb2010-05-10 18:58:54855TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
856 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
857 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
858
859 ClientSocketHandle handle;
860 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21861 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
862 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54863
864 ClientSocketHandle handles[4];
865 for (size_t i = 0; i < arraysize(handles); ++i) {
866 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21867 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init("b", params_, kDefaultPriority,
868 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54869 }
870
871 // One will be stalled, cancel all the handles now.
872 // This should hit the OnAvailableSocketSlot() code where we previously had
873 // stalled groups, but no longer have any.
874 for (size_t i = 0; i < arraysize(handles); ++i)
875 handles[i].Reset();
876}
877
[email protected]eb5a99382010-07-11 03:18:26878TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
880 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
881
[email protected]eb5a99382010-07-11 03:18:26882 {
883 ClientSocketHandle handles[kDefaultMaxSockets];
884 TestCompletionCallback callbacks[kDefaultMaxSockets];
885 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]df4b4ef2010-07-12 18:25:21886 EXPECT_EQ(OK, handles[i].Init(IntToString(i), params_, kDefaultPriority,
887 &callbacks[i], pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26888 }
889
890 // Force a stalled group.
891 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54892 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21893 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
894 kDefaultPriority, &callback,
895 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26896
897 // Cancel the stalled request.
898 stalled_handle.Reset();
899
900 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
901 EXPECT_EQ(0, pool_->IdleSocketCount());
902
903 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54904 }
905
[email protected]43a21b82010-06-10 21:30:54906 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
907 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26908}
[email protected]43a21b82010-06-10 21:30:54909
[email protected]eb5a99382010-07-11 03:18:26910TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
911 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
912 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
913
914 {
915 ClientSocketHandle handles[kDefaultMaxSockets];
916 for (int i = 0; i < kDefaultMaxSockets; ++i) {
917 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21918 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(IntToString(i), params_,
919 kDefaultPriority, &callback,
920 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26921 }
922
923 // Force a stalled group.
924 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
925 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54926 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21927 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
928 kDefaultPriority, &callback,
929 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26930
931 // Since it is stalled, it should have no connect jobs.
932 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
933
934 // Cancel the stalled request.
935 handles[0].Reset();
936
[email protected]994d4932010-07-12 17:55:13937 // Wait for the pending job to be guaranteed to complete.
938 PlatformThread::Sleep(TestConnectJob::kPendingConnectDelay * 2);
939
[email protected]eb5a99382010-07-11 03:18:26940 MessageLoop::current()->RunAllPending();
941
942 // Now we should have a connect job.
943 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
944
945 // The stalled socket should connect.
946 EXPECT_EQ(OK, callback.WaitForResult());
947
948 EXPECT_EQ(kDefaultMaxSockets + 1,
949 client_socket_factory_.allocation_count());
950 EXPECT_EQ(0, pool_->IdleSocketCount());
951 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
952
953 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54954 }
955
[email protected]eb5a99382010-07-11 03:18:26956 EXPECT_EQ(1, pool_->IdleSocketCount());
957}
[email protected]43a21b82010-06-10 21:30:54958
[email protected]eb5a99382010-07-11 03:18:26959TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
960 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
961 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54962
[email protected]eb5a99382010-07-11 03:18:26963 ClientSocketHandle stalled_handle;
964 TestCompletionCallback callback;
965 {
966 ClientSocketHandle handles[kDefaultMaxSockets];
967 for (int i = 0; i < kDefaultMaxSockets; ++i) {
968 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21969 EXPECT_EQ(OK, handles[i].Init(StringPrintf("Take 2: %d", i), params_,
970 kDefaultPriority, &callback, pool_,
971 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26972 }
973
974 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
975 EXPECT_EQ(0, pool_->IdleSocketCount());
976
977 // Now we will hit the socket limit.
[email protected]df4b4ef2010-07-12 18:25:21978 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
979 kDefaultPriority, &callback,
980 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26981
982 // Dropping out of scope will close all handles and return them to idle.
983 }
[email protected]43a21b82010-06-10 21:30:54984
985 // But if we wait for it, the released idle sockets will be closed in
986 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:10987 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:26988
989 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
990 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54991}
992
993// Regression test for http://crbug.com/40952.
994TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
995 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
996 pool_->EnableBackupJobs();
997 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
998
999 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1000 ClientSocketHandle handle;
1001 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211002 EXPECT_EQ(OK, handle.Init(IntToString(i), params_, kDefaultPriority,
1003 &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541004 }
1005
1006 // Flush all the DoReleaseSocket tasks.
1007 MessageLoop::current()->RunAllPending();
1008
1009 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1010 // reuse a socket.
1011 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1012 ClientSocketHandle handle;
1013 TestCompletionCallback callback;
1014
1015 // "0" is special here, since it should be the first entry in the sorted map,
1016 // which is the one which we would close an idle socket for. We shouldn't
1017 // close an idle socket though, since we should reuse the idle socket.
[email protected]df4b4ef2010-07-12 18:25:211018 EXPECT_EQ(OK, handle.Init("0", params_, kDefaultPriority, &callback, pool_,
1019 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541020
1021 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1022 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1023}
1024
[email protected]ab838892009-06-30 18:49:051025TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531026 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091027
[email protected]c9d6a1d2009-07-14 16:15:201028 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1029 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[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));
1044 EXPECT_EQ(6, GetOrderOfRequest(3));
1045 EXPECT_EQ(4, GetOrderOfRequest(4));
1046 EXPECT_EQ(3, GetOrderOfRequest(5));
1047 EXPECT_EQ(5, GetOrderOfRequest(6));
1048 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171049
1050 // Make sure we test order of all requests made.
1051 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091052}
1053
[email protected]ab838892009-06-30 18:49:051054TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091056
[email protected]c9d6a1d2009-07-14 16:15:201057 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1058 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1063 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091064
[email protected]c9d6a1d2009-07-14 16:15:201065 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091066
[email protected]c9d6a1d2009-07-14 16:15:201067 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1068 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1069
1070 EXPECT_EQ(static_cast<int>(requests_.size()),
1071 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171072 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091073}
1074
1075// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051076// The pending connect job will be cancelled and should not call back into
1077// ClientSocketPoolBase.
1078TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531079 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201080
[email protected]ab838892009-06-30 18:49:051081 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061082 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211083 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1084 &req, pool_, BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331085 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091086}
1087
[email protected]ab838892009-06-30 18:49:051088TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531089 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201090
[email protected]ab838892009-06-30 18:49:051091 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061092 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091093 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061094 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091095
[email protected]df4b4ef2010-07-12 18:25:211096 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1097 &callback, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091098
1099 handle.Reset();
1100
1101 TestCompletionCallback callback2;
[email protected]df4b4ef2010-07-12 18:25:211102 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1103 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091104
1105 EXPECT_EQ(OK, callback2.WaitForResult());
1106 EXPECT_FALSE(callback.have_result());
1107
1108 handle.Reset();
1109}
1110
[email protected]ab838892009-06-30 18:49:051111TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531112 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091113
[email protected]c9d6a1d2009-07-14 16:15:201114 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1115 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311116 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1117 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1118 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1120 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091121
1122 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201123 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331124 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1125 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091126
[email protected]c9d6a1d2009-07-14 16:15:201127 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091128
[email protected]c9d6a1d2009-07-14 16:15:201129 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1130 client_socket_factory_.allocation_count());
1131 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171132 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091133
[email protected]c9d6a1d2009-07-14 16:15:201134 EXPECT_EQ(1, GetOrderOfRequest(1));
1135 EXPECT_EQ(2, GetOrderOfRequest(2));
1136 EXPECT_EQ(5, GetOrderOfRequest(3));
1137 EXPECT_EQ(3, GetOrderOfRequest(4));
1138 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1139 EXPECT_EQ(4, GetOrderOfRequest(6));
1140 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171141
1142 // Make sure we test order of all requests made.
1143 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091144}
1145
1146class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1147 public:
[email protected]2ab05b52009-07-01 23:57:581148 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241149 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581150 TestConnectJobFactory* test_connect_job_factory,
1151 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091152 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061153 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581154 within_callback_(false),
1155 test_connect_job_factory_(test_connect_job_factory),
1156 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091157
1158 virtual void RunWithParams(const Tuple1<int>& params) {
1159 callback_.RunWithParams(params);
1160 ASSERT_EQ(OK, params.a);
1161
1162 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581163 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111164
1165 // Don't allow reuse of the socket. Disconnect it and then release it and
1166 // run through the MessageLoop once to get it completely released.
1167 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091168 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111169 {
1170 MessageLoop::ScopedNestableTaskAllower nestable(
1171 MessageLoop::current());
1172 MessageLoop::current()->RunAllPending();
1173 }
[email protected]f6d1d6eb2009-06-24 20:16:091174 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471175 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211176 scoped_refptr<TestSocketParams> params = new TestSocketParams();
1177 int rv = handle_->Init("a", params, kDefaultPriority, &next_job_callback,
1178 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581179 switch (next_job_type_) {
1180 case TestConnectJob::kMockJob:
1181 EXPECT_EQ(OK, rv);
1182 break;
1183 case TestConnectJob::kMockPendingJob:
1184 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471185
1186 // For pending jobs, wait for new socket to be created. This makes
1187 // sure there are no more pending operations nor any unclosed sockets
1188 // when the test finishes.
1189 // We need to give it a little bit of time to run, so that all the
1190 // operations that happen on timers (e.g. cleanup of idle
1191 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111192 {
1193 MessageLoop::ScopedNestableTaskAllower nestable(
1194 MessageLoop::current());
1195 PlatformThread::Sleep(10);
1196 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1197 }
[email protected]2ab05b52009-07-01 23:57:581198 break;
1199 default:
1200 FAIL() << "Unexpected job type: " << next_job_type_;
1201 break;
1202 }
[email protected]f6d1d6eb2009-06-24 20:16:091203 }
1204 }
1205
1206 int WaitForResult() {
1207 return callback_.WaitForResult();
1208 }
1209
1210 private:
1211 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241212 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091213 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581214 TestConnectJobFactory* const test_connect_job_factory_;
1215 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091216 TestCompletionCallback callback_;
1217};
1218
[email protected]2ab05b52009-07-01 23:57:581219TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531220 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201221
[email protected]0b7648c2009-07-06 20:14:011222 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061223 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581224 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061225 &handle, pool_.get(), connect_job_factory_,
1226 TestConnectJob::kMockPendingJob);
[email protected]df4b4ef2010-07-12 18:25:211227 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1228 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091229 ASSERT_EQ(ERR_IO_PENDING, rv);
1230
1231 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581232}
[email protected]f6d1d6eb2009-06-24 20:16:091233
[email protected]2ab05b52009-07-01 23:57:581234TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531235 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201236
[email protected]0b7648c2009-07-06 20:14:011237 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061238 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581239 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061240 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]df4b4ef2010-07-12 18:25:211241 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1242 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581243 ASSERT_EQ(ERR_IO_PENDING, rv);
1244
1245 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091246}
1247
1248// Make sure that pending requests get serviced after active requests get
1249// cancelled.
[email protected]ab838892009-06-30 18:49:051250TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531251 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201252
[email protected]0b7648c2009-07-06 20:14:011253 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091254
[email protected]c9d6a1d2009-07-14 16:15:201255 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1256 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));
[email protected]f6d1d6eb2009-06-24 20:16:091262
[email protected]c9d6a1d2009-07-14 16:15:201263 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1264 // Let's cancel them.
1265 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331266 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1267 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091268 }
1269
[email protected]f6d1d6eb2009-06-24 20:16:091270 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201271 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1272 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331273 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091274 }
1275
[email protected]75439d3b2009-07-23 22:11:171276 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091277}
1278
1279// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051280TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531281 const size_t kMaxSockets = 5;
1282 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201283
[email protected]0b7648c2009-07-06 20:14:011284 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091285
[email protected]211d21722009-07-22 15:48:531286 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1287 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091288
1289 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531290 for (size_t i = 0; i < kNumberOfRequests; ++i)
1291 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091292
[email protected]211d21722009-07-22 15:48:531293 for (size_t i = 0; i < kNumberOfRequests; ++i)
1294 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091295}
1296
[email protected]5fc08e32009-07-15 17:09:571297TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531298 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571299
1300 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1301
[email protected]a512f5982009-08-18 16:01:061302 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211303 int rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1304 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571305 EXPECT_EQ(ERR_IO_PENDING, rv);
1306
1307 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331308 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571309
[email protected]df4b4ef2010-07-12 18:25:211310 rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1311 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571312 EXPECT_EQ(ERR_IO_PENDING, rv);
1313 EXPECT_EQ(OK, req.WaitForResult());
1314
[email protected]a6c59f62009-07-29 16:33:331315 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171316 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571317 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1318}
1319
[email protected]2b7523d2009-07-29 20:29:231320// Regression test for http://crbug.com/17985.
1321TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1322 const int kMaxSockets = 3;
1323 const int kMaxSocketsPerGroup = 2;
1324 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1325
[email protected]ac790b42009-12-02 04:31:311326 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231327
1328 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1329 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1330
1331 // This is going to be a pending request in an otherwise empty group.
1332 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1333
1334 // Reach the maximum socket limit.
1335 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1336
1337 // Create a stalled group with high priorities.
1338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231340
[email protected]eb5a99382010-07-11 03:18:261341 // Release the first two sockets from "a". Because this is a keepalive,
1342 // the first release will unblock the pending request for "a". The
1343 // second release will unblock a request for "c", becaue it is the next
1344 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231345 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1346 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1347
1348 // Closing idle sockets should not get us into trouble, but in the bug
1349 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411350 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541351 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261352
1353 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231354}
1355
[email protected]4d3b05d2010-01-27 21:27:291356TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531357 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571358
1359 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061360 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531361 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211362 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571363 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331364 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571365 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331366 EXPECT_TRUE(req.handle()->is_initialized());
1367 EXPECT_TRUE(req.handle()->socket());
1368 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301369
[email protected]06650c52010-06-03 00:49:171370 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461371 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531372 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171373 EXPECT_TRUE(LogContainsEvent(
1374 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1375 NetLog::PHASE_NONE));
1376 EXPECT_TRUE(LogContainsEvent(
1377 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1378 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461379 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171380 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571381}
1382
[email protected]4d3b05d2010-01-27 21:27:291383TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571384 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531385 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571386
1387 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061388 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531389 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181390 // Set the additional error state members to ensure that they get cleared.
1391 req.handle()->set_is_ssl_error(true);
1392 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(""));
1393 req.handle()->set_tunnel_auth_response_info(headers, NULL);
[email protected]df4b4ef2010-07-12 18:25:211394 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1395 &req, pool_, log.bound()));
[email protected]a6c59f62009-07-29 16:33:331396 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571397 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]e60e47a2010-07-14 03:37:181398 EXPECT_FALSE(req.handle()->is_ssl_error());
1399 EXPECT_TRUE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301400
[email protected]06650c52010-06-03 00:49:171401 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461402 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531403 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171404 EXPECT_TRUE(LogContainsEvent(
1405 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1406 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321407 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171408 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571409}
1410
[email protected]4d3b05d2010-01-27 21:27:291411TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101412 // TODO(eroman): Add back the log expectations! Removed them because the
1413 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531414 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571415
1416 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061417 TestSocketRequest req(&request_order_, &completion_count_);
1418 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571419
[email protected]df4b4ef2010-07-12 18:25:211420 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1421 &req, pool_, BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531422 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211423 EXPECT_EQ(ERR_IO_PENDING, req2.handle()->Init("a", params_, kDefaultPriority,
1424 &req2, pool_, BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571425
[email protected]a6c59f62009-07-29 16:33:331426 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571427
[email protected]fd7b7c92009-08-20 19:38:301428
1429 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301430
[email protected]5fc08e32009-07-15 17:09:571431 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331432 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301433
1434 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531435 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571436}
1437
[email protected]4d3b05d2010-01-27 21:27:291438TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341439 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1440
[email protected]17a0c6c2009-08-04 00:07:041441 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1442
[email protected]ac790b42009-12-02 04:31:311443 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1444 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1445 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1446 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341447
1448 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1449 requests_[2]->handle()->Reset();
1450 requests_[3]->handle()->Reset();
1451 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1452
1453 requests_[1]->handle()->Reset();
1454 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1455
1456 requests_[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261457 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341458}
1459
[email protected]5fc08e32009-07-15 17:09:571460// When requests and ConnectJobs are not coupled, the request will get serviced
1461// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291462TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531463 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571464
1465 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321466 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571467
[email protected]a512f5982009-08-18 16:01:061468 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211469 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1470 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571471 EXPECT_EQ(ERR_IO_PENDING, rv);
1472 EXPECT_EQ(OK, req1.WaitForResult());
1473
1474 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1475 // without a job.
1476 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1477
[email protected]a512f5982009-08-18 16:01:061478 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211479 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1480 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571481 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061482 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211483 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1484 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571485 EXPECT_EQ(ERR_IO_PENDING, rv);
1486
1487 // Both Requests 2 and 3 are pending. We release socket 1 which should
1488 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331489 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261490 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331491 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571492 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331493 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571494
1495 // Signal job 2, which should service request 3.
1496
1497 client_socket_factory_.SignalJobs();
1498 EXPECT_EQ(OK, req3.WaitForResult());
1499
1500 ASSERT_EQ(3U, request_order_.size());
1501 EXPECT_EQ(&req1, request_order_[0]);
1502 EXPECT_EQ(&req2, request_order_[1]);
1503 EXPECT_EQ(&req3, request_order_[2]);
1504 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1505}
1506
1507// The requests are not coupled to the jobs. So, the requests should finish in
1508// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291509TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531510 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571511 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321512 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571513
[email protected]a512f5982009-08-18 16:01:061514 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211515 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1516 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571517 EXPECT_EQ(ERR_IO_PENDING, rv);
1518
[email protected]a512f5982009-08-18 16:01:061519 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211520 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1521 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571522 EXPECT_EQ(ERR_IO_PENDING, rv);
1523
1524 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321525 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571526
[email protected]a512f5982009-08-18 16:01:061527 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211528 rv = req3.handle()->Init("a", params_, kDefaultPriority, &req3, pool_,
1529 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571530 EXPECT_EQ(ERR_IO_PENDING, rv);
1531
1532 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1533 EXPECT_EQ(OK, req2.WaitForResult());
1534 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1535
1536 ASSERT_EQ(3U, request_order_.size());
1537 EXPECT_EQ(&req1, request_order_[0]);
1538 EXPECT_EQ(&req2, request_order_[1]);
1539 EXPECT_EQ(&req3, request_order_[2]);
1540}
1541
[email protected]e6ec67b2010-06-16 00:12:461542TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531543 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571544 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321545 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571546
[email protected]a512f5982009-08-18 16:01:061547 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211548 int rv = req1.handle()->Init("a", params_, kDefaultPriority, &req1, pool_,
1549 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571550 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331551 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571552
1553 MessageLoop::current()->RunAllPending();
1554
[email protected]a512f5982009-08-18 16:01:061555 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211556 rv = req2.handle()->Init("a", params_, kDefaultPriority, &req2, pool_,
1557 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571558 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561559 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1560 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571561}
1562
[email protected]e772db3f2010-07-12 18:11:131563TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1564 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1565 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1566
1567 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211568 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.handle()->Init("a", params_,
1569 kDefaultPriority,
1570 &req, pool_,
1571 BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131572 EXPECT_TRUE(req.handle()->is_initialized());
1573 EXPECT_TRUE(req.handle()->socket());
1574 req.handle()->Reset();
1575}
1576
1577TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1578 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1579
1580 connect_job_factory_->set_job_type(
1581 TestConnectJob::kMockPendingRecoverableJob);
1582 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211583 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1584 &req, pool_, BoundNetLog()));
[email protected]e772db3f2010-07-12 18:11:131585 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1586 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, req.WaitForResult());
1587 EXPECT_TRUE(req.handle()->is_initialized());
1588 EXPECT_TRUE(req.handle()->socket());
1589 req.handle()->Reset();
1590}
1591
[email protected]e60e47a2010-07-14 03:37:181592TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1593 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1594 connect_job_factory_->set_job_type(
1595 TestConnectJob::kMockAdditionalErrorStateJob);
1596
1597 TestSocketRequest req(&request_order_, &completion_count_);
1598 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
1599 kDefaultPriority, &req,
1600 pool_, BoundNetLog()));
1601 EXPECT_FALSE(req.handle()->is_initialized());
1602 EXPECT_FALSE(req.handle()->socket());
1603 EXPECT_TRUE(req.handle()->is_ssl_error());
1604 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
1605 req.handle()->Reset();
1606}
1607
1608TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1609 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1610
1611 connect_job_factory_->set_job_type(
1612 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1613 TestSocketRequest req(&request_order_, &completion_count_);
1614 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1615 &req, pool_, BoundNetLog()));
1616 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1617 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1618 EXPECT_FALSE(req.handle()->is_initialized());
1619 EXPECT_FALSE(req.handle()->socket());
1620 EXPECT_TRUE(req.handle()->is_ssl_error());
1621 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
1622 req.handle()->Reset();
1623}
1624
[email protected]4d3b05d2010-01-27 21:27:291625TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161626 CreatePoolWithIdleTimeouts(
1627 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1628 base::TimeDelta(), // Time out unused sockets immediately.
1629 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1630
1631 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1632
1633 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1634
1635 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211636 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161637 EXPECT_EQ(ERR_IO_PENDING, rv);
1638 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1639
1640 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211641 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161642 EXPECT_EQ(ERR_IO_PENDING, rv);
1643 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1644
1645 // Cancel one of the requests. Wait for the other, which will get the first
1646 // job. Release the socket. Run the loop again to make sure the second
1647 // socket is sitting idle and the first one is released (since ReleaseSocket()
1648 // just posts a DoReleaseSocket() task).
1649
1650 req.handle()->Reset();
1651 EXPECT_EQ(OK, req2.WaitForResult());
1652 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471653
1654 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1655 // actually become pending until 2ms after they have been created. In order
1656 // to flush all tasks, we need to wait so that we know there are no
1657 // soon-to-be-pending tasks waiting.
1658 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161659 MessageLoop::current()->RunAllPending();
1660
1661 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041662
[email protected]9bf28db2009-08-29 01:35:161663 // Invoke the idle socket cleanup check. Only one socket should be left, the
1664 // used socket. Request it to make sure that it's used.
1665
1666 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531667 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211668 rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161669 EXPECT_EQ(OK, rv);
1670 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151671 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451672 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161673}
1674
[email protected]2041cf342010-02-19 03:15:591675// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161676// because of multiple releasing disconnected sockets.
1677TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1678 CreatePoolWithIdleTimeouts(
1679 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1680 base::TimeDelta(), // Time out unused sockets immediately.
1681 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1682
1683 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1684
1685 // Startup 4 connect jobs. Two of them will be pending.
1686
1687 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211688 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161689 EXPECT_EQ(OK, rv);
1690
1691 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211692 rv = req2.handle()->Init("a", params_, LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161693 EXPECT_EQ(OK, rv);
1694
1695 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211696 rv = req3.handle()->Init("a", params_, LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161697 EXPECT_EQ(ERR_IO_PENDING, rv);
1698
1699 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211700 rv = req4.handle()->Init("a", params_, LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161701 EXPECT_EQ(ERR_IO_PENDING, rv);
1702
1703 // Release two disconnected sockets.
1704
1705 req.handle()->socket()->Disconnect();
1706 req.handle()->Reset();
1707 req2.handle()->socket()->Disconnect();
1708 req2.handle()->Reset();
1709
1710 EXPECT_EQ(OK, req3.WaitForResult());
1711 EXPECT_FALSE(req3.handle()->is_reused());
1712 EXPECT_EQ(OK, req4.WaitForResult());
1713 EXPECT_FALSE(req4.handle()->is_reused());
1714}
1715
[email protected]d7027bb2010-05-10 18:58:541716// Regression test for http://crbug.com/42267.
1717// When DoReleaseSocket() is processed for one socket, it is blocked because the
1718// other stalled groups all have releasing sockets, so no progress can be made.
1719TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1720 CreatePoolWithIdleTimeouts(
1721 4 /* socket limit */, 4 /* socket limit per group */,
1722 base::TimeDelta(), // Time out unused sockets immediately.
1723 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1724
1725 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1726
1727 // Max out the socket limit with 2 per group.
1728
1729 scoped_ptr<TestSocketRequest> req_a[4];
1730 scoped_ptr<TestSocketRequest> req_b[4];
1731
1732 for (int i = 0; i < 2; ++i) {
1733 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1734 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211735 EXPECT_EQ(OK, req_a[i]->handle()->Init("a", params_, LOWEST, req_a[i].get(),
1736 pool_, BoundNetLog()));
1737 EXPECT_EQ(OK, req_b[i]->handle()->Init("b", params_, LOWEST, req_b[i].get(),
1738 pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541739 }
[email protected]b89f7e42010-05-20 20:37:001740
[email protected]d7027bb2010-05-10 18:58:541741 // Make 4 pending requests, 2 per group.
1742
1743 for (int i = 2; i < 4; ++i) {
1744 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1745 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
[email protected]df4b4ef2010-07-12 18:25:211746 EXPECT_EQ(ERR_IO_PENDING, req_a[i]->handle()->Init("a", params_, LOWEST,
1747 req_a[i].get(), pool_,
1748 BoundNetLog()));
1749 EXPECT_EQ(ERR_IO_PENDING, req_b[i]->handle()->Init("b", params_, LOWEST,
1750 req_b[i].get(), pool_,
1751 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541752 }
1753
1754 // Release b's socket first. The order is important, because in
1755 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1756 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1757 // first, which has a releasing socket, so it refuses to start up another
1758 // ConnectJob. So, we used to infinite loop on this.
1759 req_b[0]->handle()->socket()->Disconnect();
1760 req_b[0]->handle()->Reset();
1761 req_a[0]->handle()->socket()->Disconnect();
1762 req_a[0]->handle()->Reset();
1763
1764 // Used to get stuck here.
1765 MessageLoop::current()->RunAllPending();
1766
1767 req_b[1]->handle()->socket()->Disconnect();
1768 req_b[1]->handle()->Reset();
1769 req_a[1]->handle()->socket()->Disconnect();
1770 req_a[1]->handle()->Reset();
1771
1772 for (int i = 2; i < 4; ++i) {
1773 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1774 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1775 }
1776}
1777
[email protected]fd4fe0b2010-02-08 23:02:151778TEST_F(ClientSocketPoolBaseTest,
1779 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1780 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1781
1782 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1783
1784 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1787 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1788
1789 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1790 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1791 EXPECT_EQ(2u, completion_count_);
1792
1793 // Releases one connection.
1794 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1795 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1796
1797 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1798 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1799 EXPECT_EQ(4u, completion_count_);
1800
1801 EXPECT_EQ(1, GetOrderOfRequest(1));
1802 EXPECT_EQ(2, GetOrderOfRequest(2));
1803 EXPECT_EQ(3, GetOrderOfRequest(3));
1804 EXPECT_EQ(4, GetOrderOfRequest(4));
1805
1806 // Make sure we test order of all requests made.
1807 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1808}
1809
[email protected]4f1e4982010-03-02 18:31:041810class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1811 public:
[email protected]e60e47a2010-07-14 03:37:181812 TestReleasingSocketRequest(TestClientSocketPool* pool, int expected_result,
1813 bool reset_releasing_handle)
1814 : pool_(pool),
1815 expected_result_(expected_result),
1816 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:041817
1818 ClientSocketHandle* handle() { return &handle_; }
1819
1820 int WaitForResult() {
1821 return callback_.WaitForResult();
1822 }
1823
1824 virtual void RunWithParams(const Tuple1<int>& params) {
1825 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:181826 if (reset_releasing_handle_)
1827 handle_.Reset();
[email protected]df4b4ef2010-07-12 18:25:211828 scoped_refptr<TestSocketParams> con_params = new TestSocketParams();
[email protected]e60e47a2010-07-14 03:37:181829 EXPECT_EQ(expected_result_, handle2_.Init("a", con_params, kDefaultPriority,
1830 &callback2_, pool_,
1831 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041832 }
1833
1834 private:
[email protected]df4b4ef2010-07-12 18:25:211835 scoped_refptr<TestClientSocketPool> pool_;
[email protected]e60e47a2010-07-14 03:37:181836 int expected_result_;
1837 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:041838 ClientSocketHandle handle_;
1839 ClientSocketHandle handle2_;
1840 TestCompletionCallback callback_;
1841 TestCompletionCallback callback2_;
1842};
1843
[email protected]e60e47a2010-07-14 03:37:181844
1845TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
1846 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1847
1848 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1849 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1850 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1851
1852 EXPECT_EQ(static_cast<int>(requests_.size()),
1853 client_socket_factory_.allocation_count());
1854
1855 connect_job_factory_->set_job_type(
1856 TestConnectJob::kMockPendingAdditionalErrorStateJob);
1857 TestReleasingSocketRequest req(pool_.get(), OK, false);
1858 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1859 &req, pool_, BoundNetLog()));
1860 // The next job should complete synchronously
1861 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1862
1863 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1864 EXPECT_FALSE(req.handle()->is_initialized());
1865 EXPECT_FALSE(req.handle()->socket());
1866 EXPECT_TRUE(req.handle()->is_ssl_error());
1867 EXPECT_FALSE(req.handle()->tunnel_auth_response_info().headers.get() == NULL);
1868}
1869
[email protected]b6501d3d2010-06-03 23:53:341870// http://crbug.com/44724 regression test.
1871// We start releasing the pool when we flush on network change. When that
1872// happens, the only active references are in the ClientSocketHandles. When a
1873// ConnectJob completes and calls back into the last ClientSocketHandle, that
1874// callback can release the last reference and delete the pool. After the
1875// callback finishes, we go back to the stack frame within the now-deleted pool.
1876// Executing any code that refers to members of the now-deleted pool can cause
1877// crashes.
1878TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1879 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1880 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1881
1882 ClientSocketHandle handle;
1883 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211884 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1885 &callback, pool_, BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:341886
1887 // Simulate flushing the pool.
1888 pool_ = NULL;
1889
1890 // We'll call back into this now.
1891 callback.WaitForResult();
1892}
1893
[email protected]a7e38572010-06-07 18:22:241894TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1895 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1896 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1897
1898 ClientSocketHandle handle;
1899 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211900 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1901 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241902 EXPECT_EQ(OK, callback.WaitForResult());
1903 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1904
1905 pool_->Flush();
1906
1907 handle.Reset();
1908 MessageLoop::current()->RunAllPending();
1909
[email protected]df4b4ef2010-07-12 18:25:211910 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1911 &callback, pool_, BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:241912 EXPECT_EQ(OK, callback.WaitForResult());
1913 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1914}
1915
[email protected]25eea382010-07-10 23:55:261916// Cancel a pending socket request while we're at max sockets,
1917// and verify that the backup socket firing doesn't cause a crash.
1918TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
1919 // Max 4 sockets globally, max 4 sockets per group.
1920 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1921 pool_->EnableBackupJobs();
1922
1923 // Create the first socket and set to ERR_IO_PENDING. This creates a
1924 // backup job.
1925 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1926 ClientSocketHandle handle;
1927 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211928 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
1929 &callback, pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261930
1931 // Start (MaxSockets - 1) connected sockets to reach max sockets.
1932 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1933 ClientSocketHandle handles[kDefaultMaxSockets];
1934 for (int i = 1; i < kDefaultMaxSockets; ++i) {
1935 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211936 EXPECT_EQ(OK, handles[i].Init("bar", params_, kDefaultPriority, &callback,
1937 pool_, BoundNetLog()));
[email protected]25eea382010-07-10 23:55:261938 }
1939
1940 MessageLoop::current()->RunAllPending();
1941
1942 // Cancel the pending request.
1943 handle.Reset();
1944
1945 // Wait for the backup timer to fire (add some slop to ensure it fires)
1946 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
1947
1948 MessageLoop::current()->RunAllPending();
1949 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1950}
1951
[email protected]eb5a99382010-07-11 03:18:261952// Test delayed socket binding for the case where we have two connects,
1953// and while one is waiting on a connect, the other frees up.
1954// The socket waiting on a connect should switch immediately to the freed
1955// up socket.
1956TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
1957 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1958 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1959
1960 ClientSocketHandle handle1;
1961 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211962 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
1963 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261964 EXPECT_EQ(OK, callback.WaitForResult());
1965
1966 // No idle sockets, no pending jobs.
1967 EXPECT_EQ(0, pool_->IdleSocketCount());
1968 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1969
1970 // Create a second socket to the same host, but this one will wait.
1971 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1972 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:211973 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
1974 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261975 // No idle sockets, and one connecting job.
1976 EXPECT_EQ(0, pool_->IdleSocketCount());
1977 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1978
1979 // Return the first handle to the pool. This will initiate the delayed
1980 // binding.
1981 handle1.Reset();
1982
1983 MessageLoop::current()->RunAllPending();
1984
1985 // Still no idle sockets, still one pending connect job.
1986 EXPECT_EQ(0, pool_->IdleSocketCount());
1987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1988
1989 // The second socket connected, even though it was a Waiting Job.
1990 EXPECT_EQ(OK, callback.WaitForResult());
1991
1992 // And we can see there is still one job waiting.
1993 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
1994
1995 // Finally, signal the waiting Connect.
1996 client_socket_factory_.SignalJobs();
1997 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
1998
1999 MessageLoop::current()->RunAllPending();
2000}
2001
2002// Test delayed socket binding when a group is at capacity and one
2003// of the group's sockets frees up.
2004TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2005 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2006 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2007
2008 ClientSocketHandle handle1;
2009 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212010 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2011 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262012 EXPECT_EQ(OK, callback.WaitForResult());
2013
2014 // No idle sockets, no pending jobs.
2015 EXPECT_EQ(0, pool_->IdleSocketCount());
2016 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2017
2018 // Create a second socket to the same host, but this one will wait.
2019 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2020 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212021 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2022 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262023 // No idle sockets, and one connecting job.
2024 EXPECT_EQ(0, pool_->IdleSocketCount());
2025 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2026
2027 // Return the first handle to the pool. This will initiate the delayed
2028 // binding.
2029 handle1.Reset();
2030
2031 MessageLoop::current()->RunAllPending();
2032
2033 // Still no idle sockets, still one pending connect job.
2034 EXPECT_EQ(0, pool_->IdleSocketCount());
2035 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2036
2037 // The second socket connected, even though it was a Waiting Job.
2038 EXPECT_EQ(OK, callback.WaitForResult());
2039
2040 // And we can see there is still one job waiting.
2041 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2042
2043 // Finally, signal the waiting Connect.
2044 client_socket_factory_.SignalJobs();
2045 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2046
2047 MessageLoop::current()->RunAllPending();
2048}
2049
2050// Test out the case where we have one socket connected, one
2051// connecting, when the first socket finishes and goes idle.
2052// Although the second connection is pending, th second request
2053// should complete, by taking the first socket's idle socket.
2054TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2056 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2057
2058 ClientSocketHandle handle1;
2059 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:212060 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", params_, kDefaultPriority,
2061 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262062 EXPECT_EQ(OK, callback.WaitForResult());
2063
2064 // No idle sockets, no pending jobs.
2065 EXPECT_EQ(0, pool_->IdleSocketCount());
2066 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2067
2068 // Create a second socket to the same host, but this one will wait.
2069 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2070 ClientSocketHandle handle2;
[email protected]df4b4ef2010-07-12 18:25:212071 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a", params_, kDefaultPriority,
2072 &callback, pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262073 // No idle sockets, and one connecting job.
2074 EXPECT_EQ(0, pool_->IdleSocketCount());
2075 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2076
2077 // Return the first handle to the pool. This will initiate the delayed
2078 // binding.
2079 handle1.Reset();
2080
2081 MessageLoop::current()->RunAllPending();
2082
2083 // Still no idle sockets, still one pending connect job.
2084 EXPECT_EQ(0, pool_->IdleSocketCount());
2085 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2086
2087 // The second socket connected, even though it was a Waiting Job.
2088 EXPECT_EQ(OK, callback.WaitForResult());
2089
2090 // And we can see there is still one job waiting.
2091 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2092
2093 // Finally, signal the waiting Connect.
2094 client_socket_factory_.SignalJobs();
2095 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2096
2097 MessageLoop::current()->RunAllPending();
2098}
2099
[email protected]f6d1d6eb2009-06-24 20:16:092100} // namespace
2101
2102} // namespace net