blob: 55f1949ad7df438ced599951817d9ff903c42414 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]43a21b82010-06-10 21:30:5413#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5314#include "net/base/net_log.h"
15#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3117#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0918#include "net/base/test_completion_callback.h"
19#include "net/socket/client_socket.h"
20#include "net/socket/client_socket_factory.h"
21#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0022#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1723#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0924#include "testing/gtest/include/gtest/gtest.h"
25
26namespace net {
27
28namespace {
29
[email protected]211d21722009-07-22 15:48:5330const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2031const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5232const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0133
[email protected]df4b4ef2010-07-12 18:25:2134class TestSocketParams : public base::RefCounted<TestSocketParams> {
35 private:
36 friend class base::RefCounted<TestSocketParams>;
37 ~TestSocketParams() {}
38};
[email protected]7fc5b09a2010-02-27 00:07:3839typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4940
[email protected]f6d1d6eb2009-06-24 20:16:0941class MockClientSocket : public ClientSocket {
42 public:
43 MockClientSocket() : connected_(false) {}
44
[email protected]ab838892009-06-30 18:49:0545 // Socket methods:
46 virtual int Read(
47 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
48 return ERR_UNEXPECTED;
49 }
50
51 virtual int Write(
52 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53 return ERR_UNEXPECTED;
54 }
[email protected]06650c52010-06-03 00:49:1755 virtual bool SetReceiveBufferSize(int32 size) { return true; }
56 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0557
[email protected]f6d1d6eb2009-06-24 20:16:0958 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0559
[email protected]a2006ece2010-04-23 16:44:0260 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0961 connected_ = true;
62 return OK;
63 }
[email protected]f6d1d6eb2009-06-24 20:16:0964
[email protected]ab838892009-06-30 18:49:0565 virtual void Disconnect() { connected_ = false; }
66 virtual bool IsConnected() const { return connected_; }
67 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0168
[email protected]ac9eec62010-02-20 18:50:3869 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1670 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0971 }
[email protected]f6d1d6eb2009-06-24 20:16:0972
[email protected]a2006ece2010-04-23 16:44:0273 virtual const BoundNetLog& NetLog() const {
74 return net_log_;
75 }
76
[email protected]f6d1d6eb2009-06-24 20:16:0977 private:
78 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0279 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0980
[email protected]ab838892009-06-30 18:49:0581 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0982};
83
[email protected]5fc08e32009-07-15 17:09:5784class TestConnectJob;
85
[email protected]f6d1d6eb2009-06-24 20:16:0986class MockClientSocketFactory : public ClientSocketFactory {
87 public:
[email protected]ab838892009-06-30 18:49:0588 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0989
[email protected]a2006ece2010-04-23 16:44:0290 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
91 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0992 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0593 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0994 }
95
96 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:1897 ClientSocketHandle* transport_socket,
[email protected]f6d1d6eb2009-06-24 20:16:0998 const std::string& hostname,
99 const SSLConfig& ssl_config) {
100 NOTIMPLEMENTED();
101 return NULL;
102 }
103
[email protected]5fc08e32009-07-15 17:09:57104 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
105 void SignalJobs();
106
[email protected]f6d1d6eb2009-06-24 20:16:09107 int allocation_count() const { return allocation_count_; }
108
[email protected]f6d1d6eb2009-06-24 20:16:09109 private:
110 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57111 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09112};
113
[email protected]ab838892009-06-30 18:49:05114class TestConnectJob : public ConnectJob {
115 public:
116 enum JobType {
117 kMockJob,
118 kMockFailingJob,
119 kMockPendingJob,
120 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57121 kMockWaitingJob,
122 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13123 kMockRecoverableJob,
124 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18125 kMockAdditionalErrorStateJob,
126 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05127 };
128
[email protected]994d4932010-07-12 17:55:13129 // The kMockPendingJob uses a slight delay before allowing the connect
130 // to complete.
131 static const int kPendingConnectDelay = 2;
132
[email protected]ab838892009-06-30 18:49:05133 TestConnectJob(JobType job_type,
134 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49135 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34136 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05137 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30138 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17139 NetLog* net_log)
140 : ConnectJob(group_name, timeout_duration, delegate,
141 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58142 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05143 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21144 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18145 load_state_(LOAD_STATE_IDLE),
146 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05147
[email protected]974ebd62009-08-03 23:14:34148 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13149 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34150 }
151
[email protected]46451352009-09-01 14:54:21152 virtual LoadState GetLoadState() const { return load_state_; }
153
[email protected]e60e47a2010-07-14 03:37:18154 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
155 if (store_additional_error_state_) {
156 // Set all of the additional error state fields in some way.
157 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43158 HttpResponseInfo info;
159 info.headers = new HttpResponseHeaders("");
160 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18161 }
162 }
163
[email protected]974ebd62009-08-03 23:14:34164 private:
[email protected]ab838892009-06-30 18:49:05165 // ConnectJob methods:
166
[email protected]974ebd62009-08-03 23:14:34167 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05168 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02169 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40170 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05171 switch (job_type_) {
172 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13173 return DoConnect(true /* successful */, false /* sync */,
174 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05175 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13176 return DoConnect(false /* error */, false /* sync */,
177 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05178 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57179 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47180
181 // Depending on execution timings, posting a delayed task can result
182 // in the task getting executed the at the earliest possible
183 // opportunity or only after returning once from the message loop and
184 // then a second call into the message loop. In order to make behavior
185 // more deterministic, we change the default delay to 2ms. This should
186 // always require us to wait for the second call into the message loop.
187 //
188 // N.B. The correct fix for this and similar timing problems is to
189 // abstract time for the purpose of unittests. Unfortunately, we have
190 // a lot of third-party components that directly call the various
191 // time functions, so this change would be rather invasive.
192 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05193 FROM_HERE,
194 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47195 &TestConnectJob::DoConnect,
196 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13197 true /* async */,
198 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13199 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05200 return ERR_IO_PENDING;
201 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57202 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47203 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05204 FROM_HERE,
205 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47206 &TestConnectJob::DoConnect,
207 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13208 true /* async */,
209 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47210 2);
[email protected]ab838892009-06-30 18:49:05211 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57212 case kMockWaitingJob:
213 client_socket_factory_->WaitForSignal(this);
214 waiting_success_ = true;
215 return ERR_IO_PENDING;
216 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46217 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57218 FROM_HERE,
219 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46220 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57221 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13222 case kMockRecoverableJob:
223 return DoConnect(false /* error */, false /* sync */,
224 true /* recoverable */);
225 case kMockPendingRecoverableJob:
226 set_load_state(LOAD_STATE_CONNECTING);
227 MessageLoop::current()->PostDelayedTask(
228 FROM_HERE,
229 method_factory_.NewRunnableMethod(
230 &TestConnectJob::DoConnect,
231 false /* error */,
232 true /* async */,
233 true /* recoverable */),
234 2);
235 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18236 case kMockAdditionalErrorStateJob:
237 store_additional_error_state_ = true;
238 return DoConnect(false /* error */, false /* sync */,
239 false /* recoverable */);
240 case kMockPendingAdditionalErrorStateJob:
241 set_load_state(LOAD_STATE_CONNECTING);
242 store_additional_error_state_ = true;
243 MessageLoop::current()->PostDelayedTask(
244 FROM_HERE,
245 method_factory_.NewRunnableMethod(
246 &TestConnectJob::DoConnect,
247 false /* error */,
248 true /* async */,
249 false /* recoverable */),
250 2);
251 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05252 default:
253 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40254 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05255 return ERR_FAILED;
256 }
257 }
258
[email protected]46451352009-09-01 14:54:21259 void set_load_state(LoadState load_state) { load_state_ = load_state; }
260
[email protected]e772db3f2010-07-12 18:11:13261 int DoConnect(bool succeed, bool was_async, bool recoverable) {
262 int result = OK;
[email protected]ab838892009-06-30 18:49:05263 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02264 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13265 } else if (recoverable) {
266 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40267 } else {
[email protected]e772db3f2010-07-12 18:11:13268 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40269 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05270 }
[email protected]2ab05b52009-07-01 23:57:58271
272 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30273 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05274 return result;
275 }
276
[email protected]cfa8228c2010-06-17 01:07:56277 // This function helps simulate the progress of load states on a ConnectJob.
278 // Each time it is called it advances the load state and posts a task to be
279 // called again. It stops at the last connecting load state (the one
280 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57281 void AdvanceLoadState(LoadState state) {
282 int tmp = state;
283 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56284 if (tmp < LOAD_STATE_SENDING_REQUEST) {
285 state = static_cast<LoadState>(tmp);
286 set_load_state(state);
287 MessageLoop::current()->PostTask(
288 FROM_HERE,
289 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
290 state));
291 }
[email protected]5fc08e32009-07-15 17:09:57292 }
293
294 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05295 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57296 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05297 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21298 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18299 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05300
301 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
302};
303
[email protected]d80a4322009-08-14 07:07:49304class TestConnectJobFactory
305 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05306 public:
[email protected]5fc08e32009-07-15 17:09:57307 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05308 : job_type_(TestConnectJob::kMockJob),
309 client_socket_factory_(client_socket_factory) {}
310
311 virtual ~TestConnectJobFactory() {}
312
313 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
314
[email protected]974ebd62009-08-03 23:14:34315 void set_timeout_duration(base::TimeDelta timeout_duration) {
316 timeout_duration_ = timeout_duration;
317 }
318
[email protected]ab838892009-06-30 18:49:05319 // ConnectJobFactory methods:
320
321 virtual ConnectJob* NewConnectJob(
322 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49323 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17324 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05325 return new TestConnectJob(job_type_,
326 group_name,
327 request,
[email protected]974ebd62009-08-03 23:14:34328 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05329 delegate,
[email protected]fd7b7c92009-08-20 19:38:30330 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17331 NULL);
[email protected]ab838892009-06-30 18:49:05332 }
333
[email protected]a796bcec2010-03-22 17:17:26334 virtual base::TimeDelta ConnectionTimeout() const {
335 return timeout_duration_;
336 }
337
[email protected]ab838892009-06-30 18:49:05338 private:
339 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34340 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57341 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05342
343 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
344};
345
346class TestClientSocketPool : public ClientSocketPool {
347 public:
348 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53349 int max_sockets,
[email protected]ab838892009-06-30 18:49:05350 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00351 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16352 base::TimeDelta unused_idle_socket_timeout,
353 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49354 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00355 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16356 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38357 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05358
359 virtual int RequestSocket(
360 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49361 const void* params,
[email protected]ac790b42009-12-02 04:31:31362 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05363 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46364 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53365 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21366 const scoped_refptr<TestSocketParams>* casted_socket_params =
367 static_cast<const scoped_refptr<TestSocketParams>*>(params);
368 return base_.RequestSocket(group_name, *casted_socket_params, priority,
369 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05370 }
371
372 virtual void CancelRequest(
373 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21374 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49375 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05376 }
377
378 virtual void ReleaseSocket(
379 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24380 ClientSocket* socket,
381 int id) {
382 base_.ReleaseSocket(group_name, socket, id);
383 }
384
385 virtual void Flush() {
386 base_.Flush();
[email protected]ab838892009-06-30 18:49:05387 }
388
389 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49390 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05391 }
392
[email protected]d80a4322009-08-14 07:07:49393 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05394
395 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49396 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05397 }
398
399 virtual LoadState GetLoadState(const std::string& group_name,
400 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49401 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05402 }
403
[email protected]a796bcec2010-03-22 17:17:26404 virtual base::TimeDelta ConnectionTimeout() const {
405 return base_.ConnectionTimeout();
406 }
407
[email protected]b89f7e42010-05-20 20:37:00408 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
409 return base_.histograms();
410 }
[email protected]a796bcec2010-03-22 17:17:26411
[email protected]d80a4322009-08-14 07:07:49412 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20413
[email protected]974ebd62009-08-03 23:14:34414 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49415 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34416 }
417
[email protected]9bf28db2009-08-29 01:35:16418 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
419
[email protected]43a21b82010-06-10 21:30:54420 void EnableBackupJobs() { base_.EnableBackupJobs(); }
421
[email protected]ab838892009-06-30 18:49:05422 private:
[email protected]5389bc72009-11-05 23:34:24423 ~TestClientSocketPool() {}
424
[email protected]d80a4322009-08-14 07:07:49425 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05426
427 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
428};
429
[email protected]a937a06d2009-08-19 21:19:24430} // namespace
431
[email protected]7fc5b09a2010-02-27 00:07:38432REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24433
434namespace {
435
[email protected]5fc08e32009-07-15 17:09:57436void MockClientSocketFactory::SignalJobs() {
437 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
438 it != waiting_jobs_.end(); ++it) {
439 (*it)->Signal();
440 }
441 waiting_jobs_.clear();
442}
443
[email protected]974ebd62009-08-03 23:14:34444class TestConnectJobDelegate : public ConnectJob::Delegate {
445 public:
446 TestConnectJobDelegate()
447 : have_result_(false), waiting_for_result_(false), result_(OK) {}
448 virtual ~TestConnectJobDelegate() {}
449
450 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
451 result_ = result;
[email protected]6e713f02009-08-06 02:56:40452 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07453 // socket.get() should be NULL iff result != OK
454 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34455 delete job;
456 have_result_ = true;
457 if (waiting_for_result_)
458 MessageLoop::current()->Quit();
459 }
460
461 int WaitForResult() {
462 DCHECK(!waiting_for_result_);
463 while (!have_result_) {
464 waiting_for_result_ = true;
465 MessageLoop::current()->Run();
466 waiting_for_result_ = false;
467 }
468 have_result_ = false; // auto-reset for next callback
469 return result_;
470 }
471
472 private:
473 bool have_result_;
474 bool waiting_for_result_;
475 int result_;
476};
477
[email protected]75439d3b2009-07-23 22:11:17478class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09479 protected:
[email protected]b89f7e42010-05-20 20:37:00480 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21481 : params_(new TestSocketParams()),
482 histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20483
[email protected]211d21722009-07-22 15:48:53484 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16485 CreatePoolWithIdleTimeouts(
486 max_sockets,
487 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00488 base::TimeDelta::FromSeconds(
489 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16490 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
491 }
492
493 void CreatePoolWithIdleTimeouts(
494 int max_sockets, int max_sockets_per_group,
495 base::TimeDelta unused_idle_socket_timeout,
496 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20497 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04498 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53499 pool_ = new TestClientSocketPool(max_sockets,
500 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00501 histograms_,
[email protected]9bf28db2009-08-29 01:35:16502 unused_idle_socket_timeout,
503 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20504 connect_job_factory_);
505 }
[email protected]f6d1d6eb2009-06-24 20:16:09506
[email protected]ac790b42009-12-02 04:31:31507 int StartRequest(const std::string& group_name,
508 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38509 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]df4b4ef2010-07-12 18:25:21510 pool_, group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09511 }
512
513 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47514 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
515 // actually become pending until 2ms after they have been created. In order
516 // to flush all tasks, we need to wait so that we know there are no
517 // soon-to-be-pending tasks waiting.
518 PlatformThread::Sleep(10);
519 MessageLoop::current()->RunAllPending();
520
[email protected]211d21722009-07-22 15:48:53521 // Need to delete |pool_| before we turn late binding back off. We also need
522 // to delete |requests_| because the pool is reference counted and requests
523 // keep reference to it.
524 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]05ea9ff2010-07-15 19:08:21525 TestClientSocketPool* pool = pool_.get();
[email protected]5fc08e32009-07-15 17:09:57526 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53527 requests_.reset();
[email protected]05ea9ff2010-07-15 19:08:21528 pool = NULL;
[email protected]211d21722009-07-22 15:48:53529
[email protected]75439d3b2009-07-23 22:11:17530 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09531 }
532
[email protected]f6d1d6eb2009-06-24 20:16:09533 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04534 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21535 scoped_refptr<TestSocketParams> params_;
[email protected]c9d6a1d2009-07-14 16:15:20536 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00537 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09538};
539
[email protected]974ebd62009-08-03 23:14:34540// Even though a timeout is specified, it doesn't time out on a synchronous
541// completion.
542TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
543 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06544 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49545 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21546 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34547 scoped_ptr<TestConnectJob> job(
548 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12549 "a",
[email protected]974ebd62009-08-03 23:14:34550 request,
551 base::TimeDelta::FromMicroseconds(1),
552 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30553 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17554 NULL));
[email protected]974ebd62009-08-03 23:14:34555 EXPECT_EQ(OK, job->Connect());
556}
557
558TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
559 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06560 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17561 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53562
[email protected]d80a4322009-08-14 07:07:49563 TestClientSocketPoolBase::Request request(
[email protected]df4b4ef2010-07-12 18:25:21564 &ignored, NULL, kDefaultPriority, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34565 // Deleted by TestConnectJobDelegate.
566 TestConnectJob* job =
567 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12568 "a",
[email protected]974ebd62009-08-03 23:14:34569 request,
570 base::TimeDelta::FromMicroseconds(1),
571 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30572 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17573 &log);
[email protected]974ebd62009-08-03 23:14:34574 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
575 PlatformThread::Sleep(1);
576 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30577
[email protected]06650c52010-06-03 00:49:17578 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46579 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53580 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17581 EXPECT_TRUE(LogContainsBeginEvent(
582 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46583 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17584 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
585 NetLog::PHASE_NONE));
586 EXPECT_TRUE(LogContainsEvent(
587 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53588 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46589 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17590 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
591 EXPECT_TRUE(LogContainsEndEvent(
592 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34593}
594
[email protected]5fc08e32009-07-15 17:09:57595TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53596 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20597
[email protected]f6d1d6eb2009-06-24 20:16:09598 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06599 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53600 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
601
[email protected]df4b4ef2010-07-12 18:25:21602 EXPECT_EQ(OK, handle.Init("a", params_, kDefaultPriority, &callback, pool_,
603 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09604 EXPECT_TRUE(handle.is_initialized());
605 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09606 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30607
[email protected]06650c52010-06-03 00:49:17608 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46609 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53610 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53611 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17612 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
613 NetLog::PHASE_NONE));
614 EXPECT_TRUE(LogContainsEvent(
615 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53616 NetLog::PHASE_NONE));
617 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17618 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09619}
620
[email protected]ab838892009-06-30 18:49:05621TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53622 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20623
[email protected]ab838892009-06-30 18:49:05624 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53625 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
626
[email protected]a512f5982009-08-18 16:01:06627 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]e60e47a2010-07-14 03:37:18628 // Set the additional error state members to ensure that they get cleared.
629 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43630 HttpResponseInfo info;
631 info.headers = new HttpResponseHeaders("");
632 req.handle()->set_ssl_error_response_info(info);
[email protected]df4b4ef2010-07-12 18:25:21633 EXPECT_EQ(ERR_CONNECTION_FAILED, req.handle()->Init("a", params_,
634 kDefaultPriority, &req,
635 pool_, log.bound()));
[email protected]e772db3f2010-07-12 18:11:13636 EXPECT_FALSE(req.handle()->socket());
[email protected]e60e47a2010-07-14 03:37:18637 EXPECT_FALSE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:43638 EXPECT_TRUE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30639
[email protected]06650c52010-06-03 00:49:17640 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27641 EXPECT_TRUE(LogContainsBeginEvent(
642 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17643 EXPECT_TRUE(LogContainsEvent(
644 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
645 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02646 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17647 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09648}
649
[email protected]211d21722009-07-22 15:48:53650TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
651 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
652
[email protected]9e743cd2010-03-16 07:03:53653 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30654
[email protected]211d21722009-07-22 15:48:53655 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
656 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
657 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
658 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
659
660 EXPECT_EQ(static_cast<int>(requests_.size()),
661 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17662 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53663
664 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
666 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
667
[email protected]43a21b82010-06-10 21:30:54668 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53669
670 EXPECT_EQ(static_cast<int>(requests_.size()),
671 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17672 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53673
674 EXPECT_EQ(1, GetOrderOfRequest(1));
675 EXPECT_EQ(2, GetOrderOfRequest(2));
676 EXPECT_EQ(3, GetOrderOfRequest(3));
677 EXPECT_EQ(4, GetOrderOfRequest(4));
678 EXPECT_EQ(5, GetOrderOfRequest(5));
679 EXPECT_EQ(6, GetOrderOfRequest(6));
680 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17681
682 // Make sure we test order of all requests made.
683 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53684}
685
686TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
687 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
688
[email protected]9e743cd2010-03-16 07:03:53689 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30690
[email protected]211d21722009-07-22 15:48:53691 // Reach all limits: max total sockets, and max sockets per group.
692 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
693 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
694 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
695 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
696
697 EXPECT_EQ(static_cast<int>(requests_.size()),
698 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17699 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53700
701 // Now create a new group and verify that we don't starve it.
702 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
703
[email protected]43a21b82010-06-10 21:30:54704 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(static_cast<int>(requests_.size()),
707 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17708 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53709
710 EXPECT_EQ(1, GetOrderOfRequest(1));
711 EXPECT_EQ(2, GetOrderOfRequest(2));
712 EXPECT_EQ(3, GetOrderOfRequest(3));
713 EXPECT_EQ(4, GetOrderOfRequest(4));
714 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17715
716 // Make sure we test order of all requests made.
717 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53718}
719
720TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
721 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
722
[email protected]ac790b42009-12-02 04:31:31723 EXPECT_EQ(OK, StartRequest("b", LOWEST));
724 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
725 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
726 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53727
728 EXPECT_EQ(static_cast<int>(requests_.size()),
729 client_socket_factory_.allocation_count());
730
[email protected]ac790b42009-12-02 04:31:31731 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
732 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
733 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53734
[email protected]43a21b82010-06-10 21:30:54735 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53736
[email protected]75439d3b2009-07-23 22:11:17737 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53738
739 // First 4 requests don't have to wait, and finish in order.
740 EXPECT_EQ(1, GetOrderOfRequest(1));
741 EXPECT_EQ(2, GetOrderOfRequest(2));
742 EXPECT_EQ(3, GetOrderOfRequest(3));
743 EXPECT_EQ(4, GetOrderOfRequest(4));
744
[email protected]ac790b42009-12-02 04:31:31745 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
746 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53747 EXPECT_EQ(7, GetOrderOfRequest(5));
748 EXPECT_EQ(6, GetOrderOfRequest(6));
749 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17750
751 // Make sure we test order of all requests made.
752 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53753}
754
755TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
756 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
757
[email protected]ac790b42009-12-02 04:31:31758 EXPECT_EQ(OK, StartRequest("a", LOWEST));
759 EXPECT_EQ(OK, StartRequest("a", LOW));
760 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
761 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53762
763 EXPECT_EQ(static_cast<int>(requests_.size()),
764 client_socket_factory_.allocation_count());
765
[email protected]ac790b42009-12-02 04:31:31766 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
767 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
768 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53769
[email protected]43a21b82010-06-10 21:30:54770 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53771
[email protected]43a21b82010-06-10 21:30:54772 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53773 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17774 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53775
776 // First 4 requests don't have to wait, and finish in order.
777 EXPECT_EQ(1, GetOrderOfRequest(1));
778 EXPECT_EQ(2, GetOrderOfRequest(2));
779 EXPECT_EQ(3, GetOrderOfRequest(3));
780 EXPECT_EQ(4, GetOrderOfRequest(4));
781
782 // Request ("b", 7) has the highest priority, but we can't make new socket for
783 // group "b", because it has reached the per-group limit. Then we make
784 // socket for ("c", 6), because it has higher priority than ("a", 4),
785 // and we still can't make a socket for group "b".
786 EXPECT_EQ(5, GetOrderOfRequest(5));
787 EXPECT_EQ(6, GetOrderOfRequest(6));
788 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17789
790 // Make sure we test order of all requests made.
791 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53792}
793
794// Make sure that we count connecting sockets against the total limit.
795TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
797
798 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
799 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
800 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
801
802 // Create one asynchronous request.
803 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
805
[email protected]6b175382009-10-13 06:47:47806 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
807 // actually become pending until 2ms after they have been created. In order
808 // to flush all tasks, we need to wait so that we know there are no
809 // soon-to-be-pending tasks waiting.
810 PlatformThread::Sleep(10);
811 MessageLoop::current()->RunAllPending();
812
[email protected]211d21722009-07-22 15:48:53813 // The next synchronous request should wait for its turn.
814 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
815 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
816
[email protected]43a21b82010-06-10 21:30:54817 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53818
819 EXPECT_EQ(static_cast<int>(requests_.size()),
820 client_socket_factory_.allocation_count());
821
822 EXPECT_EQ(1, GetOrderOfRequest(1));
823 EXPECT_EQ(2, GetOrderOfRequest(2));
824 EXPECT_EQ(3, GetOrderOfRequest(3));
825 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17826 EXPECT_EQ(5, GetOrderOfRequest(5));
827
828 // Make sure we test order of all requests made.
829 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53830}
831
[email protected]6427fe22010-04-16 22:27:41832TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
833 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
834 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
835
836 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
837 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
838 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
839 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
840
841 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
842
843 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
844
845 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
846 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
847
848 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
849
850 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
851 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
852 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
853 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
854 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
855 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
856 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
857}
858
[email protected]d7027bb2010-05-10 18:58:54859TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
860 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
861 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
862
863 ClientSocketHandle handle;
864 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21865 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
866 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54867
868 ClientSocketHandle handles[4];
869 for (size_t i = 0; i < arraysize(handles); ++i) {
870 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21871 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init("b", params_, kDefaultPriority,
872 &callback, pool_, BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54873 }
874
875 // One will be stalled, cancel all the handles now.
876 // This should hit the OnAvailableSocketSlot() code where we previously had
877 // stalled groups, but no longer have any.
878 for (size_t i = 0; i < arraysize(handles); ++i)
879 handles[i].Reset();
880}
881
[email protected]eb5a99382010-07-11 03:18:26882TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54883 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
884 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
885
[email protected]eb5a99382010-07-11 03:18:26886 {
887 ClientSocketHandle handles[kDefaultMaxSockets];
888 TestCompletionCallback callbacks[kDefaultMaxSockets];
889 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]df4b4ef2010-07-12 18:25:21890 EXPECT_EQ(OK, handles[i].Init(IntToString(i), params_, kDefaultPriority,
891 &callbacks[i], pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26892 }
893
894 // Force a stalled group.
895 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54896 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21897 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
898 kDefaultPriority, &callback,
899 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26900
901 // Cancel the stalled request.
902 stalled_handle.Reset();
903
904 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
905 EXPECT_EQ(0, pool_->IdleSocketCount());
906
907 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54908 }
909
[email protected]43a21b82010-06-10 21:30:54910 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
911 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26912}
[email protected]43a21b82010-06-10 21:30:54913
[email protected]eb5a99382010-07-11 03:18:26914TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
916 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
917
918 {
919 ClientSocketHandle handles[kDefaultMaxSockets];
920 for (int i = 0; i < kDefaultMaxSockets; ++i) {
921 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21922 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(IntToString(i), params_,
923 kDefaultPriority, &callback,
924 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26925 }
926
927 // Force a stalled group.
928 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
929 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54930 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21931 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
932 kDefaultPriority, &callback,
933 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26934
935 // Since it is stalled, it should have no connect jobs.
936 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
937
938 // Cancel the stalled request.
939 handles[0].Reset();
940
[email protected]eb5a99382010-07-11 03:18:26941 // Now we should have a connect job.
942 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
943
944 // The stalled socket should connect.
945 EXPECT_EQ(OK, callback.WaitForResult());
946
947 EXPECT_EQ(kDefaultMaxSockets + 1,
948 client_socket_factory_.allocation_count());
949 EXPECT_EQ(0, pool_->IdleSocketCount());
950 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
951
952 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54953 }
954
[email protected]eb5a99382010-07-11 03:18:26955 EXPECT_EQ(1, pool_->IdleSocketCount());
956}
[email protected]43a21b82010-06-10 21:30:54957
[email protected]eb5a99382010-07-11 03:18:26958TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
959 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
960 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:54961
[email protected]eb5a99382010-07-11 03:18:26962 ClientSocketHandle stalled_handle;
963 TestCompletionCallback callback;
964 {
965 ClientSocketHandle handles[kDefaultMaxSockets];
966 for (int i = 0; i < kDefaultMaxSockets; ++i) {
967 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:21968 EXPECT_EQ(OK, handles[i].Init(StringPrintf("Take 2: %d", i), params_,
969 kDefaultPriority, &callback, pool_,
970 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26971 }
972
973 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
974 EXPECT_EQ(0, pool_->IdleSocketCount());
975
976 // Now we will hit the socket limit.
[email protected]df4b4ef2010-07-12 18:25:21977 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", params_,
978 kDefaultPriority, &callback,
979 pool_, BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26980
981 // Dropping out of scope will close all handles and return them to idle.
982 }
[email protected]43a21b82010-06-10 21:30:54983
984 // But if we wait for it, the released idle sockets will be closed in
985 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:10986 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:26987
988 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
989 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54990}
991
992// Regression test for http://crbug.com/40952.
993TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
994 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
995 pool_->EnableBackupJobs();
996 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
997
998 for (int i = 0; i < kDefaultMaxSockets; ++i) {
999 ClientSocketHandle handle;
1000 TestCompletionCallback callback;
[email protected]df4b4ef2010-07-12 18:25:211001 EXPECT_EQ(OK, handle.Init(IntToString(i), params_, kDefaultPriority,
1002 &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541003 }
1004
1005 // Flush all the DoReleaseSocket tasks.
1006 MessageLoop::current()->RunAllPending();
1007
1008 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1009 // reuse a socket.
1010 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1011 ClientSocketHandle handle;
1012 TestCompletionCallback callback;
1013
1014 // "0" is special here, since it should be the first entry in the sorted map,
1015 // which is the one which we would close an idle socket for. We shouldn't
1016 // close an idle socket though, since we should reuse the idle socket.
[email protected]df4b4ef2010-07-12 18:25:211017 EXPECT_EQ(OK, handle.Init("0", params_, kDefaultPriority, &callback, pool_,
1018 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541019
1020 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1021 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1022}
1023
[email protected]ab838892009-06-30 18:49:051024TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531025 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091026
[email protected]c9d6a1d2009-07-14 16:15:201027 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1028 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311029 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1030 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1031 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1032 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1033 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091034
[email protected]c9d6a1d2009-07-14 16:15:201035 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091036
[email protected]c9d6a1d2009-07-14 16:15:201037 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1038 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171039 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091040
[email protected]c9d6a1d2009-07-14 16:15:201041 EXPECT_EQ(1, GetOrderOfRequest(1));
1042 EXPECT_EQ(2, GetOrderOfRequest(2));
1043 EXPECT_EQ(6, GetOrderOfRequest(3));
1044 EXPECT_EQ(4, GetOrderOfRequest(4));
1045 EXPECT_EQ(3, GetOrderOfRequest(5));
1046 EXPECT_EQ(5, GetOrderOfRequest(6));
1047 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171048
1049 // Make sure we test order of all requests made.
1050 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091051}
1052
[email protected]ab838892009-06-30 18:49:051053TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531054 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091055
[email protected]c9d6a1d2009-07-14 16:15:201056 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1057 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311058 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091063
[email protected]c9d6a1d2009-07-14 16:15:201064 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091065
[email protected]c9d6a1d2009-07-14 16:15:201066 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1067 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1068
1069 EXPECT_EQ(static_cast<int>(requests_.size()),
1070 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171071 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091072}
1073
1074// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051075// The pending connect job will be cancelled and should not call back into
1076// ClientSocketPoolBase.
1077TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531078 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201079
[email protected]ab838892009-06-30 18:49:051080 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061081 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211082 EXPECT_EQ(ERR_IO_PENDING, req.handle()->Init("a", params_, kDefaultPriority,
1083 &req, pool_, BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331084 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091085}
1086
[email protected]ab838892009-06-30 18:49:051087TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531088 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201089
[email protected]ab838892009-06-30 18:49:051090 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061091 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091092 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061093 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091094
[email protected]df4b4ef2010-07-12 18:25:211095 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1096 &callback, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091097
1098 handle.Reset();
1099
1100 TestCompletionCallback callback2;
[email protected]df4b4ef2010-07-12 18:25:211101 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", params_, kDefaultPriority,
1102 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091103
1104 EXPECT_EQ(OK, callback2.WaitForResult());
1105 EXPECT_FALSE(callback.have_result());
1106
1107 handle.Reset();
1108}
1109
[email protected]ab838892009-06-30 18:49:051110TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091112
[email protected]c9d6a1d2009-07-14 16:15:201113 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1114 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311115 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1116 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1117 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1118 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091120
1121 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201122 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331123 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1124 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091125
[email protected]c9d6a1d2009-07-14 16:15:201126 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]c9d6a1d2009-07-14 16:15:201128 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1129 client_socket_factory_.allocation_count());
1130 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171131 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091132
[email protected]c9d6a1d2009-07-14 16:15:201133 EXPECT_EQ(1, GetOrderOfRequest(1));
1134 EXPECT_EQ(2, GetOrderOfRequest(2));
1135 EXPECT_EQ(5, GetOrderOfRequest(3));
1136 EXPECT_EQ(3, GetOrderOfRequest(4));
1137 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1138 EXPECT_EQ(4, GetOrderOfRequest(6));
1139 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171140
1141 // Make sure we test order of all requests made.
1142 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091143}
1144
1145class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1146 public:
[email protected]2ab05b52009-07-01 23:57:581147 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241148 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581149 TestConnectJobFactory* test_connect_job_factory,
1150 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091151 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061152 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581153 within_callback_(false),
1154 test_connect_job_factory_(test_connect_job_factory),
1155 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091156
1157 virtual void RunWithParams(const Tuple1<int>& params) {
1158 callback_.RunWithParams(params);
1159 ASSERT_EQ(OK, params.a);
1160
1161 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581162 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111163
1164 // Don't allow reuse of the socket. Disconnect it and then release it and
1165 // run through the MessageLoop once to get it completely released.
1166 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091167 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111168 {
1169 MessageLoop::ScopedNestableTaskAllower nestable(
1170 MessageLoop::current());
1171 MessageLoop::current()->RunAllPending();
1172 }
[email protected]f6d1d6eb2009-06-24 20:16:091173 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471174 TestCompletionCallback next_job_callback;
[email protected]df4b4ef2010-07-12 18:25:211175 scoped_refptr<TestSocketParams> params = new TestSocketParams();
1176 int rv = handle_->Init("a", params, kDefaultPriority, &next_job_callback,
1177 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581178 switch (next_job_type_) {
1179 case TestConnectJob::kMockJob:
1180 EXPECT_EQ(OK, rv);
1181 break;
1182 case TestConnectJob::kMockPendingJob:
1183 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471184
1185 // For pending jobs, wait for new socket to be created. This makes
1186 // sure there are no more pending operations nor any unclosed sockets
1187 // when the test finishes.
1188 // We need to give it a little bit of time to run, so that all the
1189 // operations that happen on timers (e.g. cleanup of idle
1190 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111191 {
1192 MessageLoop::ScopedNestableTaskAllower nestable(
1193 MessageLoop::current());
1194 PlatformThread::Sleep(10);
1195 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1196 }
[email protected]2ab05b52009-07-01 23:57:581197 break;
1198 default:
1199 FAIL() << "Unexpected job type: " << next_job_type_;
1200 break;
1201 }
[email protected]f6d1d6eb2009-06-24 20:16:091202 }
1203 }
1204
1205 int WaitForResult() {
1206 return callback_.WaitForResult();
1207 }
1208
1209 private:
1210 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241211 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091212 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581213 TestConnectJobFactory* const test_connect_job_factory_;
1214 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091215 TestCompletionCallback callback_;
1216};
1217
[email protected]2ab05b52009-07-01 23:57:581218TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201220
[email protected]0b7648c2009-07-06 20:14:011221 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061222 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581223 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061224 &handle, pool_.get(), connect_job_factory_,
1225 TestConnectJob::kMockPendingJob);
[email protected]df4b4ef2010-07-12 18:25:211226 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1227 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091228 ASSERT_EQ(ERR_IO_PENDING, rv);
1229
1230 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581231}
[email protected]f6d1d6eb2009-06-24 20:16:091232
[email protected]2ab05b52009-07-01 23:57:581233TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531234 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201235
[email protected]0b7648c2009-07-06 20:14:011236 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061237 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581238 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061239 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]df4b4ef2010-07-12 18:25:211240 int rv = handle.Init("a", params_, kDefaultPriority, &callback, pool_,
1241 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581242 ASSERT_EQ(ERR_IO_PENDING, rv);
1243
1244 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091245}
1246
1247// Make sure that pending requests get serviced after active requests get
1248// cancelled.
[email protected]ab838892009-06-30 18:49:051249TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531250 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201251
[email protected]0b7648c2009-07-06 20:14:011252 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091253
[email protected]c9d6a1d2009-07-14 16:15:201254 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1255 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));
[email protected]f6d1d6eb2009-06-24 20:16:091261
[email protected]c9d6a1d2009-07-14 16:15:201262 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1263 // Let's cancel them.
1264 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331265 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1266 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091267 }
1268
[email protected]f6d1d6eb2009-06-24 20:16:091269 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201270 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1271 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331272 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091273 }
1274
[email protected]75439d3b2009-07-23 22:11:171275 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091276}
1277
1278// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051279TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531280 const size_t kMaxSockets = 5;
1281 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201282
[email protected]0b7648c2009-07-06 20:14:011283 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091284
[email protected]211d21722009-07-22 15:48:531285 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1286 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091287
1288 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531289 for (size_t i = 0; i < kNumberOfRequests; ++i)
1290 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091291
[email protected]211d21722009-07-22 15:48:531292 for (size_t i = 0; i < kNumberOfRequests; ++i)
1293 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091294}
1295
[email protected]5fc08e32009-07-15 17:09:571296TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531297 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571298
1299 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1300
[email protected]a512f5982009-08-18 16:01:061301 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]df4b4ef2010-07-12 18:25:211302 int rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1303 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571304 EXPECT_EQ(ERR_IO_PENDING, rv);
1305
1306 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331307 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571308
[email protected]df4b4ef2010-07-12 18:25:211309 rv = req.handle()->Init("a", params_, kDefaultPriority, &req, pool_,
1310 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571311 EXPECT_EQ(ERR_IO_PENDING, rv);
1312 EXPECT_EQ(OK, req.WaitForResult());
1313
[email protected]a6c59f62009-07-29 16:33:331314 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171315 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571316 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1317}
1318
[email protected]2b7523d2009-07-29 20:29:231319// Regression test for http://crbug.com/17985.
1320TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1321 const int kMaxSockets = 3;
1322 const int kMaxSocketsPerGroup = 2;
1323 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1324
[email protected]ac790b42009-12-02 04:31:311325 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231326
1327 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1328 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1329
1330 // This is going to be a pending request in an otherwise empty group.
1331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1332
1333 // Reach the maximum socket limit.
1334 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1335
1336 // Create a stalled group with high priorities.
1337 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231339
[email protected]eb5a99382010-07-11 03:18:261340 // Release the first two sockets from "a". Because this is a keepalive,
1341 // the first release will unblock the pending request for "a". The
1342 // second release will unblock a request for "c", becaue it is the next
1343 // high priority socket.
[email protected]2b7523d2009-07-29 20:29:231344 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1345 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1346
1347 // Closing idle sockets should not get us into trouble, but in the bug
1348 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411349 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541350 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261351
1352 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231353}
1354
[email protected]4d3b05d2010-01-27 21:27:291355TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531356 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571357
1358 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061359 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531360 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]df4b4ef2010-07-12 18:25:211361 int rv = req.handle()->Init("a", params_, LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571362 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331363 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571364 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331365 EXPECT_TRUE(req.handle()->is_initialized());
1366 EXPECT_TRUE(req.handle()->socket());
1367 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301368
[email protected]06650c52010-06-03 00:49:171369 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461370 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531371 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171372 EXPECT_TRUE(LogContainsEvent(
1373 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1374 NetLog::PHASE_NONE));
1375 EXPECT_TRUE(LogContainsEvent(
1376 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1377 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461378 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171379 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571380}
1381
[email protected]4d3b05d2010-01-27 21:27:291382TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571383 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531384 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571385
1386 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061387 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531388 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181389 // Set the additional error state members to ensure that they get cleared.
1390 req.handle()->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431391 HttpResponseInfo info;
1392 info.headers = new HttpResponseHeaders("");
1393 req.handle()->set_ssl_error_response_info(info);
[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());
[email protected]8b498692010-07-16 17:11:431399 EXPECT_TRUE(req.handle()->ssl_error_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());
[email protected]8b498692010-07-16 17:11:431604 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181605 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());
[email protected]8b498692010-07-16 17:11:431621 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181622 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());
[email protected]8b498692010-07-16 17:11:431867 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181868}
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