blob: c6092d7f76913060ade2984b6da0be798da45270 [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]df4b4ef2010-07-12 18:25:2110#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2011#include "base/scoped_vector.h"
[email protected]e83326f2010-07-31 17:29:2512#include "base/string_number_conversions.h"
[email protected]43a21b82010-06-10 21:30:5413#include "base/string_util.h"
[email protected]f214f8792011-01-01 02:17:0814#include "base/threading/platform_thread.h"
[email protected]d8eb84242010-09-25 02:25:0615#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5316#include "net/base/net_log.h"
17#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "testing/gtest/include/gtest/gtest.h"
28
29namespace net {
30
31namespace {
32
[email protected]211d21722009-07-22 15:48:5333const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2034const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5235const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0136
[email protected]df4b4ef2010-07-12 18:25:2137class TestSocketParams : public base::RefCounted<TestSocketParams> {
38 private:
39 friend class base::RefCounted<TestSocketParams>;
40 ~TestSocketParams() {}
41};
[email protected]7fc5b09a2010-02-27 00:07:3842typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4943
[email protected]f6d1d6eb2009-06-24 20:16:0944class MockClientSocket : public ClientSocket {
45 public:
[email protected]0f873e82010-09-02 16:09:0146 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0947
[email protected]ab838892009-06-30 18:49:0548 // Socket methods:
49 virtual int Read(
50 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
51 return ERR_UNEXPECTED;
52 }
53
54 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0155 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
56 was_used_to_convey_data_ = true;
57 return len;
[email protected]ab838892009-06-30 18:49:0558 }
[email protected]06650c52010-06-03 00:49:1759 virtual bool SetReceiveBufferSize(int32 size) { return true; }
60 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0561
[email protected]f6d1d6eb2009-06-24 20:16:0962 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0563
[email protected]a2006ece2010-04-23 16:44:0264 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0965 connected_ = true;
66 return OK;
67 }
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]ab838892009-06-30 18:49:0569 virtual void Disconnect() { connected_ = false; }
70 virtual bool IsConnected() const { return connected_; }
71 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0172
[email protected]ac9eec62010-02-20 18:50:3873 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1674 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0975 }
[email protected]f6d1d6eb2009-06-24 20:16:0976
[email protected]a2006ece2010-04-23 16:44:0277 virtual const BoundNetLog& NetLog() const {
78 return net_log_;
79 }
80
[email protected]9b5614a2010-08-25 20:29:4581 virtual void SetSubresourceSpeculation() {}
82 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0183 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]7f7e92392010-10-26 18:29:2984 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]9b5614a2010-08-25 20:29:4585
[email protected]f6d1d6eb2009-06-24 20:16:0986 private:
87 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0288 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0189 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0990
[email protected]ab838892009-06-30 18:49:0591 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0992};
93
[email protected]5fc08e32009-07-15 17:09:5794class TestConnectJob;
95
[email protected]f6d1d6eb2009-06-24 20:16:0996class MockClientSocketFactory : public ClientSocketFactory {
97 public:
[email protected]ab838892009-06-30 18:49:0598 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0999
[email protected]0a0b7682010-08-25 17:08:07100 virtual ClientSocket* CreateTCPClientSocket(
101 const AddressList& addresses,
102 NetLog* /* net_log */,
103 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09104 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05105 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09106 }
107
108 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18109 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27110 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21111 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12112 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15113 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18114 DnsCertProvenanceChecker* dns_cert_checker) {
[email protected]f6d1d6eb2009-06-24 20:16:09115 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21116 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09117 return NULL;
118 }
119
[email protected]5fc08e32009-07-15 17:09:57120 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
121 void SignalJobs();
122
[email protected]f6d1d6eb2009-06-24 20:16:09123 int allocation_count() const { return allocation_count_; }
124
[email protected]f6d1d6eb2009-06-24 20:16:09125 private:
126 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57127 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09128};
129
[email protected]ab838892009-06-30 18:49:05130class TestConnectJob : public ConnectJob {
131 public:
132 enum JobType {
133 kMockJob,
134 kMockFailingJob,
135 kMockPendingJob,
136 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57137 kMockWaitingJob,
138 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13139 kMockRecoverableJob,
140 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18141 kMockAdditionalErrorStateJob,
142 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05143 };
144
[email protected]994d4932010-07-12 17:55:13145 // The kMockPendingJob uses a slight delay before allowing the connect
146 // to complete.
147 static const int kPendingConnectDelay = 2;
148
[email protected]ab838892009-06-30 18:49:05149 TestConnectJob(JobType job_type,
150 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49151 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34152 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05153 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30154 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17155 NetLog* net_log)
156 : ConnectJob(group_name, timeout_duration, delegate,
157 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58158 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05159 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21160 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18161 load_state_(LOAD_STATE_IDLE),
162 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05163
[email protected]974ebd62009-08-03 23:14:34164 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13165 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34166 }
167
[email protected]46451352009-09-01 14:54:21168 virtual LoadState GetLoadState() const { return load_state_; }
169
[email protected]e60e47a2010-07-14 03:37:18170 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
171 if (store_additional_error_state_) {
172 // Set all of the additional error state fields in some way.
173 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43174 HttpResponseInfo info;
175 info.headers = new HttpResponseHeaders("");
176 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18177 }
178 }
179
[email protected]974ebd62009-08-03 23:14:34180 private:
[email protected]ab838892009-06-30 18:49:05181 // ConnectJob methods:
182
[email protected]974ebd62009-08-03 23:14:34183 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05184 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07185 client_socket_factory_->CreateTCPClientSocket(
186 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40187 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05188 switch (job_type_) {
189 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13190 return DoConnect(true /* successful */, false /* sync */,
191 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05192 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13193 return DoConnect(false /* error */, false /* sync */,
194 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05195 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57196 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47197
198 // Depending on execution timings, posting a delayed task can result
199 // in the task getting executed the at the earliest possible
200 // opportunity or only after returning once from the message loop and
201 // then a second call into the message loop. In order to make behavior
202 // more deterministic, we change the default delay to 2ms. This should
203 // always require us to wait for the second call into the message loop.
204 //
205 // N.B. The correct fix for this and similar timing problems is to
206 // abstract time for the purpose of unittests. Unfortunately, we have
207 // a lot of third-party components that directly call the various
208 // time functions, so this change would be rather invasive.
209 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05210 FROM_HERE,
211 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47212 &TestConnectJob::DoConnect,
213 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13214 true /* async */,
215 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13216 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05217 return ERR_IO_PENDING;
218 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57219 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47220 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05221 FROM_HERE,
222 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47223 &TestConnectJob::DoConnect,
224 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13225 true /* async */,
226 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47227 2);
[email protected]ab838892009-06-30 18:49:05228 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57229 case kMockWaitingJob:
230 client_socket_factory_->WaitForSignal(this);
231 waiting_success_ = true;
232 return ERR_IO_PENDING;
233 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46234 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57235 FROM_HERE,
236 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46237 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57238 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13239 case kMockRecoverableJob:
240 return DoConnect(false /* error */, false /* sync */,
241 true /* recoverable */);
242 case kMockPendingRecoverableJob:
243 set_load_state(LOAD_STATE_CONNECTING);
244 MessageLoop::current()->PostDelayedTask(
245 FROM_HERE,
246 method_factory_.NewRunnableMethod(
247 &TestConnectJob::DoConnect,
248 false /* error */,
249 true /* async */,
250 true /* recoverable */),
251 2);
252 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18253 case kMockAdditionalErrorStateJob:
254 store_additional_error_state_ = true;
255 return DoConnect(false /* error */, false /* sync */,
256 false /* recoverable */);
257 case kMockPendingAdditionalErrorStateJob:
258 set_load_state(LOAD_STATE_CONNECTING);
259 store_additional_error_state_ = true;
260 MessageLoop::current()->PostDelayedTask(
261 FROM_HERE,
262 method_factory_.NewRunnableMethod(
263 &TestConnectJob::DoConnect,
264 false /* error */,
265 true /* async */,
266 false /* recoverable */),
267 2);
268 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05269 default:
270 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40271 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05272 return ERR_FAILED;
273 }
274 }
275
[email protected]46451352009-09-01 14:54:21276 void set_load_state(LoadState load_state) { load_state_ = load_state; }
277
[email protected]e772db3f2010-07-12 18:11:13278 int DoConnect(bool succeed, bool was_async, bool recoverable) {
279 int result = OK;
[email protected]ab838892009-06-30 18:49:05280 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02281 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13282 } else if (recoverable) {
283 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40284 } else {
[email protected]e772db3f2010-07-12 18:11:13285 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40286 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05287 }
[email protected]2ab05b52009-07-01 23:57:58288
289 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30290 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05291 return result;
292 }
293
[email protected]cfa8228c2010-06-17 01:07:56294 // This function helps simulate the progress of load states on a ConnectJob.
295 // Each time it is called it advances the load state and posts a task to be
296 // called again. It stops at the last connecting load state (the one
297 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57298 void AdvanceLoadState(LoadState state) {
299 int tmp = state;
300 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56301 if (tmp < LOAD_STATE_SENDING_REQUEST) {
302 state = static_cast<LoadState>(tmp);
303 set_load_state(state);
304 MessageLoop::current()->PostTask(
305 FROM_HERE,
306 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
307 state));
308 }
[email protected]5fc08e32009-07-15 17:09:57309 }
310
311 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05312 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57313 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05314 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21315 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18316 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05317
318 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
319};
320
[email protected]d80a4322009-08-14 07:07:49321class TestConnectJobFactory
322 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05323 public:
[email protected]5fc08e32009-07-15 17:09:57324 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05325 : job_type_(TestConnectJob::kMockJob),
326 client_socket_factory_(client_socket_factory) {}
327
328 virtual ~TestConnectJobFactory() {}
329
330 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
331
[email protected]974ebd62009-08-03 23:14:34332 void set_timeout_duration(base::TimeDelta timeout_duration) {
333 timeout_duration_ = timeout_duration;
334 }
335
[email protected]ab838892009-06-30 18:49:05336 // ConnectJobFactory methods:
337
338 virtual ConnectJob* NewConnectJob(
339 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49340 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17341 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05342 return new TestConnectJob(job_type_,
343 group_name,
344 request,
[email protected]974ebd62009-08-03 23:14:34345 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05346 delegate,
[email protected]fd7b7c92009-08-20 19:38:30347 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17348 NULL);
[email protected]ab838892009-06-30 18:49:05349 }
350
[email protected]a796bcec2010-03-22 17:17:26351 virtual base::TimeDelta ConnectionTimeout() const {
352 return timeout_duration_;
353 }
354
[email protected]ab838892009-06-30 18:49:05355 private:
356 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34357 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57358 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05359
360 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
361};
362
363class TestClientSocketPool : public ClientSocketPool {
364 public:
365 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53366 int max_sockets,
[email protected]ab838892009-06-30 18:49:05367 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13368 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16369 base::TimeDelta unused_idle_socket_timeout,
370 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49371 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00372 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16373 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38374 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05375
[email protected]2431756e2010-09-29 20:26:13376 virtual ~TestClientSocketPool() {}
377
[email protected]ab838892009-06-30 18:49:05378 virtual int RequestSocket(
379 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49380 const void* params,
[email protected]ac790b42009-12-02 04:31:31381 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05382 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46383 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53384 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21385 const scoped_refptr<TestSocketParams>* casted_socket_params =
386 static_cast<const scoped_refptr<TestSocketParams>*>(params);
387 return base_.RequestSocket(group_name, *casted_socket_params, priority,
388 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05389 }
390
[email protected]2c2bef152010-10-13 00:55:03391 virtual void RequestSockets(const std::string& group_name,
392 const void* params,
393 int num_sockets,
394 const BoundNetLog& net_log) {
395 const scoped_refptr<TestSocketParams>* casted_params =
396 static_cast<const scoped_refptr<TestSocketParams>*>(params);
397
398 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
399 }
400
[email protected]ab838892009-06-30 18:49:05401 virtual void CancelRequest(
402 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21403 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49404 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05405 }
406
407 virtual void ReleaseSocket(
408 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24409 ClientSocket* socket,
410 int id) {
411 base_.ReleaseSocket(group_name, socket, id);
412 }
413
414 virtual void Flush() {
415 base_.Flush();
[email protected]ab838892009-06-30 18:49:05416 }
417
418 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49419 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05420 }
421
[email protected]d80a4322009-08-14 07:07:49422 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05423
424 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49425 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05426 }
427
428 virtual LoadState GetLoadState(const std::string& group_name,
429 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49430 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05431 }
432
[email protected]ba00b492010-09-08 14:53:38433 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
434 const std::string& type,
435 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27436 return base_.GetInfoAsValue(name, type);
437 }
438
[email protected]a796bcec2010-03-22 17:17:26439 virtual base::TimeDelta ConnectionTimeout() const {
440 return base_.ConnectionTimeout();
441 }
442
[email protected]2431756e2010-09-29 20:26:13443 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00444 return base_.histograms();
445 }
[email protected]a796bcec2010-03-22 17:17:26446
[email protected]d80a4322009-08-14 07:07:49447 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20448
[email protected]974ebd62009-08-03 23:14:34449 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49450 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34451 }
452
[email protected]2c2bef152010-10-13 00:55:03453 int NumActiveSocketsInGroup(const std::string& group_name) const {
454 return base_.NumActiveSocketsInGroup(group_name);
455 }
456
[email protected]2abfe90a2010-08-25 17:49:51457 bool HasGroup(const std::string& group_name) const {
458 return base_.HasGroup(group_name);
459 }
460
[email protected]9bf28db2009-08-29 01:35:16461 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
462
[email protected]06d94042010-08-25 01:45:22463 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54464
[email protected]ab838892009-06-30 18:49:05465 private:
[email protected]d80a4322009-08-14 07:07:49466 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05467
468 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
469};
470
[email protected]a937a06d2009-08-19 21:19:24471} // namespace
472
[email protected]7fc5b09a2010-02-27 00:07:38473REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24474
475namespace {
476
[email protected]5fc08e32009-07-15 17:09:57477void MockClientSocketFactory::SignalJobs() {
478 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
479 it != waiting_jobs_.end(); ++it) {
480 (*it)->Signal();
481 }
482 waiting_jobs_.clear();
483}
484
[email protected]974ebd62009-08-03 23:14:34485class TestConnectJobDelegate : public ConnectJob::Delegate {
486 public:
487 TestConnectJobDelegate()
488 : have_result_(false), waiting_for_result_(false), result_(OK) {}
489 virtual ~TestConnectJobDelegate() {}
490
491 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
492 result_ = result;
[email protected]6e713f02009-08-06 02:56:40493 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07494 // socket.get() should be NULL iff result != OK
495 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34496 delete job;
497 have_result_ = true;
498 if (waiting_for_result_)
499 MessageLoop::current()->Quit();
500 }
501
502 int WaitForResult() {
503 DCHECK(!waiting_for_result_);
504 while (!have_result_) {
505 waiting_for_result_ = true;
506 MessageLoop::current()->Run();
507 waiting_for_result_ = false;
508 }
509 have_result_ = false; // auto-reset for next callback
510 return result_;
511 }
512
513 private:
514 bool have_result_;
515 bool waiting_for_result_;
516 int result_;
517};
518
[email protected]2431756e2010-09-29 20:26:13519class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09520 protected:
[email protected]b89f7e42010-05-20 20:37:00521 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21522 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13523 histograms_("ClientSocketPoolTest") {}
524
525 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20526
[email protected]211d21722009-07-22 15:48:53527 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16528 CreatePoolWithIdleTimeouts(
529 max_sockets,
530 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00531 base::TimeDelta::FromSeconds(
532 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16533 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
534 }
535
536 void CreatePoolWithIdleTimeouts(
537 int max_sockets, int max_sockets_per_group,
538 base::TimeDelta unused_idle_socket_timeout,
539 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20540 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04541 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13542 pool_.reset(new TestClientSocketPool(max_sockets,
543 max_sockets_per_group,
544 &histograms_,
545 unused_idle_socket_timeout,
546 used_idle_socket_timeout,
547 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20548 }
[email protected]f6d1d6eb2009-06-24 20:16:09549
[email protected]ac790b42009-12-02 04:31:31550 int StartRequest(const std::string& group_name,
551 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13552 return test_base_.StartRequestUsingPool<
553 TestClientSocketPool, TestSocketParams>(
554 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09555 }
556
[email protected]2431756e2010-09-29 20:26:13557 int GetOrderOfRequest(size_t index) const {
558 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09559 }
560
[email protected]2431756e2010-09-29 20:26:13561 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
562 return test_base_.ReleaseOneConnection(keep_alive);
563 }
564
565 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
566 test_base_.ReleaseAllConnections(keep_alive);
567 }
568
569 TestSocketRequest* request(int i) { return test_base_.request(i); }
570 size_t requests_size() const { return test_base_.requests_size(); }
571 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
572 size_t completion_count() const { return test_base_.completion_count(); }
573
[email protected]f6d1d6eb2009-06-24 20:16:09574 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04575 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21576 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13577 ClientSocketPoolHistograms histograms_;
578 scoped_ptr<TestClientSocketPool> pool_;
579 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09580};
581
[email protected]974ebd62009-08-03 23:14:34582// Even though a timeout is specified, it doesn't time out on a synchronous
583// completion.
584TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
585 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06586 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49587 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03588 &ignored, NULL, kDefaultPriority,
589 internal::ClientSocketPoolBaseHelper::NORMAL,
590 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34591 scoped_ptr<TestConnectJob> job(
592 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12593 "a",
[email protected]974ebd62009-08-03 23:14:34594 request,
595 base::TimeDelta::FromMicroseconds(1),
596 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30597 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17598 NULL));
[email protected]974ebd62009-08-03 23:14:34599 EXPECT_EQ(OK, job->Connect());
600}
601
602TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
603 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06604 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17605 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53606
[email protected]d80a4322009-08-14 07:07:49607 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03608 &ignored, NULL, kDefaultPriority,
609 internal::ClientSocketPoolBaseHelper::NORMAL,
610 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34611 // Deleted by TestConnectJobDelegate.
612 TestConnectJob* job =
613 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12614 "a",
[email protected]974ebd62009-08-03 23:14:34615 request,
616 base::TimeDelta::FromMicroseconds(1),
617 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30618 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17619 &log);
[email protected]974ebd62009-08-03 23:14:34620 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08621 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34622 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30623
[email protected]b2fcd0e2010-12-01 15:19:40624 net::CapturingNetLog::EntryList entries;
625 log.GetEntries(&entries);
626
627 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46628 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40629 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17630 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40631 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46632 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40633 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17634 NetLog::PHASE_NONE));
635 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40636 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53637 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46638 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40639 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17640 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40641 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34642}
643
[email protected]5fc08e32009-07-15 17:09:57644TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53645 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20646
[email protected]f6d1d6eb2009-06-24 20:16:09647 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06648 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53649 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
650
[email protected]2431756e2010-09-29 20:26:13651 EXPECT_EQ(OK,
652 handle.Init("a",
653 params_,
654 kDefaultPriority,
655 &callback,
656 pool_.get(),
657 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09658 EXPECT_TRUE(handle.is_initialized());
659 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09660 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30661
[email protected]b2fcd0e2010-12-01 15:19:40662 net::CapturingNetLog::EntryList entries;
663 log.GetEntries(&entries);
664
665 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46666 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40667 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53668 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40669 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17670 NetLog::PHASE_NONE));
671 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40672 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53673 NetLog::PHASE_NONE));
674 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40675 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09676}
677
[email protected]ab838892009-06-30 18:49:05678TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53679 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20680
[email protected]ab838892009-06-30 18:49:05681 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53682 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
683
[email protected]2431756e2010-09-29 20:26:13684 ClientSocketHandle handle;
685 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18686 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13687 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43688 HttpResponseInfo info;
689 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13690 handle.set_ssl_error_response_info(info);
691 EXPECT_EQ(ERR_CONNECTION_FAILED,
692 handle.Init("a",
693 params_,
694 kDefaultPriority,
695 &callback,
696 pool_.get(),
697 log.bound()));
698 EXPECT_FALSE(handle.socket());
699 EXPECT_FALSE(handle.is_ssl_error());
700 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30701
[email protected]b2fcd0e2010-12-01 15:19:40702 net::CapturingNetLog::EntryList entries;
703 log.GetEntries(&entries);
704
705 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27706 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40707 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17708 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40709 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17710 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02711 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40712 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09713}
714
[email protected]211d21722009-07-22 15:48:53715TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
716 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
717
[email protected]9e743cd2010-03-16 07:03:53718 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30719
[email protected]211d21722009-07-22 15:48:53720 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
721 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
722 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
723 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
724
[email protected]2431756e2010-09-29 20:26:13725 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53726 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13727 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53728
729 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
730 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
731 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
732
[email protected]2431756e2010-09-29 20:26:13733 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53734
[email protected]2431756e2010-09-29 20:26:13735 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53736 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13737 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53738
739 EXPECT_EQ(1, GetOrderOfRequest(1));
740 EXPECT_EQ(2, GetOrderOfRequest(2));
741 EXPECT_EQ(3, GetOrderOfRequest(3));
742 EXPECT_EQ(4, GetOrderOfRequest(4));
743 EXPECT_EQ(5, GetOrderOfRequest(5));
744 EXPECT_EQ(6, GetOrderOfRequest(6));
745 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17746
747 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13748 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53749}
750
751TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
753
[email protected]9e743cd2010-03-16 07:03:53754 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30755
[email protected]211d21722009-07-22 15:48:53756 // Reach all limits: max total sockets, and max sockets per group.
757 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
758 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
759 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
760 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
761
[email protected]2431756e2010-09-29 20:26:13762 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53763 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13764 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53765
766 // Now create a new group and verify that we don't starve it.
767 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
768
[email protected]2431756e2010-09-29 20:26:13769 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53770
[email protected]2431756e2010-09-29 20:26:13771 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53772 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13773 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53774
775 EXPECT_EQ(1, GetOrderOfRequest(1));
776 EXPECT_EQ(2, GetOrderOfRequest(2));
777 EXPECT_EQ(3, GetOrderOfRequest(3));
778 EXPECT_EQ(4, GetOrderOfRequest(4));
779 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17780
781 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13782 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53783}
784
785TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
787
[email protected]ac790b42009-12-02 04:31:31788 EXPECT_EQ(OK, StartRequest("b", LOWEST));
789 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
790 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
791 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53792
[email protected]2431756e2010-09-29 20:26:13793 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53794 client_socket_factory_.allocation_count());
795
[email protected]ac790b42009-12-02 04:31:31796 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
797 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
798 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53799
[email protected]2431756e2010-09-29 20:26:13800 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53801
[email protected]2431756e2010-09-29 20:26:13802 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53803
804 // First 4 requests don't have to wait, and finish in order.
805 EXPECT_EQ(1, GetOrderOfRequest(1));
806 EXPECT_EQ(2, GetOrderOfRequest(2));
807 EXPECT_EQ(3, GetOrderOfRequest(3));
808 EXPECT_EQ(4, GetOrderOfRequest(4));
809
[email protected]ac790b42009-12-02 04:31:31810 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
811 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53812 EXPECT_EQ(7, GetOrderOfRequest(5));
813 EXPECT_EQ(6, GetOrderOfRequest(6));
814 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17815
816 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13817 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53818}
819
820TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
822
[email protected]ac790b42009-12-02 04:31:31823 EXPECT_EQ(OK, StartRequest("a", LOWEST));
824 EXPECT_EQ(OK, StartRequest("a", LOW));
825 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
826 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53827
[email protected]2431756e2010-09-29 20:26:13828 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53829 client_socket_factory_.allocation_count());
830
[email protected]ac790b42009-12-02 04:31:31831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
832 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
833 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53834
[email protected]2431756e2010-09-29 20:26:13835 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53836
[email protected]2431756e2010-09-29 20:26:13837 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53838 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13839 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53840
841 // First 4 requests don't have to wait, and finish in order.
842 EXPECT_EQ(1, GetOrderOfRequest(1));
843 EXPECT_EQ(2, GetOrderOfRequest(2));
844 EXPECT_EQ(3, GetOrderOfRequest(3));
845 EXPECT_EQ(4, GetOrderOfRequest(4));
846
847 // Request ("b", 7) has the highest priority, but we can't make new socket for
848 // group "b", because it has reached the per-group limit. Then we make
849 // socket for ("c", 6), because it has higher priority than ("a", 4),
850 // and we still can't make a socket for group "b".
851 EXPECT_EQ(5, GetOrderOfRequest(5));
852 EXPECT_EQ(6, GetOrderOfRequest(6));
853 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17854
855 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13856 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53857}
858
859// Make sure that we count connecting sockets against the total limit.
860TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
861 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
862
863 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
864 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
865 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
866
867 // Create one asynchronous request.
868 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
870
[email protected]6b175382009-10-13 06:47:47871 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
872 // actually become pending until 2ms after they have been created. In order
873 // to flush all tasks, we need to wait so that we know there are no
874 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08875 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47876 MessageLoop::current()->RunAllPending();
877
[email protected]211d21722009-07-22 15:48:53878 // The next synchronous request should wait for its turn.
879 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
880 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
881
[email protected]2431756e2010-09-29 20:26:13882 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53883
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53885 client_socket_factory_.allocation_count());
886
887 EXPECT_EQ(1, GetOrderOfRequest(1));
888 EXPECT_EQ(2, GetOrderOfRequest(2));
889 EXPECT_EQ(3, GetOrderOfRequest(3));
890 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17891 EXPECT_EQ(5, GetOrderOfRequest(5));
892
893 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13894 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53895}
896
[email protected]6427fe22010-04-16 22:27:41897TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
898 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
899 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
900
901 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
902 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
903 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
904 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
905
906 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
907
908 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
909
910 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
911 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
912
913 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
914
[email protected]2431756e2010-09-29 20:26:13915 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41916 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13917 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41918 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
920 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41921 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
922}
923
[email protected]d7027bb2010-05-10 18:58:54924TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
925 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
926 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
927
928 ClientSocketHandle handle;
929 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13930 EXPECT_EQ(ERR_IO_PENDING,
931 handle.Init("a",
932 params_,
933 kDefaultPriority,
934 &callback,
935 pool_.get(),
936 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54937
938 ClientSocketHandle handles[4];
939 for (size_t i = 0; i < arraysize(handles); ++i) {
940 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13941 EXPECT_EQ(ERR_IO_PENDING,
942 handles[i].Init("b",
943 params_,
944 kDefaultPriority,
945 &callback,
946 pool_.get(),
947 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54948 }
949
950 // One will be stalled, cancel all the handles now.
951 // This should hit the OnAvailableSocketSlot() code where we previously had
952 // stalled groups, but no longer have any.
953 for (size_t i = 0; i < arraysize(handles); ++i)
954 handles[i].Reset();
955}
956
[email protected]eb5a99382010-07-11 03:18:26957TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54958 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
959 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
960
[email protected]eb5a99382010-07-11 03:18:26961 {
962 ClientSocketHandle handles[kDefaultMaxSockets];
963 TestCompletionCallback callbacks[kDefaultMaxSockets];
964 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13965 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
966 params_,
[email protected]e83326f2010-07-31 17:29:25967 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13968 &callbacks[i],
969 pool_.get(),
970 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26971 }
972
973 // Force a stalled group.
974 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54975 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13976 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
977 params_,
978 kDefaultPriority,
979 &callback,
980 pool_.get(),
981 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26982
983 // Cancel the stalled request.
984 stalled_handle.Reset();
985
986 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
987 EXPECT_EQ(0, pool_->IdleSocketCount());
988
989 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54990 }
991
[email protected]43a21b82010-06-10 21:30:54992 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
993 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26994}
[email protected]43a21b82010-06-10 21:30:54995
[email protected]eb5a99382010-07-11 03:18:26996TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
997 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
998 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
999
1000 {
1001 ClientSocketHandle handles[kDefaultMaxSockets];
1002 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1003 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131004 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1005 params_,
1006 kDefaultPriority,
1007 &callback,
1008 pool_.get(),
1009 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261010 }
1011
1012 // Force a stalled group.
1013 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1014 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541015 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131016 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1017 params_,
1018 kDefaultPriority,
1019 &callback,
1020 pool_.get(),
1021 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261022
1023 // Since it is stalled, it should have no connect jobs.
1024 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1025
1026 // Cancel the stalled request.
1027 handles[0].Reset();
1028
[email protected]eb5a99382010-07-11 03:18:261029 // Now we should have a connect job.
1030 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1031
1032 // The stalled socket should connect.
1033 EXPECT_EQ(OK, callback.WaitForResult());
1034
1035 EXPECT_EQ(kDefaultMaxSockets + 1,
1036 client_socket_factory_.allocation_count());
1037 EXPECT_EQ(0, pool_->IdleSocketCount());
1038 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1039
1040 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541041 }
1042
[email protected]eb5a99382010-07-11 03:18:261043 EXPECT_EQ(1, pool_->IdleSocketCount());
1044}
[email protected]43a21b82010-06-10 21:30:541045
[email protected]eb5a99382010-07-11 03:18:261046TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1047 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1048 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541049
[email protected]eb5a99382010-07-11 03:18:261050 ClientSocketHandle stalled_handle;
1051 TestCompletionCallback callback;
1052 {
1053 ClientSocketHandle handles[kDefaultMaxSockets];
1054 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1055 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061056 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131057 params_,
1058 kDefaultPriority,
1059 &callback,
1060 pool_.get(),
1061 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261062 }
1063
1064 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1065 EXPECT_EQ(0, pool_->IdleSocketCount());
1066
1067 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131068 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1069 params_,
1070 kDefaultPriority,
1071 &callback,
1072 pool_.get(),
1073 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261074
1075 // Dropping out of scope will close all handles and return them to idle.
1076 }
[email protected]43a21b82010-06-10 21:30:541077
1078 // But if we wait for it, the released idle sockets will be closed in
1079 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101080 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261081
1082 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1083 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541084}
1085
1086// Regression test for http://crbug.com/40952.
1087TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1088 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221089 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541090 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1091
1092 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1093 ClientSocketHandle handle;
1094 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131095 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1096 params_,
1097 kDefaultPriority,
1098 &callback,
1099 pool_.get(),
1100 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541101 }
1102
1103 // Flush all the DoReleaseSocket tasks.
1104 MessageLoop::current()->RunAllPending();
1105
1106 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1107 // reuse a socket.
1108 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1109 ClientSocketHandle handle;
1110 TestCompletionCallback callback;
1111
1112 // "0" is special here, since it should be the first entry in the sorted map,
1113 // which is the one which we would close an idle socket for. We shouldn't
1114 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131115 EXPECT_EQ(OK, handle.Init("0",
1116 params_,
1117 kDefaultPriority,
1118 &callback,
1119 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211120 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541121
1122 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1123 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1124}
1125
[email protected]ab838892009-06-30 18:49:051126TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531127 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091128
[email protected]c9d6a1d2009-07-14 16:15:201129 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1130 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031131 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311132 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1133 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1134 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1135 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1136 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091137
[email protected]2431756e2010-09-29 20:26:131138 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091139
[email protected]c9d6a1d2009-07-14 16:15:201140 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1141 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131142 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1143 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091144
[email protected]c9d6a1d2009-07-14 16:15:201145 EXPECT_EQ(1, GetOrderOfRequest(1));
1146 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031147 EXPECT_EQ(8, GetOrderOfRequest(3));
1148 EXPECT_EQ(6, GetOrderOfRequest(4));
1149 EXPECT_EQ(4, GetOrderOfRequest(5));
1150 EXPECT_EQ(3, GetOrderOfRequest(6));
1151 EXPECT_EQ(5, GetOrderOfRequest(7));
1152 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171153
1154 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131155 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091156}
1157
[email protected]ab838892009-06-30 18:49:051158TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531159 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091160
[email protected]c9d6a1d2009-07-14 16:15:201161 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1162 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311163 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1164 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1165 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1166 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1167 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091168
[email protected]2431756e2010-09-29 20:26:131169 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091170
[email protected]2431756e2010-09-29 20:26:131171 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1172 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201173
[email protected]2431756e2010-09-29 20:26:131174 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201175 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131176 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1177 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091178}
1179
1180// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051181// The pending connect job will be cancelled and should not call back into
1182// ClientSocketPoolBase.
1183TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531184 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201185
[email protected]ab838892009-06-30 18:49:051186 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131187 ClientSocketHandle handle;
1188 TestCompletionCallback callback;
1189 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1190 params_,
1191 kDefaultPriority,
1192 &callback,
1193 pool_.get(),
1194 BoundNetLog()));
1195 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091196}
1197
[email protected]ab838892009-06-30 18:49:051198TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531199 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201200
[email protected]ab838892009-06-30 18:49:051201 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061202 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091203 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091204
[email protected]2431756e2010-09-29 20:26:131205 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1206 params_,
1207 kDefaultPriority,
1208 &callback,
1209 pool_.get(),
1210 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091211
1212 handle.Reset();
1213
1214 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131215 EXPECT_EQ(ERR_IO_PENDING,
1216 handle.Init("a",
1217 params_,
1218 kDefaultPriority,
1219 &callback2,
1220 pool_.get(),
1221 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091222
1223 EXPECT_EQ(OK, callback2.WaitForResult());
1224 EXPECT_FALSE(callback.have_result());
1225
1226 handle.Reset();
1227}
1228
[email protected]ab838892009-06-30 18:49:051229TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531230 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091231
[email protected]c9d6a1d2009-07-14 16:15:201232 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1233 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311234 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1238 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091239
1240 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201241 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131242 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1243 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091244
[email protected]2431756e2010-09-29 20:26:131245 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091246
[email protected]c9d6a1d2009-07-14 16:15:201247 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1248 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131249 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1250 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091251
[email protected]c9d6a1d2009-07-14 16:15:201252 EXPECT_EQ(1, GetOrderOfRequest(1));
1253 EXPECT_EQ(2, GetOrderOfRequest(2));
1254 EXPECT_EQ(5, GetOrderOfRequest(3));
1255 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131256 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1257 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201258 EXPECT_EQ(4, GetOrderOfRequest(6));
1259 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171260
1261 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131262 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091263}
1264
1265class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1266 public:
[email protected]2ab05b52009-07-01 23:57:581267 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241268 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581269 TestConnectJobFactory* test_connect_job_factory,
1270 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091271 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061272 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581273 within_callback_(false),
1274 test_connect_job_factory_(test_connect_job_factory),
1275 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091276
1277 virtual void RunWithParams(const Tuple1<int>& params) {
1278 callback_.RunWithParams(params);
1279 ASSERT_EQ(OK, params.a);
1280
1281 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581282 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111283
1284 // Don't allow reuse of the socket. Disconnect it and then release it and
1285 // run through the MessageLoop once to get it completely released.
1286 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091287 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111288 {
1289 MessageLoop::ScopedNestableTaskAllower nestable(
1290 MessageLoop::current());
1291 MessageLoop::current()->RunAllPending();
1292 }
[email protected]f6d1d6eb2009-06-24 20:16:091293 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471294 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271295 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131296 int rv = handle_->Init("a",
1297 params,
1298 kDefaultPriority,
1299 &next_job_callback,
1300 pool_,
1301 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581302 switch (next_job_type_) {
1303 case TestConnectJob::kMockJob:
1304 EXPECT_EQ(OK, rv);
1305 break;
1306 case TestConnectJob::kMockPendingJob:
1307 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471308
1309 // For pending jobs, wait for new socket to be created. This makes
1310 // sure there are no more pending operations nor any unclosed sockets
1311 // when the test finishes.
1312 // We need to give it a little bit of time to run, so that all the
1313 // operations that happen on timers (e.g. cleanup of idle
1314 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111315 {
1316 MessageLoop::ScopedNestableTaskAllower nestable(
1317 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081318 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111319 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1320 }
[email protected]2ab05b52009-07-01 23:57:581321 break;
1322 default:
1323 FAIL() << "Unexpected job type: " << next_job_type_;
1324 break;
1325 }
[email protected]f6d1d6eb2009-06-24 20:16:091326 }
1327 }
1328
1329 int WaitForResult() {
1330 return callback_.WaitForResult();
1331 }
1332
1333 private:
1334 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131335 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091336 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581337 TestConnectJobFactory* const test_connect_job_factory_;
1338 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091339 TestCompletionCallback callback_;
1340};
1341
[email protected]2ab05b52009-07-01 23:57:581342TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531343 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201344
[email protected]0b7648c2009-07-06 20:14:011345 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061346 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581347 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061348 &handle, pool_.get(), connect_job_factory_,
1349 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131350 int rv = handle.Init("a",
1351 params_,
1352 kDefaultPriority,
1353 &callback,
1354 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211355 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091356 ASSERT_EQ(ERR_IO_PENDING, rv);
1357
1358 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581359}
[email protected]f6d1d6eb2009-06-24 20:16:091360
[email protected]2ab05b52009-07-01 23:57:581361TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531362 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201363
[email protected]0b7648c2009-07-06 20:14:011364 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061365 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581366 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061367 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131368 int rv = handle.Init("a",
1369 params_,
1370 kDefaultPriority,
1371 &callback,
1372 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211373 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581374 ASSERT_EQ(ERR_IO_PENDING, rv);
1375
1376 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091377}
1378
1379// Make sure that pending requests get serviced after active requests get
1380// cancelled.
[email protected]ab838892009-06-30 18:49:051381TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531382 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201383
[email protected]0b7648c2009-07-06 20:14:011384 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091385
[email protected]c9d6a1d2009-07-14 16:15:201386 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1387 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1388 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1389 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1390 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1391 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1392 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091393
[email protected]c9d6a1d2009-07-14 16:15:201394 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1395 // Let's cancel them.
1396 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131397 ASSERT_FALSE(request(i)->handle()->is_initialized());
1398 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091399 }
1400
[email protected]f6d1d6eb2009-06-24 20:16:091401 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131402 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1403 EXPECT_EQ(OK, request(i)->WaitForResult());
1404 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091405 }
1406
[email protected]2431756e2010-09-29 20:26:131407 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1408 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091409}
1410
1411// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051412TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531413 const size_t kMaxSockets = 5;
1414 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201415
[email protected]0b7648c2009-07-06 20:14:011416 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091417
[email protected]211d21722009-07-22 15:48:531418 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1419 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091420
1421 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531422 for (size_t i = 0; i < kNumberOfRequests; ++i)
1423 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091424
[email protected]211d21722009-07-22 15:48:531425 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131426 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091427}
1428
[email protected]5fc08e32009-07-15 17:09:571429TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531430 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571431
1432 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1433
[email protected]2431756e2010-09-29 20:26:131434 ClientSocketHandle handle;
1435 TestCompletionCallback callback;
1436 int rv = handle.Init("a",
1437 params_,
1438 kDefaultPriority,
1439 &callback,
1440 pool_.get(),
1441 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571442 EXPECT_EQ(ERR_IO_PENDING, rv);
1443
1444 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131445 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571446
[email protected]2431756e2010-09-29 20:26:131447 rv = handle.Init("a",
1448 params_,
1449 kDefaultPriority,
1450 &callback,
1451 pool_.get(),
1452 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571453 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131454 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571455
[email protected]2431756e2010-09-29 20:26:131456 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571457 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1458}
1459
[email protected]2b7523d2009-07-29 20:29:231460// Regression test for http://crbug.com/17985.
1461TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1462 const int kMaxSockets = 3;
1463 const int kMaxSocketsPerGroup = 2;
1464 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1465
[email protected]ac790b42009-12-02 04:31:311466 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231467
1468 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1469 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1470
1471 // This is going to be a pending request in an otherwise empty group.
1472 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1473
1474 // Reach the maximum socket limit.
1475 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1476
1477 // Create a stalled group with high priorities.
1478 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1479 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231480
[email protected]eb5a99382010-07-11 03:18:261481 // Release the first two sockets from "a". Because this is a keepalive,
1482 // the first release will unblock the pending request for "a". The
1483 // second release will unblock a request for "c", becaue it is the next
1484 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131485 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1486 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231487
1488 // Closing idle sockets should not get us into trouble, but in the bug
1489 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411490 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541491 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261492
1493 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231494}
1495
[email protected]4d3b05d2010-01-27 21:27:291496TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531497 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571498
1499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131500 ClientSocketHandle handle;
1501 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531502 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131503 int rv = handle.Init("a",
1504 params_,
1505 LOWEST,
1506 &callback,
1507 pool_.get(),
1508 log.bound());
[email protected]5fc08e32009-07-15 17:09:571509 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131510 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1511 EXPECT_EQ(OK, callback.WaitForResult());
1512 EXPECT_TRUE(handle.is_initialized());
1513 EXPECT_TRUE(handle.socket());
1514 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301515
[email protected]b2fcd0e2010-12-01 15:19:401516 net::CapturingNetLog::EntryList entries;
1517 log.GetEntries(&entries);
1518
1519 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461520 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401521 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171522 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401523 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171524 NetLog::PHASE_NONE));
1525 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401526 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171527 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461528 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401529 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571530}
1531
[email protected]4d3b05d2010-01-27 21:27:291532TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571533 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571535
1536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131537 ClientSocketHandle handle;
1538 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531539 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181540 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131541 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431542 HttpResponseInfo info;
1543 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131544 handle.set_ssl_error_response_info(info);
1545 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1546 params_,
1547 kDefaultPriority,
1548 &callback,
1549 pool_.get(),
1550 log.bound()));
1551 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1552 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1553 EXPECT_FALSE(handle.is_ssl_error());
1554 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301555
[email protected]b2fcd0e2010-12-01 15:19:401556 net::CapturingNetLog::EntryList entries;
1557 log.GetEntries(&entries);
1558
1559 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461560 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401561 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171562 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401563 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171564 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321565 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401566 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571567}
1568
[email protected]4d3b05d2010-01-27 21:27:291569TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101570 // TODO(eroman): Add back the log expectations! Removed them because the
1571 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531572 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571573
1574 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131575 ClientSocketHandle handle;
1576 TestCompletionCallback callback;
1577 ClientSocketHandle handle2;
1578 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571579
[email protected]2431756e2010-09-29 20:26:131580 EXPECT_EQ(ERR_IO_PENDING,
1581 handle.Init("a",
1582 params_,
1583 kDefaultPriority,
1584 &callback,
1585 pool_.get(),
1586 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531587 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131588 EXPECT_EQ(ERR_IO_PENDING,
1589 handle2.Init("a",
1590 params_,
1591 kDefaultPriority,
1592 &callback2,
1593 pool_.get(),
1594 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571595
[email protected]2431756e2010-09-29 20:26:131596 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571597
[email protected]fd7b7c92009-08-20 19:38:301598
1599 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301600
[email protected]2431756e2010-09-29 20:26:131601 EXPECT_EQ(OK, callback2.WaitForResult());
1602 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301603
1604 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531605 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571606}
1607
[email protected]4d3b05d2010-01-27 21:27:291608TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341609 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1610
[email protected]17a0c6c2009-08-04 00:07:041611 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1612
[email protected]ac790b42009-12-02 04:31:311613 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1614 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1615 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1616 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341617
1618 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131619 (*requests())[2]->handle()->Reset();
1620 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341621 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1622
[email protected]2431756e2010-09-29 20:26:131623 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341624 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1625
[email protected]2431756e2010-09-29 20:26:131626 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261627 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341628}
1629
[email protected]5fc08e32009-07-15 17:09:571630// When requests and ConnectJobs are not coupled, the request will get serviced
1631// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291632TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531633 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571634
1635 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321636 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571637
[email protected]2431756e2010-09-29 20:26:131638 std::vector<TestSocketRequest*> request_order;
1639 size_t completion_count; // unused
1640 TestSocketRequest req1(&request_order, &completion_count);
1641 int rv = req1.handle()->Init("a",
1642 params_,
1643 kDefaultPriority,
1644 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211645 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571646 EXPECT_EQ(ERR_IO_PENDING, rv);
1647 EXPECT_EQ(OK, req1.WaitForResult());
1648
1649 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1650 // without a job.
1651 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1652
[email protected]2431756e2010-09-29 20:26:131653 TestSocketRequest req2(&request_order, &completion_count);
1654 rv = req2.handle()->Init("a",
1655 params_,
1656 kDefaultPriority,
1657 &req2,
1658 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211659 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571660 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131661 TestSocketRequest req3(&request_order, &completion_count);
1662 rv = req3.handle()->Init("a",
1663 params_,
1664 kDefaultPriority,
1665 &req3,
1666 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211667 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571668 EXPECT_EQ(ERR_IO_PENDING, rv);
1669
1670 // Both Requests 2 and 3 are pending. We release socket 1 which should
1671 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331672 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261673 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331674 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571675 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331676 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571677
1678 // Signal job 2, which should service request 3.
1679
1680 client_socket_factory_.SignalJobs();
1681 EXPECT_EQ(OK, req3.WaitForResult());
1682
[email protected]2431756e2010-09-29 20:26:131683 ASSERT_EQ(3U, request_order.size());
1684 EXPECT_EQ(&req1, request_order[0]);
1685 EXPECT_EQ(&req2, request_order[1]);
1686 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571687 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1688}
1689
1690// The requests are not coupled to the jobs. So, the requests should finish in
1691// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291692TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531693 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571694 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321695 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571696
[email protected]2431756e2010-09-29 20:26:131697 std::vector<TestSocketRequest*> request_order;
1698 size_t completion_count; // unused
1699 TestSocketRequest req1(&request_order, &completion_count);
1700 int rv = req1.handle()->Init("a",
1701 params_,
1702 kDefaultPriority,
1703 &req1,
1704 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211705 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571706 EXPECT_EQ(ERR_IO_PENDING, rv);
1707
[email protected]2431756e2010-09-29 20:26:131708 TestSocketRequest req2(&request_order, &completion_count);
1709 rv = req2.handle()->Init("a",
1710 params_,
1711 kDefaultPriority,
1712 &req2,
1713 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211714 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571715 EXPECT_EQ(ERR_IO_PENDING, rv);
1716
1717 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321718 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571719
[email protected]2431756e2010-09-29 20:26:131720 TestSocketRequest req3(&request_order, &completion_count);
1721 rv = req3.handle()->Init("a",
1722 params_,
1723 kDefaultPriority,
1724 &req3,
1725 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211726 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571727 EXPECT_EQ(ERR_IO_PENDING, rv);
1728
1729 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1730 EXPECT_EQ(OK, req2.WaitForResult());
1731 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1732
[email protected]2431756e2010-09-29 20:26:131733 ASSERT_EQ(3U, request_order.size());
1734 EXPECT_EQ(&req1, request_order[0]);
1735 EXPECT_EQ(&req2, request_order[1]);
1736 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571737}
1738
[email protected]e6ec67b2010-06-16 00:12:461739TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531740 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571741 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321742 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571743
[email protected]2431756e2010-09-29 20:26:131744 ClientSocketHandle handle;
1745 TestCompletionCallback callback;
1746 int rv = handle.Init("a",
1747 params_,
1748 kDefaultPriority,
1749 &callback,
1750 pool_.get(),
1751 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571752 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131753 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571754
1755 MessageLoop::current()->RunAllPending();
1756
[email protected]2431756e2010-09-29 20:26:131757 ClientSocketHandle handle2;
1758 TestCompletionCallback callback2;
1759 rv = handle2.Init("a",
1760 params_,
1761 kDefaultPriority,
1762 &callback2, pool_.get(),
1763 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571764 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131765 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1766 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571767}
1768
[email protected]e772db3f2010-07-12 18:11:131769TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1770 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1771 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1772
[email protected]2431756e2010-09-29 20:26:131773 ClientSocketHandle handle;
1774 TestCompletionCallback callback;
1775 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1776 params_,
1777 kDefaultPriority,
1778 &callback, pool_.get(),
1779 BoundNetLog()));
1780 EXPECT_TRUE(handle.is_initialized());
1781 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131782}
1783
1784TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1785 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1786
1787 connect_job_factory_->set_job_type(
1788 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131789 ClientSocketHandle handle;
1790 TestCompletionCallback callback;
1791 EXPECT_EQ(ERR_IO_PENDING,
1792 handle.Init("a",
1793 params_,
1794 kDefaultPriority,
1795 &callback,
1796 pool_.get(),
1797 BoundNetLog()));
1798 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1799 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1800 EXPECT_TRUE(handle.is_initialized());
1801 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131802}
1803
[email protected]e60e47a2010-07-14 03:37:181804TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1805 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1806 connect_job_factory_->set_job_type(
1807 TestConnectJob::kMockAdditionalErrorStateJob);
1808
[email protected]2431756e2010-09-29 20:26:131809 ClientSocketHandle handle;
1810 TestCompletionCallback callback;
1811 EXPECT_EQ(ERR_CONNECTION_FAILED,
1812 handle.Init("a",
1813 params_,
1814 kDefaultPriority,
1815 &callback,
1816 pool_.get(),
1817 BoundNetLog()));
1818 EXPECT_FALSE(handle.is_initialized());
1819 EXPECT_FALSE(handle.socket());
1820 EXPECT_TRUE(handle.is_ssl_error());
1821 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181822}
1823
1824TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1825 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1826
1827 connect_job_factory_->set_job_type(
1828 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131829 ClientSocketHandle handle;
1830 TestCompletionCallback callback;
1831 EXPECT_EQ(ERR_IO_PENDING,
1832 handle.Init("a",
1833 params_,
1834 kDefaultPriority,
1835 &callback,
1836 pool_.get(),
1837 BoundNetLog()));
1838 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1839 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1840 EXPECT_FALSE(handle.is_initialized());
1841 EXPECT_FALSE(handle.socket());
1842 EXPECT_TRUE(handle.is_ssl_error());
1843 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181844}
1845
[email protected]4d3b05d2010-01-27 21:27:291846TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161847 CreatePoolWithIdleTimeouts(
1848 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1849 base::TimeDelta(), // Time out unused sockets immediately.
1850 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1851
1852 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1853
1854 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1855
[email protected]2431756e2010-09-29 20:26:131856 ClientSocketHandle handle;
1857 TestCompletionCallback callback;
1858 int rv = handle.Init("a",
1859 params_,
1860 LOWEST,
1861 &callback,
1862 pool_.get(),
1863 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161864 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131865 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161866
[email protected]2431756e2010-09-29 20:26:131867 ClientSocketHandle handle2;
1868 TestCompletionCallback callback2;
1869 rv = handle2.Init("a",
1870 params_,
1871 LOWEST,
1872 &callback2,
1873 pool_.get(),
1874 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131876 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161877
1878 // Cancel one of the requests. Wait for the other, which will get the first
1879 // job. Release the socket. Run the loop again to make sure the second
1880 // socket is sitting idle and the first one is released (since ReleaseSocket()
1881 // just posts a DoReleaseSocket() task).
1882
[email protected]2431756e2010-09-29 20:26:131883 handle.Reset();
1884 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011885 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131886 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1887 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471888
1889 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1890 // actually become pending until 2ms after they have been created. In order
1891 // to flush all tasks, we need to wait so that we know there are no
1892 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081893 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161894 MessageLoop::current()->RunAllPending();
1895
1896 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041897
[email protected]9bf28db2009-08-29 01:35:161898 // Invoke the idle socket cleanup check. Only one socket should be left, the
1899 // used socket. Request it to make sure that it's used.
1900
1901 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531902 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131903 rv = handle.Init("a",
1904 params_,
1905 LOWEST,
1906 &callback,
1907 pool_.get(),
1908 log.bound());
[email protected]9bf28db2009-08-29 01:35:161909 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131910 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:401911
1912 net::CapturingNetLog::EntryList entries;
1913 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:151914 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:401915 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161916}
1917
[email protected]2041cf342010-02-19 03:15:591918// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161919// because of multiple releasing disconnected sockets.
1920TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1921 CreatePoolWithIdleTimeouts(
1922 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1923 base::TimeDelta(), // Time out unused sockets immediately.
1924 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1925
1926 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1927
1928 // Startup 4 connect jobs. Two of them will be pending.
1929
[email protected]2431756e2010-09-29 20:26:131930 ClientSocketHandle handle;
1931 TestCompletionCallback callback;
1932 int rv = handle.Init("a",
1933 params_,
1934 LOWEST,
1935 &callback,
1936 pool_.get(),
1937 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161938 EXPECT_EQ(OK, rv);
1939
[email protected]2431756e2010-09-29 20:26:131940 ClientSocketHandle handle2;
1941 TestCompletionCallback callback2;
1942 rv = handle2.Init("a",
1943 params_,
1944 LOWEST,
1945 &callback2,
1946 pool_.get(),
1947 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161948 EXPECT_EQ(OK, rv);
1949
[email protected]2431756e2010-09-29 20:26:131950 ClientSocketHandle handle3;
1951 TestCompletionCallback callback3;
1952 rv = handle3.Init("a",
1953 params_,
1954 LOWEST,
1955 &callback3,
1956 pool_.get(),
1957 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161958 EXPECT_EQ(ERR_IO_PENDING, rv);
1959
[email protected]2431756e2010-09-29 20:26:131960 ClientSocketHandle handle4;
1961 TestCompletionCallback callback4;
1962 rv = handle4.Init("a",
1963 params_,
1964 LOWEST,
1965 &callback4,
1966 pool_.get(),
1967 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161968 EXPECT_EQ(ERR_IO_PENDING, rv);
1969
1970 // Release two disconnected sockets.
1971
[email protected]2431756e2010-09-29 20:26:131972 handle.socket()->Disconnect();
1973 handle.Reset();
1974 handle2.socket()->Disconnect();
1975 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161976
[email protected]2431756e2010-09-29 20:26:131977 EXPECT_EQ(OK, callback3.WaitForResult());
1978 EXPECT_FALSE(handle3.is_reused());
1979 EXPECT_EQ(OK, callback4.WaitForResult());
1980 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161981}
1982
[email protected]d7027bb2010-05-10 18:58:541983// Regression test for http://crbug.com/42267.
1984// When DoReleaseSocket() is processed for one socket, it is blocked because the
1985// other stalled groups all have releasing sockets, so no progress can be made.
1986TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1987 CreatePoolWithIdleTimeouts(
1988 4 /* socket limit */, 4 /* socket limit per group */,
1989 base::TimeDelta(), // Time out unused sockets immediately.
1990 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1991
1992 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1993
1994 // Max out the socket limit with 2 per group.
1995
[email protected]2431756e2010-09-29 20:26:131996 ClientSocketHandle handle_a[4];
1997 TestCompletionCallback callback_a[4];
1998 ClientSocketHandle handle_b[4];
1999 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542000
2001 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132002 EXPECT_EQ(OK, handle_a[i].Init("a",
2003 params_,
2004 LOWEST,
2005 &callback_a[i],
2006 pool_.get(),
2007 BoundNetLog()));
2008 EXPECT_EQ(OK, handle_b[i].Init("b",
2009 params_,
2010 LOWEST,
2011 &callback_b[i],
2012 pool_.get(),
2013 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542014 }
[email protected]b89f7e42010-05-20 20:37:002015
[email protected]d7027bb2010-05-10 18:58:542016 // Make 4 pending requests, 2 per group.
2017
2018 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132019 EXPECT_EQ(ERR_IO_PENDING,
2020 handle_a[i].Init("a",
2021 params_,
2022 LOWEST,
2023 &callback_a[i],
2024 pool_.get(),
2025 BoundNetLog()));
2026 EXPECT_EQ(ERR_IO_PENDING,
2027 handle_b[i].Init("b",
2028 params_,
2029 LOWEST,
2030 &callback_b[i],
2031 pool_.get(),
2032 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542033 }
2034
2035 // Release b's socket first. The order is important, because in
2036 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2037 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2038 // first, which has a releasing socket, so it refuses to start up another
2039 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132040 handle_b[0].socket()->Disconnect();
2041 handle_b[0].Reset();
2042 handle_a[0].socket()->Disconnect();
2043 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542044
2045 // Used to get stuck here.
2046 MessageLoop::current()->RunAllPending();
2047
[email protected]2431756e2010-09-29 20:26:132048 handle_b[1].socket()->Disconnect();
2049 handle_b[1].Reset();
2050 handle_a[1].socket()->Disconnect();
2051 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542052
2053 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132054 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2055 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542056 }
2057}
2058
[email protected]fd4fe0b2010-02-08 23:02:152059TEST_F(ClientSocketPoolBaseTest,
2060 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2061 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2062
2063 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2064
2065 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2066 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2069
[email protected]2431756e2010-09-29 20:26:132070 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2071 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2072 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152073
2074 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132075 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2076 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152077
[email protected]2431756e2010-09-29 20:26:132078 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2079 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2080 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152081
2082 EXPECT_EQ(1, GetOrderOfRequest(1));
2083 EXPECT_EQ(2, GetOrderOfRequest(2));
2084 EXPECT_EQ(3, GetOrderOfRequest(3));
2085 EXPECT_EQ(4, GetOrderOfRequest(4));
2086
2087 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132088 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152089}
2090
[email protected]4f1e4982010-03-02 18:31:042091class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2092 public:
[email protected]2431756e2010-09-29 20:26:132093 TestReleasingSocketRequest(TestClientSocketPool* pool,
2094 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182095 bool reset_releasing_handle)
2096 : pool_(pool),
2097 expected_result_(expected_result),
2098 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042099
2100 ClientSocketHandle* handle() { return &handle_; }
2101
2102 int WaitForResult() {
2103 return callback_.WaitForResult();
2104 }
2105
2106 virtual void RunWithParams(const Tuple1<int>& params) {
2107 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182108 if (reset_releasing_handle_)
2109 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272110 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132111 EXPECT_EQ(expected_result_, handle2_.Init("a",
2112 con_params,
2113 kDefaultPriority,
2114 &callback2_,
2115 pool_,
[email protected]e60e47a2010-07-14 03:37:182116 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042117 }
2118
2119 private:
[email protected]2431756e2010-09-29 20:26:132120 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182121 int expected_result_;
2122 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042123 ClientSocketHandle handle_;
2124 ClientSocketHandle handle2_;
2125 TestCompletionCallback callback_;
2126 TestCompletionCallback callback2_;
2127};
2128
[email protected]e60e47a2010-07-14 03:37:182129
2130TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2131 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2132
2133 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2134 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2135 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2136
[email protected]2431756e2010-09-29 20:26:132137 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182138 client_socket_factory_.allocation_count());
2139
2140 connect_job_factory_->set_job_type(
2141 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2142 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132143 EXPECT_EQ(ERR_IO_PENDING,
2144 req.handle()->Init("a",
2145 params_,
2146 kDefaultPriority,
2147 &req,
2148 pool_.get(),
2149 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182150 // The next job should complete synchronously
2151 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2152
2153 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2154 EXPECT_FALSE(req.handle()->is_initialized());
2155 EXPECT_FALSE(req.handle()->socket());
2156 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432157 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182158}
2159
[email protected]b6501d3d2010-06-03 23:53:342160// http://crbug.com/44724 regression test.
2161// We start releasing the pool when we flush on network change. When that
2162// happens, the only active references are in the ClientSocketHandles. When a
2163// ConnectJob completes and calls back into the last ClientSocketHandle, that
2164// callback can release the last reference and delete the pool. After the
2165// callback finishes, we go back to the stack frame within the now-deleted pool.
2166// Executing any code that refers to members of the now-deleted pool can cause
2167// crashes.
2168TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2169 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2170 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2171
2172 ClientSocketHandle handle;
2173 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132174 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2175 params_,
2176 kDefaultPriority,
2177 &callback,
2178 pool_.get(),
2179 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342180
[email protected]2431756e2010-09-29 20:26:132181 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342182
2183 // We'll call back into this now.
2184 callback.WaitForResult();
2185}
2186
[email protected]a7e38572010-06-07 18:22:242187TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2188 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2189 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2190
2191 ClientSocketHandle handle;
2192 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132193 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2194 params_,
2195 kDefaultPriority,
2196 &callback,
2197 pool_.get(),
2198 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242199 EXPECT_EQ(OK, callback.WaitForResult());
2200 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2201
2202 pool_->Flush();
2203
2204 handle.Reset();
2205 MessageLoop::current()->RunAllPending();
2206
[email protected]2431756e2010-09-29 20:26:132207 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2208 params_,
2209 kDefaultPriority,
2210 &callback,
2211 pool_.get(),
2212 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242213 EXPECT_EQ(OK, callback.WaitForResult());
2214 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2215}
2216
[email protected]06f92462010-08-31 19:24:142217class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2218 public:
2219 ConnectWithinCallback(
2220 const std::string& group_name,
2221 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132222 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142223 : group_name_(group_name), params_(params), pool_(pool) {}
2224
2225 ~ConnectWithinCallback() {}
2226
2227 virtual void RunWithParams(const Tuple1<int>& params) {
2228 callback_.RunWithParams(params);
2229 EXPECT_EQ(ERR_IO_PENDING,
2230 handle_.Init(group_name_,
2231 params_,
2232 kDefaultPriority,
2233 &nested_callback_,
2234 pool_,
2235 BoundNetLog()));
2236 }
2237
2238 int WaitForResult() {
2239 return callback_.WaitForResult();
2240 }
2241
2242 int WaitForNestedResult() {
2243 return nested_callback_.WaitForResult();
2244 }
2245
2246 private:
2247 const std::string group_name_;
2248 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132249 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142250 ClientSocketHandle handle_;
2251 TestCompletionCallback callback_;
2252 TestCompletionCallback nested_callback_;
2253};
2254
2255TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2256 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2257
2258 // First job will be waiting until it gets aborted.
2259 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2260
2261 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132262 ConnectWithinCallback callback("a", params_, pool_.get());
2263 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2264 params_,
2265 kDefaultPriority,
2266 &callback,
2267 pool_.get(),
2268 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142269
2270 // Second job will be started during the first callback, and will
2271 // asynchronously complete with OK.
2272 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2273 pool_->Flush();
2274 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2275 EXPECT_EQ(OK, callback.WaitForNestedResult());
2276}
2277
[email protected]25eea382010-07-10 23:55:262278// Cancel a pending socket request while we're at max sockets,
2279// and verify that the backup socket firing doesn't cause a crash.
2280TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2281 // Max 4 sockets globally, max 4 sockets per group.
2282 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222283 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262284
[email protected]4baaf9d2010-08-31 15:15:442285 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2286 // timer.
[email protected]25eea382010-07-10 23:55:262287 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2288 ClientSocketHandle handle;
2289 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132290 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2291 params_,
2292 kDefaultPriority,
2293 &callback,
2294 pool_.get(),
2295 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262296
2297 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2298 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2299 ClientSocketHandle handles[kDefaultMaxSockets];
2300 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2301 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132302 EXPECT_EQ(OK, handles[i].Init("bar",
2303 params_,
2304 kDefaultPriority,
2305 &callback,
2306 pool_.get(),
2307 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262308 }
2309
2310 MessageLoop::current()->RunAllPending();
2311
2312 // Cancel the pending request.
2313 handle.Reset();
2314
2315 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082316 base::PlatformThread::Sleep(
2317 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262318
2319 MessageLoop::current()->RunAllPending();
2320 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2321}
2322
[email protected]3f00be82010-09-27 19:50:022323TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442324 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2325 pool_->EnableConnectBackupJobs();
2326
2327 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2328 // timer.
2329 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2330 ClientSocketHandle handle;
2331 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132332 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2333 params_,
2334 kDefaultPriority,
2335 &callback,
2336 pool_.get(),
2337 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442338 ASSERT_TRUE(pool_->HasGroup("bar"));
2339 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2340
2341 // Cancel the socket request. This should cancel the backup timer. Wait for
2342 // the backup time to see if it indeed got canceled.
2343 handle.Reset();
2344 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082345 base::PlatformThread::Sleep(
2346 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442347 MessageLoop::current()->RunAllPending();
2348 ASSERT_TRUE(pool_->HasGroup("bar"));
2349 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2350}
2351
[email protected]3f00be82010-09-27 19:50:022352TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2353 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2354 pool_->EnableConnectBackupJobs();
2355
2356 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2357 // timer.
2358 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2359 ClientSocketHandle handle;
2360 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132361 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2362 params_,
2363 kDefaultPriority,
2364 &callback,
2365 pool_.get(),
2366 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022367 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2368 ClientSocketHandle handle2;
2369 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132370 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2371 params_,
2372 kDefaultPriority,
2373 &callback2,
2374 pool_.get(),
2375 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022376 ASSERT_TRUE(pool_->HasGroup("bar"));
2377 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2378
2379 // Cancel request 1 and then complete request 2. With the requests finished,
2380 // the backup timer should be cancelled.
2381 handle.Reset();
2382 EXPECT_EQ(OK, callback2.WaitForResult());
2383 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082384 base::PlatformThread::Sleep(
2385 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022386 MessageLoop::current()->RunAllPending();
2387}
2388
[email protected]eb5a99382010-07-11 03:18:262389// Test delayed socket binding for the case where we have two connects,
2390// and while one is waiting on a connect, the other frees up.
2391// The socket waiting on a connect should switch immediately to the freed
2392// up socket.
2393TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2394 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2395 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2396
2397 ClientSocketHandle handle1;
2398 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132399 EXPECT_EQ(ERR_IO_PENDING,
2400 handle1.Init("a",
2401 params_,
2402 kDefaultPriority,
2403 &callback,
2404 pool_.get(),
2405 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262406 EXPECT_EQ(OK, callback.WaitForResult());
2407
2408 // No idle sockets, no pending jobs.
2409 EXPECT_EQ(0, pool_->IdleSocketCount());
2410 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2411
2412 // Create a second socket to the same host, but this one will wait.
2413 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2414 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132415 EXPECT_EQ(ERR_IO_PENDING,
2416 handle2.Init("a",
2417 params_,
2418 kDefaultPriority,
2419 &callback,
2420 pool_.get(),
2421 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262422 // No idle sockets, and one connecting job.
2423 EXPECT_EQ(0, pool_->IdleSocketCount());
2424 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2425
2426 // Return the first handle to the pool. This will initiate the delayed
2427 // binding.
2428 handle1.Reset();
2429
2430 MessageLoop::current()->RunAllPending();
2431
2432 // Still no idle sockets, still one pending connect job.
2433 EXPECT_EQ(0, pool_->IdleSocketCount());
2434 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2435
2436 // The second socket connected, even though it was a Waiting Job.
2437 EXPECT_EQ(OK, callback.WaitForResult());
2438
2439 // And we can see there is still one job waiting.
2440 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2441
2442 // Finally, signal the waiting Connect.
2443 client_socket_factory_.SignalJobs();
2444 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2445
2446 MessageLoop::current()->RunAllPending();
2447}
2448
2449// Test delayed socket binding when a group is at capacity and one
2450// of the group's sockets frees up.
2451TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2452 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2453 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2454
2455 ClientSocketHandle handle1;
2456 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132457 EXPECT_EQ(ERR_IO_PENDING,
2458 handle1.Init("a",
2459 params_,
2460 kDefaultPriority,
2461 &callback,
2462 pool_.get(),
2463 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262464 EXPECT_EQ(OK, callback.WaitForResult());
2465
2466 // No idle sockets, no pending jobs.
2467 EXPECT_EQ(0, pool_->IdleSocketCount());
2468 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2469
2470 // Create a second socket to the same host, but this one will wait.
2471 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2472 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132473 EXPECT_EQ(ERR_IO_PENDING,
2474 handle2.Init("a",
2475 params_,
2476 kDefaultPriority,
2477 &callback,
2478 pool_.get(),
2479 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262480 // No idle sockets, and one connecting job.
2481 EXPECT_EQ(0, pool_->IdleSocketCount());
2482 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2483
2484 // Return the first handle to the pool. This will initiate the delayed
2485 // binding.
2486 handle1.Reset();
2487
2488 MessageLoop::current()->RunAllPending();
2489
2490 // Still no idle sockets, still one pending connect job.
2491 EXPECT_EQ(0, pool_->IdleSocketCount());
2492 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2493
2494 // The second socket connected, even though it was a Waiting Job.
2495 EXPECT_EQ(OK, callback.WaitForResult());
2496
2497 // And we can see there is still one job waiting.
2498 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2499
2500 // Finally, signal the waiting Connect.
2501 client_socket_factory_.SignalJobs();
2502 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2503
2504 MessageLoop::current()->RunAllPending();
2505}
2506
2507// Test out the case where we have one socket connected, one
2508// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512509// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262510// should complete, by taking the first socket's idle socket.
2511TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2512 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2513 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2514
2515 ClientSocketHandle handle1;
2516 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132517 EXPECT_EQ(ERR_IO_PENDING,
2518 handle1.Init("a",
2519 params_,
2520 kDefaultPriority,
2521 &callback,
2522 pool_.get(),
2523 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262524 EXPECT_EQ(OK, callback.WaitForResult());
2525
2526 // No idle sockets, no pending jobs.
2527 EXPECT_EQ(0, pool_->IdleSocketCount());
2528 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2529
2530 // Create a second socket to the same host, but this one will wait.
2531 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2532 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132533 EXPECT_EQ(ERR_IO_PENDING,
2534 handle2.Init("a",
2535 params_,
2536 kDefaultPriority,
2537 &callback,
2538 pool_.get(),
2539 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262540 // No idle sockets, and one connecting job.
2541 EXPECT_EQ(0, pool_->IdleSocketCount());
2542 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2543
2544 // Return the first handle to the pool. This will initiate the delayed
2545 // binding.
2546 handle1.Reset();
2547
2548 MessageLoop::current()->RunAllPending();
2549
2550 // Still no idle sockets, still one pending connect job.
2551 EXPECT_EQ(0, pool_->IdleSocketCount());
2552 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2553
2554 // The second socket connected, even though it was a Waiting Job.
2555 EXPECT_EQ(OK, callback.WaitForResult());
2556
2557 // And we can see there is still one job waiting.
2558 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2559
2560 // Finally, signal the waiting Connect.
2561 client_socket_factory_.SignalJobs();
2562 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2563
2564 MessageLoop::current()->RunAllPending();
2565}
2566
[email protected]2abfe90a2010-08-25 17:49:512567// Cover the case where on an available socket slot, we have one pending
2568// request that completes synchronously, thereby making the Group empty.
2569TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2570 const int kUnlimitedSockets = 100;
2571 const int kOneSocketPerGroup = 1;
2572 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2573
2574 // Make the first request asynchronous fail.
2575 // This will free up a socket slot later.
2576 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2577
2578 ClientSocketHandle handle1;
2579 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132580 EXPECT_EQ(ERR_IO_PENDING,
2581 handle1.Init("a",
2582 params_,
2583 kDefaultPriority,
2584 &callback1,
2585 pool_.get(),
2586 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512587 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2588
2589 // Make the second request synchronously fail. This should make the Group
2590 // empty.
2591 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2592 ClientSocketHandle handle2;
2593 TestCompletionCallback callback2;
2594 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2595 // when created.
[email protected]2431756e2010-09-29 20:26:132596 EXPECT_EQ(ERR_IO_PENDING,
2597 handle2.Init("a",
2598 params_,
2599 kDefaultPriority,
2600 &callback2,
2601 pool_.get(),
2602 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512603
2604 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2605
2606 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2607 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2608 EXPECT_FALSE(pool_->HasGroup("a"));
2609}
2610
[email protected]e1b54dc2010-10-06 21:27:222611TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2612 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2613
2614 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2615
2616 ClientSocketHandle handle1;
2617 TestCompletionCallback callback1;
2618 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2619 params_,
2620 kDefaultPriority,
2621 &callback1,
2622 pool_.get(),
2623 BoundNetLog()));
2624
2625 ClientSocketHandle handle2;
2626 TestCompletionCallback callback2;
2627 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2628 params_,
2629 kDefaultPriority,
2630 &callback2,
2631 pool_.get(),
2632 BoundNetLog()));
2633 ClientSocketHandle handle3;
2634 TestCompletionCallback callback3;
2635 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2636 params_,
2637 kDefaultPriority,
2638 &callback3,
2639 pool_.get(),
2640 BoundNetLog()));
2641
2642 EXPECT_EQ(OK, callback1.WaitForResult());
2643 EXPECT_EQ(OK, callback2.WaitForResult());
2644 EXPECT_EQ(OK, callback3.WaitForResult());
2645
2646 // Use the socket.
2647 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2648 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2649
2650 handle1.Reset();
2651 handle2.Reset();
2652 handle3.Reset();
2653
2654 EXPECT_EQ(OK, handle1.Init("a",
2655 params_,
2656 kDefaultPriority,
2657 &callback1,
2658 pool_.get(),
2659 BoundNetLog()));
2660 EXPECT_EQ(OK, handle2.Init("a",
2661 params_,
2662 kDefaultPriority,
2663 &callback2,
2664 pool_.get(),
2665 BoundNetLog()));
2666 EXPECT_EQ(OK, handle3.Init("a",
2667 params_,
2668 kDefaultPriority,
2669 &callback3,
2670 pool_.get(),
2671 BoundNetLog()));
2672
2673 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2674 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2675 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2676}
2677
[email protected]2c2bef152010-10-13 00:55:032678TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2679 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2680 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2681
2682 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2683
2684 ASSERT_TRUE(pool_->HasGroup("a"));
2685 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2686 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2687
2688 ClientSocketHandle handle1;
2689 TestCompletionCallback callback1;
2690 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2691 params_,
2692 kDefaultPriority,
2693 &callback1,
2694 pool_.get(),
2695 BoundNetLog()));
2696
2697 ClientSocketHandle handle2;
2698 TestCompletionCallback callback2;
2699 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2700 params_,
2701 kDefaultPriority,
2702 &callback2,
2703 pool_.get(),
2704 BoundNetLog()));
2705
2706 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2707 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2708
2709 EXPECT_EQ(OK, callback1.WaitForResult());
2710 EXPECT_EQ(OK, callback2.WaitForResult());
2711 handle1.Reset();
2712 handle2.Reset();
2713
2714 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2715 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2716}
2717
2718TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2719 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2720 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2721
2722 ClientSocketHandle handle1;
2723 TestCompletionCallback callback1;
2724 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2725 params_,
2726 kDefaultPriority,
2727 &callback1,
2728 pool_.get(),
2729 BoundNetLog()));
2730
2731 ASSERT_TRUE(pool_->HasGroup("a"));
2732 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2733 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2734
2735 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2736
2737 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2738 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2739
2740 ClientSocketHandle handle2;
2741 TestCompletionCallback callback2;
2742 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2743 params_,
2744 kDefaultPriority,
2745 &callback2,
2746 pool_.get(),
2747 BoundNetLog()));
2748
2749 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2750 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2751
2752 EXPECT_EQ(OK, callback1.WaitForResult());
2753 EXPECT_EQ(OK, callback2.WaitForResult());
2754 handle1.Reset();
2755 handle2.Reset();
2756
2757 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2758 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2759}
2760
2761TEST_F(ClientSocketPoolBaseTest,
2762 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2763 CreatePool(4, 4);
2764 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2765
2766 ClientSocketHandle handle1;
2767 TestCompletionCallback callback1;
2768 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2769 params_,
2770 kDefaultPriority,
2771 &callback1,
2772 pool_.get(),
2773 BoundNetLog()));
2774
2775 ClientSocketHandle handle2;
2776 TestCompletionCallback callback2;
2777 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2778 params_,
2779 kDefaultPriority,
2780 &callback2,
2781 pool_.get(),
2782 BoundNetLog()));
2783
2784 ClientSocketHandle handle3;
2785 TestCompletionCallback callback3;
2786 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2787 params_,
2788 kDefaultPriority,
2789 &callback3,
2790 pool_.get(),
2791 BoundNetLog()));
2792
2793 ASSERT_TRUE(pool_->HasGroup("a"));
2794 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2795 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2796
2797 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2798
2799 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2800 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2801
2802 EXPECT_EQ(OK, callback1.WaitForResult());
2803 EXPECT_EQ(OK, callback2.WaitForResult());
2804 EXPECT_EQ(OK, callback3.WaitForResult());
2805 handle1.Reset();
2806 handle2.Reset();
2807 handle3.Reset();
2808
2809 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2810 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2811}
2812
2813TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2814 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2815 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2816
2817 ASSERT_FALSE(pool_->HasGroup("a"));
2818
2819 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2820 BoundNetLog());
2821
2822 ASSERT_TRUE(pool_->HasGroup("a"));
2823 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2824
2825 ASSERT_FALSE(pool_->HasGroup("b"));
2826
2827 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2828 BoundNetLog());
2829
2830 ASSERT_FALSE(pool_->HasGroup("b"));
2831}
2832
2833TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2834 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2835 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2836
2837 ASSERT_FALSE(pool_->HasGroup("a"));
2838
2839 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2840 BoundNetLog());
2841
2842 ASSERT_TRUE(pool_->HasGroup("a"));
2843 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2844
2845 ASSERT_FALSE(pool_->HasGroup("b"));
2846
2847 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2848 BoundNetLog());
2849
2850 ASSERT_TRUE(pool_->HasGroup("b"));
2851 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2852}
2853
2854TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2855 CreatePool(4, 4);
2856 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2857
2858 ClientSocketHandle handle1;
2859 TestCompletionCallback callback1;
2860 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2861 params_,
2862 kDefaultPriority,
2863 &callback1,
2864 pool_.get(),
2865 BoundNetLog()));
2866 ASSERT_EQ(OK, callback1.WaitForResult());
2867 handle1.Reset();
2868
2869 ASSERT_TRUE(pool_->HasGroup("a"));
2870 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2871 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2872
2873 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2874
2875 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2876 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2877}
2878
2879TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2880 CreatePool(4, 4);
2881 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2882
2883 ClientSocketHandle handle1;
2884 TestCompletionCallback callback1;
2885 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2886 params_,
2887 kDefaultPriority,
2888 &callback1,
2889 pool_.get(),
2890 BoundNetLog()));
2891 ASSERT_EQ(OK, callback1.WaitForResult());
2892
2893 ASSERT_TRUE(pool_->HasGroup("a"));
2894 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2895 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2896 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2897
2898 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2899
2900 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2901 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2902 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2903}
2904
2905TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2906 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2907 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2908
2909 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2910 BoundNetLog());
2911
2912 ASSERT_TRUE(pool_->HasGroup("a"));
2913 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2914 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2915
2916 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2917 BoundNetLog());
2918
2919 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2920 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2921}
2922
[email protected]3c819f522010-12-02 02:03:122923TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
2924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2925 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2926
2927 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2928 BoundNetLog());
2929
2930 ASSERT_FALSE(pool_->HasGroup("a"));
2931}
2932
[email protected]2c2bef152010-10-13 00:55:032933TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2934 CreatePool(4, 4);
2935 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2936
2937 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2938
2939 ASSERT_TRUE(pool_->HasGroup("a"));
2940 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2941 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2942
2943 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2944 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2945 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2946
2947 ClientSocketHandle handle1;
2948 TestCompletionCallback callback1;
2949 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2950 params_,
2951 kDefaultPriority,
2952 &callback1,
2953 pool_.get(),
2954 BoundNetLog()));
2955 ASSERT_EQ(OK, callback1.WaitForResult());
2956
2957 ClientSocketHandle handle2;
2958 TestCompletionCallback callback2;
2959 int rv = handle2.Init("a",
2960 params_,
2961 kDefaultPriority,
2962 &callback2,
2963 pool_.get(),
2964 BoundNetLog());
2965 if (rv != OK) {
2966 EXPECT_EQ(ERR_IO_PENDING, rv);
2967 EXPECT_EQ(OK, callback2.WaitForResult());
2968 }
2969
2970 handle1.Reset();
2971 handle2.Reset();
2972
2973 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2974
2975 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2976 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2977 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2978}
2979
2980TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2981 CreatePool(4, 4);
2982 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2983
2984 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2985
2986 ASSERT_TRUE(pool_->HasGroup("a"));
2987 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2988 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2989
2990 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2991 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2992 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2993
2994 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2995 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2996 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2997
2998 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2999 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3000 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3001}
3002
3003TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3004 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3005 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3006
3007 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3008
3009 ASSERT_TRUE(pool_->HasGroup("a"));
3010 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3011 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3012
3013 ClientSocketHandle handle1;
3014 TestCompletionCallback callback1;
3015 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3016 params_,
3017 kDefaultPriority,
3018 &callback1,
3019 pool_.get(),
3020 BoundNetLog()));
3021
3022 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3023 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3024
3025 ASSERT_EQ(OK, callback1.WaitForResult());
3026
3027 handle1.Reset();
3028
3029 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3030}
3031
[email protected]dcbe168a2010-12-02 03:14:463032// http://crbug.com/64940 regression test.
3033TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3034 const int kMaxTotalSockets = 3;
3035 const int kMaxSocketsPerGroup = 2;
3036 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3037 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3038
3039 // Note that group name ordering matters here. "a" comes before "b", so
3040 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3041
3042 // Set up one idle socket in "a".
3043 ClientSocketHandle handle1;
3044 TestCompletionCallback callback1;
3045 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3046 params_,
3047 kDefaultPriority,
3048 &callback1,
3049 pool_.get(),
3050 BoundNetLog()));
3051
3052 ASSERT_EQ(OK, callback1.WaitForResult());
3053 handle1.Reset();
3054 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3055
3056 // Set up two active sockets in "b".
3057 ClientSocketHandle handle2;
3058 TestCompletionCallback callback2;
3059 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3060 params_,
3061 kDefaultPriority,
3062 &callback1,
3063 pool_.get(),
3064 BoundNetLog()));
3065 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3066 params_,
3067 kDefaultPriority,
3068 &callback2,
3069 pool_.get(),
3070 BoundNetLog()));
3071
3072 ASSERT_EQ(OK, callback1.WaitForResult());
3073 ASSERT_EQ(OK, callback2.WaitForResult());
3074 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3075 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3076
3077 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3078 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3079 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3080 // sockets for "a", and "b" should still have 2 active sockets.
3081
3082 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3083 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3084 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3085 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3086 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3087 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3088 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3089
3090 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3091 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3092 // "a" should result in closing 1 for "b".
3093 handle1.Reset();
3094 handle2.Reset();
3095 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3096 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3097
3098 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3099 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3100 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3101 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3102 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3103 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3104 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3105}
3106
[email protected]f6d1d6eb2009-06-24 20:16:093107} // namespace
3108
3109} // namespace net