blob: 4864001fd6dcba83b4f33aaf892d0366134cd67e [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 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"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/ref_counted.h"
10#include "base/memory/scoped_vector.h"
[email protected]f6d1d6eb2009-06-24 20:16:0911#include "base/message_loop.h"
[email protected]1870d5cf2011-05-12 01:55:4012#include "base/stringprintf.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.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_factory.h"
22#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0023#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1724#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1925#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1026#include "net/socket/stream_socket.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> {
[email protected]5acdce12011-03-30 13:00:2038 public:
39 bool ignore_limits() { return false; }
[email protected]df4b4ef2010-07-12 18:25:2140 private:
41 friend class base::RefCounted<TestSocketParams>;
42 ~TestSocketParams() {}
43};
[email protected]7fc5b09a2010-02-27 00:07:3844typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4945
[email protected]3268023f2011-05-05 00:08:1046class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0947 public:
[email protected]0f873e82010-09-02 16:09:0148 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0949
[email protected]ab838892009-06-30 18:49:0550 // Socket methods:
51 virtual int Read(
52 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
53 return ERR_UNEXPECTED;
54 }
55
56 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0157 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
58 was_used_to_convey_data_ = true;
59 return len;
[email protected]ab838892009-06-30 18:49:0560 }
[email protected]06650c52010-06-03 00:49:1761 virtual bool SetReceiveBufferSize(int32 size) { return true; }
62 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0563
[email protected]3268023f2011-05-05 00:08:1064 // StreamSocket methods:
[email protected]ab838892009-06-30 18:49:0565
[email protected]a2006ece2010-04-23 16:44:0266 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0967 connected_ = true;
68 return OK;
69 }
[email protected]f6d1d6eb2009-06-24 20:16:0970
[email protected]ab838892009-06-30 18:49:0571 virtual void Disconnect() { connected_ = false; }
72 virtual bool IsConnected() const { return connected_; }
73 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0174
[email protected]ac9eec62010-02-20 18:50:3875 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1676 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0977 }
[email protected]f6d1d6eb2009-06-24 20:16:0978
[email protected]e7f74da2011-04-19 23:49:3579 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
80 return ERR_UNEXPECTED;
81 }
82
[email protected]a2006ece2010-04-23 16:44:0283 virtual const BoundNetLog& NetLog() const {
84 return net_log_;
85 }
86
[email protected]9b5614a2010-08-25 20:29:4587 virtual void SetSubresourceSpeculation() {}
88 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0189 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]7f7e92392010-10-26 18:29:2990 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]9b5614a2010-08-25 20:29:4591
[email protected]f6d1d6eb2009-06-24 20:16:0992 private:
93 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0294 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0195 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0996
[email protected]ab838892009-06-30 18:49:0597 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0998};
99
[email protected]5fc08e32009-07-15 17:09:57100class TestConnectJob;
101
[email protected]f6d1d6eb2009-06-24 20:16:09102class MockClientSocketFactory : public ClientSocketFactory {
103 public:
[email protected]ab838892009-06-30 18:49:05104 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09105
[email protected]98b0e582011-06-22 14:31:41106 virtual DatagramClientSocket* CreateDatagramClientSocket(
107 NetLog* net_log,
108 const NetLog::Source& source) {
109 NOTREACHED();
110 return NULL;
111 }
112
[email protected]3268023f2011-05-05 00:08:10113 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07114 const AddressList& addresses,
115 NetLog* /* net_log */,
116 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09117 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05118 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09119 }
120
121 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18122 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27123 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21124 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12125 SSLHostInfo* ssl_host_info,
[email protected]822581d2010-12-16 17:27:15126 CertVerifier* cert_verifier,
[email protected]345c613b2010-11-22 19:33:18127 DnsCertProvenanceChecker* dns_cert_checker) {
[email protected]f6d1d6eb2009-06-24 20:16:09128 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21129 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09130 return NULL;
131 }
132
[email protected]25f47352011-02-25 16:31:59133 virtual void ClearSSLSessionCache() {
134 NOTIMPLEMENTED();
135 }
136
[email protected]5fc08e32009-07-15 17:09:57137 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
138 void SignalJobs();
139
[email protected]f6d1d6eb2009-06-24 20:16:09140 int allocation_count() const { return allocation_count_; }
141
[email protected]f6d1d6eb2009-06-24 20:16:09142 private:
143 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57144 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09145};
146
[email protected]ab838892009-06-30 18:49:05147class TestConnectJob : public ConnectJob {
148 public:
149 enum JobType {
150 kMockJob,
151 kMockFailingJob,
152 kMockPendingJob,
153 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57154 kMockWaitingJob,
155 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13156 kMockRecoverableJob,
157 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18158 kMockAdditionalErrorStateJob,
159 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05160 };
161
[email protected]994d4932010-07-12 17:55:13162 // The kMockPendingJob uses a slight delay before allowing the connect
163 // to complete.
164 static const int kPendingConnectDelay = 2;
165
[email protected]ab838892009-06-30 18:49:05166 TestConnectJob(JobType job_type,
167 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49168 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34169 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05170 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30171 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17172 NetLog* net_log)
173 : ConnectJob(group_name, timeout_duration, delegate,
174 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58175 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05176 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21177 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18178 load_state_(LOAD_STATE_IDLE),
179 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05180
[email protected]974ebd62009-08-03 23:14:34181 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13182 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34183 }
184
[email protected]46451352009-09-01 14:54:21185 virtual LoadState GetLoadState() const { return load_state_; }
186
[email protected]e60e47a2010-07-14 03:37:18187 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
188 if (store_additional_error_state_) {
189 // Set all of the additional error state fields in some way.
190 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43191 HttpResponseInfo info;
192 info.headers = new HttpResponseHeaders("");
193 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18194 }
195 }
196
[email protected]974ebd62009-08-03 23:14:34197 private:
[email protected]ab838892009-06-30 18:49:05198 // ConnectJob methods:
199
[email protected]974ebd62009-08-03 23:14:34200 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05201 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28202 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07203 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40204 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05205 switch (job_type_) {
206 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13207 return DoConnect(true /* successful */, false /* sync */,
208 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05209 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13210 return DoConnect(false /* error */, false /* sync */,
211 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05212 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57213 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47214
215 // Depending on execution timings, posting a delayed task can result
216 // in the task getting executed the at the earliest possible
217 // opportunity or only after returning once from the message loop and
218 // then a second call into the message loop. In order to make behavior
219 // more deterministic, we change the default delay to 2ms. This should
220 // always require us to wait for the second call into the message loop.
221 //
222 // N.B. The correct fix for this and similar timing problems is to
223 // abstract time for the purpose of unittests. Unfortunately, we have
224 // a lot of third-party components that directly call the various
225 // time functions, so this change would be rather invasive.
226 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05227 FROM_HERE,
228 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47229 &TestConnectJob::DoConnect,
230 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13231 true /* async */,
232 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13233 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05234 return ERR_IO_PENDING;
235 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57236 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47237 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05238 FROM_HERE,
239 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47240 &TestConnectJob::DoConnect,
241 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13242 true /* async */,
243 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47244 2);
[email protected]ab838892009-06-30 18:49:05245 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57246 case kMockWaitingJob:
247 client_socket_factory_->WaitForSignal(this);
248 waiting_success_ = true;
249 return ERR_IO_PENDING;
250 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46251 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57252 FROM_HERE,
253 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46254 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57255 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13256 case kMockRecoverableJob:
257 return DoConnect(false /* error */, false /* sync */,
258 true /* recoverable */);
259 case kMockPendingRecoverableJob:
260 set_load_state(LOAD_STATE_CONNECTING);
261 MessageLoop::current()->PostDelayedTask(
262 FROM_HERE,
263 method_factory_.NewRunnableMethod(
264 &TestConnectJob::DoConnect,
265 false /* error */,
266 true /* async */,
267 true /* recoverable */),
268 2);
269 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18270 case kMockAdditionalErrorStateJob:
271 store_additional_error_state_ = true;
272 return DoConnect(false /* error */, false /* sync */,
273 false /* recoverable */);
274 case kMockPendingAdditionalErrorStateJob:
275 set_load_state(LOAD_STATE_CONNECTING);
276 store_additional_error_state_ = true;
277 MessageLoop::current()->PostDelayedTask(
278 FROM_HERE,
279 method_factory_.NewRunnableMethod(
280 &TestConnectJob::DoConnect,
281 false /* error */,
282 true /* async */,
283 false /* recoverable */),
284 2);
285 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05286 default:
287 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40288 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05289 return ERR_FAILED;
290 }
291 }
292
[email protected]46451352009-09-01 14:54:21293 void set_load_state(LoadState load_state) { load_state_ = load_state; }
294
[email protected]e772db3f2010-07-12 18:11:13295 int DoConnect(bool succeed, bool was_async, bool recoverable) {
296 int result = OK;
[email protected]ab838892009-06-30 18:49:05297 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02298 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13299 } else if (recoverable) {
300 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40301 } else {
[email protected]e772db3f2010-07-12 18:11:13302 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40303 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05304 }
[email protected]2ab05b52009-07-01 23:57:58305
306 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30307 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05308 return result;
309 }
310
[email protected]cfa8228c2010-06-17 01:07:56311 // This function helps simulate the progress of load states on a ConnectJob.
312 // Each time it is called it advances the load state and posts a task to be
313 // called again. It stops at the last connecting load state (the one
314 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57315 void AdvanceLoadState(LoadState state) {
316 int tmp = state;
317 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56318 if (tmp < LOAD_STATE_SENDING_REQUEST) {
319 state = static_cast<LoadState>(tmp);
320 set_load_state(state);
321 MessageLoop::current()->PostTask(
322 FROM_HERE,
323 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
324 state));
325 }
[email protected]5fc08e32009-07-15 17:09:57326 }
327
328 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05329 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57330 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05331 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21332 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18333 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05334
335 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
336};
337
[email protected]d80a4322009-08-14 07:07:49338class TestConnectJobFactory
339 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05340 public:
[email protected]5fc08e32009-07-15 17:09:57341 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05342 : job_type_(TestConnectJob::kMockJob),
343 client_socket_factory_(client_socket_factory) {}
344
345 virtual ~TestConnectJobFactory() {}
346
347 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
348
[email protected]974ebd62009-08-03 23:14:34349 void set_timeout_duration(base::TimeDelta timeout_duration) {
350 timeout_duration_ = timeout_duration;
351 }
352
[email protected]ab838892009-06-30 18:49:05353 // ConnectJobFactory methods:
354
355 virtual ConnectJob* NewConnectJob(
356 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49357 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17358 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05359 return new TestConnectJob(job_type_,
360 group_name,
361 request,
[email protected]974ebd62009-08-03 23:14:34362 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05363 delegate,
[email protected]fd7b7c92009-08-20 19:38:30364 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17365 NULL);
[email protected]ab838892009-06-30 18:49:05366 }
367
[email protected]a796bcec2010-03-22 17:17:26368 virtual base::TimeDelta ConnectionTimeout() const {
369 return timeout_duration_;
370 }
371
[email protected]ab838892009-06-30 18:49:05372 private:
373 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34374 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57375 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05376
377 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
378};
379
380class TestClientSocketPool : public ClientSocketPool {
381 public:
382 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53383 int max_sockets,
[email protected]ab838892009-06-30 18:49:05384 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13385 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16386 base::TimeDelta unused_idle_socket_timeout,
387 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49388 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00389 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16390 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38391 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05392
[email protected]2431756e2010-09-29 20:26:13393 virtual ~TestClientSocketPool() {}
394
[email protected]ab838892009-06-30 18:49:05395 virtual int RequestSocket(
396 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49397 const void* params,
[email protected]ac790b42009-12-02 04:31:31398 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05399 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46400 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53401 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21402 const scoped_refptr<TestSocketParams>* casted_socket_params =
403 static_cast<const scoped_refptr<TestSocketParams>*>(params);
404 return base_.RequestSocket(group_name, *casted_socket_params, priority,
405 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05406 }
407
[email protected]2c2bef152010-10-13 00:55:03408 virtual void RequestSockets(const std::string& group_name,
409 const void* params,
410 int num_sockets,
411 const BoundNetLog& net_log) {
412 const scoped_refptr<TestSocketParams>* casted_params =
413 static_cast<const scoped_refptr<TestSocketParams>*>(params);
414
415 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
416 }
417
[email protected]ab838892009-06-30 18:49:05418 virtual void CancelRequest(
419 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21420 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49421 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05422 }
423
424 virtual void ReleaseSocket(
425 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10426 StreamSocket* socket,
[email protected]a7e38572010-06-07 18:22:24427 int id) {
428 base_.ReleaseSocket(group_name, socket, id);
429 }
430
431 virtual void Flush() {
432 base_.Flush();
[email protected]ab838892009-06-30 18:49:05433 }
434
435 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49436 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05437 }
438
[email protected]d80a4322009-08-14 07:07:49439 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05440
441 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49442 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05443 }
444
445 virtual LoadState GetLoadState(const std::string& group_name,
446 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49447 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05448 }
449
[email protected]ba00b492010-09-08 14:53:38450 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
451 const std::string& type,
452 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27453 return base_.GetInfoAsValue(name, type);
454 }
455
[email protected]a796bcec2010-03-22 17:17:26456 virtual base::TimeDelta ConnectionTimeout() const {
457 return base_.ConnectionTimeout();
458 }
459
[email protected]2431756e2010-09-29 20:26:13460 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00461 return base_.histograms();
462 }
[email protected]a796bcec2010-03-22 17:17:26463
[email protected]d80a4322009-08-14 07:07:49464 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20465
[email protected]974ebd62009-08-03 23:14:34466 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49467 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34468 }
469
[email protected]2c2bef152010-10-13 00:55:03470 int NumActiveSocketsInGroup(const std::string& group_name) const {
471 return base_.NumActiveSocketsInGroup(group_name);
472 }
473
[email protected]2abfe90a2010-08-25 17:49:51474 bool HasGroup(const std::string& group_name) const {
475 return base_.HasGroup(group_name);
476 }
477
[email protected]9bf28db2009-08-29 01:35:16478 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
479
[email protected]06d94042010-08-25 01:45:22480 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54481
[email protected]ab838892009-06-30 18:49:05482 private:
[email protected]d80a4322009-08-14 07:07:49483 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05484
485 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
486};
487
[email protected]a937a06d2009-08-19 21:19:24488} // namespace
489
[email protected]7fc5b09a2010-02-27 00:07:38490REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24491
492namespace {
493
[email protected]5fc08e32009-07-15 17:09:57494void MockClientSocketFactory::SignalJobs() {
495 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
496 it != waiting_jobs_.end(); ++it) {
497 (*it)->Signal();
498 }
499 waiting_jobs_.clear();
500}
501
[email protected]974ebd62009-08-03 23:14:34502class TestConnectJobDelegate : public ConnectJob::Delegate {
503 public:
504 TestConnectJobDelegate()
505 : have_result_(false), waiting_for_result_(false), result_(OK) {}
506 virtual ~TestConnectJobDelegate() {}
507
508 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
509 result_ = result;
[email protected]3268023f2011-05-05 00:08:10510 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07511 // socket.get() should be NULL iff result != OK
512 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34513 delete job;
514 have_result_ = true;
515 if (waiting_for_result_)
516 MessageLoop::current()->Quit();
517 }
518
519 int WaitForResult() {
520 DCHECK(!waiting_for_result_);
521 while (!have_result_) {
522 waiting_for_result_ = true;
523 MessageLoop::current()->Run();
524 waiting_for_result_ = false;
525 }
526 have_result_ = false; // auto-reset for next callback
527 return result_;
528 }
529
530 private:
531 bool have_result_;
532 bool waiting_for_result_;
533 int result_;
534};
535
[email protected]2431756e2010-09-29 20:26:13536class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09537 protected:
[email protected]b89f7e42010-05-20 20:37:00538 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21539 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54540 histograms_("ClientSocketPoolTest") {
541 connect_backup_jobs_enabled_ =
542 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
543 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
544 }
[email protected]2431756e2010-09-29 20:26:13545
[email protected]636b8252011-04-08 19:56:54546 virtual ~ClientSocketPoolBaseTest() {
547 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
548 connect_backup_jobs_enabled_);
549 }
[email protected]c9d6a1d2009-07-14 16:15:20550
[email protected]211d21722009-07-22 15:48:53551 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16552 CreatePoolWithIdleTimeouts(
553 max_sockets,
554 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00555 base::TimeDelta::FromSeconds(
556 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16557 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
558 }
559
560 void CreatePoolWithIdleTimeouts(
561 int max_sockets, int max_sockets_per_group,
562 base::TimeDelta unused_idle_socket_timeout,
563 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20564 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04565 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13566 pool_.reset(new TestClientSocketPool(max_sockets,
567 max_sockets_per_group,
568 &histograms_,
569 unused_idle_socket_timeout,
570 used_idle_socket_timeout,
571 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20572 }
[email protected]f6d1d6eb2009-06-24 20:16:09573
[email protected]ac790b42009-12-02 04:31:31574 int StartRequest(const std::string& group_name,
575 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13576 return test_base_.StartRequestUsingPool<
577 TestClientSocketPool, TestSocketParams>(
578 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09579 }
580
[email protected]2431756e2010-09-29 20:26:13581 int GetOrderOfRequest(size_t index) const {
582 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09583 }
584
[email protected]2431756e2010-09-29 20:26:13585 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
586 return test_base_.ReleaseOneConnection(keep_alive);
587 }
588
589 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
590 test_base_.ReleaseAllConnections(keep_alive);
591 }
592
593 TestSocketRequest* request(int i) { return test_base_.request(i); }
594 size_t requests_size() const { return test_base_.requests_size(); }
595 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
596 size_t completion_count() const { return test_base_.completion_count(); }
597
[email protected]636b8252011-04-08 19:56:54598 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09599 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04600 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21601 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13602 ClientSocketPoolHistograms histograms_;
603 scoped_ptr<TestClientSocketPool> pool_;
604 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09605};
606
[email protected]974ebd62009-08-03 23:14:34607// Even though a timeout is specified, it doesn't time out on a synchronous
608// completion.
609TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
610 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06611 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49612 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03613 &ignored, NULL, kDefaultPriority,
614 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20615 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34616 scoped_ptr<TestConnectJob> job(
617 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12618 "a",
[email protected]974ebd62009-08-03 23:14:34619 request,
620 base::TimeDelta::FromMicroseconds(1),
621 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30622 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17623 NULL));
[email protected]974ebd62009-08-03 23:14:34624 EXPECT_EQ(OK, job->Connect());
625}
626
627TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
628 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06629 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17630 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53631
[email protected]d80a4322009-08-14 07:07:49632 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03633 &ignored, NULL, kDefaultPriority,
634 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20635 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34636 // Deleted by TestConnectJobDelegate.
637 TestConnectJob* job =
638 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12639 "a",
[email protected]974ebd62009-08-03 23:14:34640 request,
641 base::TimeDelta::FromMicroseconds(1),
642 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30643 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17644 &log);
[email protected]974ebd62009-08-03 23:14:34645 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08646 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34647 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30648
[email protected]b2fcd0e2010-12-01 15:19:40649 net::CapturingNetLog::EntryList entries;
650 log.GetEntries(&entries);
651
652 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46653 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40654 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17655 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40656 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46657 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40658 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17659 NetLog::PHASE_NONE));
660 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40661 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53662 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46663 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40664 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17665 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40666 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34667}
668
[email protected]5fc08e32009-07-15 17:09:57669TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53670 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20671
[email protected]f6d1d6eb2009-06-24 20:16:09672 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06673 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53674 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
675
[email protected]2431756e2010-09-29 20:26:13676 EXPECT_EQ(OK,
677 handle.Init("a",
678 params_,
679 kDefaultPriority,
680 &callback,
681 pool_.get(),
682 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09683 EXPECT_TRUE(handle.is_initialized());
684 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09685 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30686
[email protected]b2fcd0e2010-12-01 15:19:40687 net::CapturingNetLog::EntryList entries;
688 log.GetEntries(&entries);
689
690 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46691 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40692 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53693 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40694 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17695 NetLog::PHASE_NONE));
696 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40697 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53698 NetLog::PHASE_NONE));
699 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40700 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09701}
702
[email protected]ab838892009-06-30 18:49:05703TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53704 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20705
[email protected]ab838892009-06-30 18:49:05706 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53707 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
708
[email protected]2431756e2010-09-29 20:26:13709 ClientSocketHandle handle;
710 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18711 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13712 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43713 HttpResponseInfo info;
714 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13715 handle.set_ssl_error_response_info(info);
716 EXPECT_EQ(ERR_CONNECTION_FAILED,
717 handle.Init("a",
718 params_,
719 kDefaultPriority,
720 &callback,
721 pool_.get(),
722 log.bound()));
723 EXPECT_FALSE(handle.socket());
724 EXPECT_FALSE(handle.is_ssl_error());
725 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30726
[email protected]b2fcd0e2010-12-01 15:19:40727 net::CapturingNetLog::EntryList entries;
728 log.GetEntries(&entries);
729
730 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27731 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40732 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17733 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40734 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17735 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02736 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40737 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09738}
739
[email protected]211d21722009-07-22 15:48:53740TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
741 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
742
[email protected]9e743cd2010-03-16 07:03:53743 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30744
[email protected]211d21722009-07-22 15:48:53745 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
746 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
747 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
748 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
749
[email protected]2431756e2010-09-29 20:26:13750 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53751 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13752 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53753
754 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
755 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
756 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
757
[email protected]2431756e2010-09-29 20:26:13758 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53759
[email protected]2431756e2010-09-29 20:26:13760 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53761 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13762 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53763
764 EXPECT_EQ(1, GetOrderOfRequest(1));
765 EXPECT_EQ(2, GetOrderOfRequest(2));
766 EXPECT_EQ(3, GetOrderOfRequest(3));
767 EXPECT_EQ(4, GetOrderOfRequest(4));
768 EXPECT_EQ(5, GetOrderOfRequest(5));
769 EXPECT_EQ(6, GetOrderOfRequest(6));
770 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17771
772 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13773 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53774}
775
776TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
777 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
778
[email protected]9e743cd2010-03-16 07:03:53779 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30780
[email protected]211d21722009-07-22 15:48:53781 // Reach all limits: max total sockets, and max sockets per group.
782 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
783 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
784 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
785 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
786
[email protected]2431756e2010-09-29 20:26:13787 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53788 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13789 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53790
791 // Now create a new group and verify that we don't starve it.
792 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
793
[email protected]2431756e2010-09-29 20:26:13794 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53795
[email protected]2431756e2010-09-29 20:26:13796 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53797 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13798 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53799
800 EXPECT_EQ(1, GetOrderOfRequest(1));
801 EXPECT_EQ(2, GetOrderOfRequest(2));
802 EXPECT_EQ(3, GetOrderOfRequest(3));
803 EXPECT_EQ(4, GetOrderOfRequest(4));
804 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17805
806 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13807 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53808}
809
810TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
811 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
812
[email protected]ac790b42009-12-02 04:31:31813 EXPECT_EQ(OK, StartRequest("b", LOWEST));
814 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
815 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
816 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53817
[email protected]2431756e2010-09-29 20:26:13818 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53819 client_socket_factory_.allocation_count());
820
[email protected]ac790b42009-12-02 04:31:31821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
822 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
823 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53824
[email protected]2431756e2010-09-29 20:26:13825 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53826
[email protected]2431756e2010-09-29 20:26:13827 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53828
829 // First 4 requests don't have to wait, and finish in order.
830 EXPECT_EQ(1, GetOrderOfRequest(1));
831 EXPECT_EQ(2, GetOrderOfRequest(2));
832 EXPECT_EQ(3, GetOrderOfRequest(3));
833 EXPECT_EQ(4, GetOrderOfRequest(4));
834
[email protected]ac790b42009-12-02 04:31:31835 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
836 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53837 EXPECT_EQ(7, GetOrderOfRequest(5));
838 EXPECT_EQ(6, GetOrderOfRequest(6));
839 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17840
841 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13842 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53843}
844
845TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
846 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
847
[email protected]ac790b42009-12-02 04:31:31848 EXPECT_EQ(OK, StartRequest("a", LOWEST));
849 EXPECT_EQ(OK, StartRequest("a", LOW));
850 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
851 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53852
[email protected]2431756e2010-09-29 20:26:13853 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53854 client_socket_factory_.allocation_count());
855
[email protected]ac790b42009-12-02 04:31:31856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
857 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
858 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53859
[email protected]2431756e2010-09-29 20:26:13860 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53861
[email protected]2431756e2010-09-29 20:26:13862 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53863 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13864 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53865
866 // First 4 requests don't have to wait, and finish in order.
867 EXPECT_EQ(1, GetOrderOfRequest(1));
868 EXPECT_EQ(2, GetOrderOfRequest(2));
869 EXPECT_EQ(3, GetOrderOfRequest(3));
870 EXPECT_EQ(4, GetOrderOfRequest(4));
871
872 // Request ("b", 7) has the highest priority, but we can't make new socket for
873 // group "b", because it has reached the per-group limit. Then we make
874 // socket for ("c", 6), because it has higher priority than ("a", 4),
875 // and we still can't make a socket for group "b".
876 EXPECT_EQ(5, GetOrderOfRequest(5));
877 EXPECT_EQ(6, GetOrderOfRequest(6));
878 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17879
880 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13881 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53882}
883
884// Make sure that we count connecting sockets against the total limit.
885TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
887
888 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
889 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
890 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
891
892 // Create one asynchronous request.
893 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
894 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
895
[email protected]6b175382009-10-13 06:47:47896 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
897 // actually become pending until 2ms after they have been created. In order
898 // to flush all tasks, we need to wait so that we know there are no
899 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08900 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47901 MessageLoop::current()->RunAllPending();
902
[email protected]211d21722009-07-22 15:48:53903 // The next synchronous request should wait for its turn.
904 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
905 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
906
[email protected]2431756e2010-09-29 20:26:13907 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53908
[email protected]2431756e2010-09-29 20:26:13909 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53910 client_socket_factory_.allocation_count());
911
912 EXPECT_EQ(1, GetOrderOfRequest(1));
913 EXPECT_EQ(2, GetOrderOfRequest(2));
914 EXPECT_EQ(3, GetOrderOfRequest(3));
915 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17916 EXPECT_EQ(5, GetOrderOfRequest(5));
917
918 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13919 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53920}
921
[email protected]6427fe22010-04-16 22:27:41922TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
923 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
924 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
925
926 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
927 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
928 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
929 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
930
931 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
932
933 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
934
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
937
938 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
939
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41941 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13942 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41943 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13944 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
945 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41946 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
947}
948
[email protected]d7027bb2010-05-10 18:58:54949TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
950 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
951 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
952
953 ClientSocketHandle handle;
954 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13955 EXPECT_EQ(ERR_IO_PENDING,
956 handle.Init("a",
957 params_,
958 kDefaultPriority,
959 &callback,
960 pool_.get(),
961 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54962
963 ClientSocketHandle handles[4];
964 for (size_t i = 0; i < arraysize(handles); ++i) {
965 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(ERR_IO_PENDING,
967 handles[i].Init("b",
968 params_,
969 kDefaultPriority,
970 &callback,
971 pool_.get(),
972 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54973 }
974
975 // One will be stalled, cancel all the handles now.
976 // This should hit the OnAvailableSocketSlot() code where we previously had
977 // stalled groups, but no longer have any.
978 for (size_t i = 0; i < arraysize(handles); ++i)
979 handles[i].Reset();
980}
981
[email protected]eb5a99382010-07-11 03:18:26982TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54983 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
984 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
985
[email protected]eb5a99382010-07-11 03:18:26986 {
987 ClientSocketHandle handles[kDefaultMaxSockets];
988 TestCompletionCallback callbacks[kDefaultMaxSockets];
989 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13990 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
991 params_,
[email protected]e83326f2010-07-31 17:29:25992 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13993 &callbacks[i],
994 pool_.get(),
995 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26996 }
997
998 // Force a stalled group.
999 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541000 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1002 params_,
1003 kDefaultPriority,
1004 &callback,
1005 pool_.get(),
1006 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261007
1008 // Cancel the stalled request.
1009 stalled_handle.Reset();
1010
1011 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1012 EXPECT_EQ(0, pool_->IdleSocketCount());
1013
1014 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541015 }
1016
[email protected]43a21b82010-06-10 21:30:541017 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1018 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261019}
[email protected]43a21b82010-06-10 21:30:541020
[email protected]eb5a99382010-07-11 03:18:261021TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1022 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1023 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1024
1025 {
1026 ClientSocketHandle handles[kDefaultMaxSockets];
1027 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1028 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131029 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1030 params_,
1031 kDefaultPriority,
1032 &callback,
1033 pool_.get(),
1034 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261035 }
1036
1037 // Force a stalled group.
1038 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1039 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541040 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131041 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1042 params_,
1043 kDefaultPriority,
1044 &callback,
1045 pool_.get(),
1046 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261047
1048 // Since it is stalled, it should have no connect jobs.
1049 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1050
1051 // Cancel the stalled request.
1052 handles[0].Reset();
1053
[email protected]eb5a99382010-07-11 03:18:261054 // Now we should have a connect job.
1055 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1056
1057 // The stalled socket should connect.
1058 EXPECT_EQ(OK, callback.WaitForResult());
1059
1060 EXPECT_EQ(kDefaultMaxSockets + 1,
1061 client_socket_factory_.allocation_count());
1062 EXPECT_EQ(0, pool_->IdleSocketCount());
1063 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1064
1065 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541066 }
1067
[email protected]eb5a99382010-07-11 03:18:261068 EXPECT_EQ(1, pool_->IdleSocketCount());
1069}
[email protected]43a21b82010-06-10 21:30:541070
[email protected]eb5a99382010-07-11 03:18:261071TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1072 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1073 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541074
[email protected]eb5a99382010-07-11 03:18:261075 ClientSocketHandle stalled_handle;
1076 TestCompletionCallback callback;
1077 {
1078 ClientSocketHandle handles[kDefaultMaxSockets];
1079 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1080 TestCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401081 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1082 "Take 2: %d", i),
1083 params_,
1084 kDefaultPriority,
1085 &callback,
1086 pool_.get(),
1087 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261088 }
1089
1090 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1091 EXPECT_EQ(0, pool_->IdleSocketCount());
1092
1093 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131094 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1095 params_,
1096 kDefaultPriority,
1097 &callback,
1098 pool_.get(),
1099 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261100
1101 // Dropping out of scope will close all handles and return them to idle.
1102 }
[email protected]43a21b82010-06-10 21:30:541103
1104 // But if we wait for it, the released idle sockets will be closed in
1105 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101106 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261107
1108 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1109 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541110}
1111
1112// Regression test for http://crbug.com/40952.
1113TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1114 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221115 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541116 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1117
1118 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1119 ClientSocketHandle handle;
1120 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131121 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1122 params_,
1123 kDefaultPriority,
1124 &callback,
1125 pool_.get(),
1126 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541127 }
1128
1129 // Flush all the DoReleaseSocket tasks.
1130 MessageLoop::current()->RunAllPending();
1131
1132 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1133 // reuse a socket.
1134 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1135 ClientSocketHandle handle;
1136 TestCompletionCallback callback;
1137
1138 // "0" is special here, since it should be the first entry in the sorted map,
1139 // which is the one which we would close an idle socket for. We shouldn't
1140 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131141 EXPECT_EQ(OK, handle.Init("0",
1142 params_,
1143 kDefaultPriority,
1144 &callback,
1145 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211146 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541147
1148 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1149 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1150}
1151
[email protected]ab838892009-06-30 18:49:051152TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531153 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091154
[email protected]c9d6a1d2009-07-14 16:15:201155 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1156 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031157 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311158 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1159 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1160 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1161 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1162 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091163
[email protected]2431756e2010-09-29 20:26:131164 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091165
[email protected]c9d6a1d2009-07-14 16:15:201166 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1167 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131168 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1169 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091170
[email protected]c9d6a1d2009-07-14 16:15:201171 EXPECT_EQ(1, GetOrderOfRequest(1));
1172 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031173 EXPECT_EQ(8, GetOrderOfRequest(3));
1174 EXPECT_EQ(6, GetOrderOfRequest(4));
1175 EXPECT_EQ(4, GetOrderOfRequest(5));
1176 EXPECT_EQ(3, GetOrderOfRequest(6));
1177 EXPECT_EQ(5, GetOrderOfRequest(7));
1178 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171179
1180 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131181 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091182}
1183
[email protected]ab838892009-06-30 18:49:051184TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531185 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091186
[email protected]c9d6a1d2009-07-14 16:15:201187 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1188 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311189 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1190 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1191 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1192 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1193 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091194
[email protected]2431756e2010-09-29 20:26:131195 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091196
[email protected]2431756e2010-09-29 20:26:131197 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1198 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201199
[email protected]2431756e2010-09-29 20:26:131200 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201201 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131202 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1203 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091204}
1205
1206// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051207// The pending connect job will be cancelled and should not call back into
1208// ClientSocketPoolBase.
1209TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531210 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201211
[email protected]ab838892009-06-30 18:49:051212 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131213 ClientSocketHandle handle;
1214 TestCompletionCallback callback;
1215 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1216 params_,
1217 kDefaultPriority,
1218 &callback,
1219 pool_.get(),
1220 BoundNetLog()));
1221 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091222}
1223
[email protected]ab838892009-06-30 18:49:051224TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531225 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201226
[email protected]ab838892009-06-30 18:49:051227 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061228 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091229 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091230
[email protected]2431756e2010-09-29 20:26:131231 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1232 params_,
1233 kDefaultPriority,
1234 &callback,
1235 pool_.get(),
1236 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091237
1238 handle.Reset();
1239
1240 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131241 EXPECT_EQ(ERR_IO_PENDING,
1242 handle.Init("a",
1243 params_,
1244 kDefaultPriority,
1245 &callback2,
1246 pool_.get(),
1247 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091248
1249 EXPECT_EQ(OK, callback2.WaitForResult());
1250 EXPECT_FALSE(callback.have_result());
1251
1252 handle.Reset();
1253}
1254
[email protected]ab838892009-06-30 18:49:051255TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531256 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091257
[email protected]c9d6a1d2009-07-14 16:15:201258 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1259 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311260 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1261 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1262 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1263 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1264 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091265
1266 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201267 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131268 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1269 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091270
[email protected]2431756e2010-09-29 20:26:131271 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091272
[email protected]c9d6a1d2009-07-14 16:15:201273 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1274 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131275 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1276 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091277
[email protected]c9d6a1d2009-07-14 16:15:201278 EXPECT_EQ(1, GetOrderOfRequest(1));
1279 EXPECT_EQ(2, GetOrderOfRequest(2));
1280 EXPECT_EQ(5, GetOrderOfRequest(3));
1281 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131282 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1283 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201284 EXPECT_EQ(4, GetOrderOfRequest(6));
1285 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171286
1287 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131288 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091289}
1290
1291class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1292 public:
[email protected]2ab05b52009-07-01 23:57:581293 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241294 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581295 TestConnectJobFactory* test_connect_job_factory,
1296 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091297 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061298 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581299 within_callback_(false),
1300 test_connect_job_factory_(test_connect_job_factory),
1301 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091302
1303 virtual void RunWithParams(const Tuple1<int>& params) {
1304 callback_.RunWithParams(params);
1305 ASSERT_EQ(OK, params.a);
1306
1307 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581308 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111309
1310 // Don't allow reuse of the socket. Disconnect it and then release it and
1311 // run through the MessageLoop once to get it completely released.
1312 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091313 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111314 {
1315 MessageLoop::ScopedNestableTaskAllower nestable(
1316 MessageLoop::current());
1317 MessageLoop::current()->RunAllPending();
1318 }
[email protected]f6d1d6eb2009-06-24 20:16:091319 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471320 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271321 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131322 int rv = handle_->Init("a",
1323 params,
1324 kDefaultPriority,
1325 &next_job_callback,
1326 pool_,
1327 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581328 switch (next_job_type_) {
1329 case TestConnectJob::kMockJob:
1330 EXPECT_EQ(OK, rv);
1331 break;
1332 case TestConnectJob::kMockPendingJob:
1333 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471334
1335 // For pending jobs, wait for new socket to be created. This makes
1336 // sure there are no more pending operations nor any unclosed sockets
1337 // when the test finishes.
1338 // We need to give it a little bit of time to run, so that all the
1339 // operations that happen on timers (e.g. cleanup of idle
1340 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111341 {
1342 MessageLoop::ScopedNestableTaskAllower nestable(
1343 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081344 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111345 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1346 }
[email protected]2ab05b52009-07-01 23:57:581347 break;
1348 default:
1349 FAIL() << "Unexpected job type: " << next_job_type_;
1350 break;
1351 }
[email protected]f6d1d6eb2009-06-24 20:16:091352 }
1353 }
1354
1355 int WaitForResult() {
1356 return callback_.WaitForResult();
1357 }
1358
1359 private:
1360 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131361 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091362 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581363 TestConnectJobFactory* const test_connect_job_factory_;
1364 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091365 TestCompletionCallback callback_;
1366};
1367
[email protected]2ab05b52009-07-01 23:57:581368TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531369 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201370
[email protected]0b7648c2009-07-06 20:14:011371 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061372 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581373 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061374 &handle, pool_.get(), connect_job_factory_,
1375 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131376 int rv = handle.Init("a",
1377 params_,
1378 kDefaultPriority,
1379 &callback,
1380 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211381 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091382 ASSERT_EQ(ERR_IO_PENDING, rv);
1383
1384 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581385}
[email protected]f6d1d6eb2009-06-24 20:16:091386
[email protected]2ab05b52009-07-01 23:57:581387TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531388 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201389
[email protected]0b7648c2009-07-06 20:14:011390 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061391 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581392 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061393 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131394 int rv = handle.Init("a",
1395 params_,
1396 kDefaultPriority,
1397 &callback,
1398 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211399 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581400 ASSERT_EQ(ERR_IO_PENDING, rv);
1401
1402 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091403}
1404
1405// Make sure that pending requests get serviced after active requests get
1406// cancelled.
[email protected]ab838892009-06-30 18:49:051407TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531408 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201409
[email protected]0b7648c2009-07-06 20:14:011410 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091411
[email protected]c9d6a1d2009-07-14 16:15:201412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1414 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1415 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1416 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1417 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1418 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091419
[email protected]c9d6a1d2009-07-14 16:15:201420 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1421 // Let's cancel them.
1422 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131423 ASSERT_FALSE(request(i)->handle()->is_initialized());
1424 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091425 }
1426
[email protected]f6d1d6eb2009-06-24 20:16:091427 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131428 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1429 EXPECT_EQ(OK, request(i)->WaitForResult());
1430 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091431 }
1432
[email protected]2431756e2010-09-29 20:26:131433 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1434 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091435}
1436
1437// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051438TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531439 const size_t kMaxSockets = 5;
1440 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201441
[email protected]0b7648c2009-07-06 20:14:011442 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091443
[email protected]211d21722009-07-22 15:48:531444 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1445 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091446
1447 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531448 for (size_t i = 0; i < kNumberOfRequests; ++i)
1449 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091450
[email protected]211d21722009-07-22 15:48:531451 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131452 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091453}
1454
[email protected]5fc08e32009-07-15 17:09:571455TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531456 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571457
1458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1459
[email protected]2431756e2010-09-29 20:26:131460 ClientSocketHandle handle;
1461 TestCompletionCallback callback;
1462 int rv = handle.Init("a",
1463 params_,
1464 kDefaultPriority,
1465 &callback,
1466 pool_.get(),
1467 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571468 EXPECT_EQ(ERR_IO_PENDING, rv);
1469
1470 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131471 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571472
[email protected]2431756e2010-09-29 20:26:131473 rv = handle.Init("a",
1474 params_,
1475 kDefaultPriority,
1476 &callback,
1477 pool_.get(),
1478 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571479 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131480 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571481
[email protected]2431756e2010-09-29 20:26:131482 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571483 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1484}
1485
[email protected]2b7523d2009-07-29 20:29:231486// Regression test for http://crbug.com/17985.
1487TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1488 const int kMaxSockets = 3;
1489 const int kMaxSocketsPerGroup = 2;
1490 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1491
[email protected]ac790b42009-12-02 04:31:311492 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231493
1494 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1495 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1496
1497 // This is going to be a pending request in an otherwise empty group.
1498 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1499
1500 // Reach the maximum socket limit.
1501 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1502
1503 // Create a stalled group with high priorities.
1504 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1505 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231506
[email protected]eb5a99382010-07-11 03:18:261507 // Release the first two sockets from "a". Because this is a keepalive,
1508 // the first release will unblock the pending request for "a". The
1509 // second release will unblock a request for "c", becaue it is the next
1510 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131511 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1512 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231513
1514 // Closing idle sockets should not get us into trouble, but in the bug
1515 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411516 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541517 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261518
1519 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231520}
1521
[email protected]4d3b05d2010-01-27 21:27:291522TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531523 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571524
1525 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131526 ClientSocketHandle handle;
1527 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531528 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131529 int rv = handle.Init("a",
1530 params_,
1531 LOWEST,
1532 &callback,
1533 pool_.get(),
1534 log.bound());
[email protected]5fc08e32009-07-15 17:09:571535 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131536 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1537 EXPECT_EQ(OK, callback.WaitForResult());
1538 EXPECT_TRUE(handle.is_initialized());
1539 EXPECT_TRUE(handle.socket());
1540 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301541
[email protected]b2fcd0e2010-12-01 15:19:401542 net::CapturingNetLog::EntryList entries;
1543 log.GetEntries(&entries);
1544
1545 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461546 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401547 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171548 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401549 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171550 NetLog::PHASE_NONE));
1551 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401552 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171553 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461554 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401555 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571556}
1557
[email protected]4d3b05d2010-01-27 21:27:291558TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571559 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531560 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571561
1562 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131563 ClientSocketHandle handle;
1564 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531565 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181566 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131567 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431568 HttpResponseInfo info;
1569 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131570 handle.set_ssl_error_response_info(info);
1571 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1572 params_,
1573 kDefaultPriority,
1574 &callback,
1575 pool_.get(),
1576 log.bound()));
1577 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1578 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1579 EXPECT_FALSE(handle.is_ssl_error());
1580 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301581
[email protected]b2fcd0e2010-12-01 15:19:401582 net::CapturingNetLog::EntryList entries;
1583 log.GetEntries(&entries);
1584
1585 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461586 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401587 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171588 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401589 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171590 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321591 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401592 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571593}
1594
[email protected]4d3b05d2010-01-27 21:27:291595TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101596 // TODO(eroman): Add back the log expectations! Removed them because the
1597 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531598 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571599
1600 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131601 ClientSocketHandle handle;
1602 TestCompletionCallback callback;
1603 ClientSocketHandle handle2;
1604 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571605
[email protected]2431756e2010-09-29 20:26:131606 EXPECT_EQ(ERR_IO_PENDING,
1607 handle.Init("a",
1608 params_,
1609 kDefaultPriority,
1610 &callback,
1611 pool_.get(),
1612 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531613 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131614 EXPECT_EQ(ERR_IO_PENDING,
1615 handle2.Init("a",
1616 params_,
1617 kDefaultPriority,
1618 &callback2,
1619 pool_.get(),
1620 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571621
[email protected]2431756e2010-09-29 20:26:131622 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571623
[email protected]fd7b7c92009-08-20 19:38:301624
1625 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301626
[email protected]2431756e2010-09-29 20:26:131627 EXPECT_EQ(OK, callback2.WaitForResult());
1628 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301629
1630 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531631 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571632}
1633
[email protected]4d3b05d2010-01-27 21:27:291634TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341635 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1636
[email protected]17a0c6c2009-08-04 00:07:041637 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1638
[email protected]ac790b42009-12-02 04:31:311639 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1640 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1641 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1642 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341643
1644 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131645 (*requests())[2]->handle()->Reset();
1646 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341647 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1648
[email protected]2431756e2010-09-29 20:26:131649 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341650 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1651
[email protected]2431756e2010-09-29 20:26:131652 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261653 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341654}
1655
[email protected]5fc08e32009-07-15 17:09:571656// When requests and ConnectJobs are not coupled, the request will get serviced
1657// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291658TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531659 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571660
1661 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321662 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571663
[email protected]2431756e2010-09-29 20:26:131664 std::vector<TestSocketRequest*> request_order;
1665 size_t completion_count; // unused
1666 TestSocketRequest req1(&request_order, &completion_count);
1667 int rv = req1.handle()->Init("a",
1668 params_,
1669 kDefaultPriority,
1670 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211671 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571672 EXPECT_EQ(ERR_IO_PENDING, rv);
1673 EXPECT_EQ(OK, req1.WaitForResult());
1674
1675 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1676 // without a job.
1677 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1678
[email protected]2431756e2010-09-29 20:26:131679 TestSocketRequest req2(&request_order, &completion_count);
1680 rv = req2.handle()->Init("a",
1681 params_,
1682 kDefaultPriority,
1683 &req2,
1684 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211685 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571686 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131687 TestSocketRequest req3(&request_order, &completion_count);
1688 rv = req3.handle()->Init("a",
1689 params_,
1690 kDefaultPriority,
1691 &req3,
1692 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211693 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571694 EXPECT_EQ(ERR_IO_PENDING, rv);
1695
1696 // Both Requests 2 and 3 are pending. We release socket 1 which should
1697 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331698 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261699 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331700 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571701 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331702 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571703
1704 // Signal job 2, which should service request 3.
1705
1706 client_socket_factory_.SignalJobs();
1707 EXPECT_EQ(OK, req3.WaitForResult());
1708
[email protected]2431756e2010-09-29 20:26:131709 ASSERT_EQ(3U, request_order.size());
1710 EXPECT_EQ(&req1, request_order[0]);
1711 EXPECT_EQ(&req2, request_order[1]);
1712 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571713 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1714}
1715
1716// The requests are not coupled to the jobs. So, the requests should finish in
1717// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291718TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531719 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571720 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321721 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571722
[email protected]2431756e2010-09-29 20:26:131723 std::vector<TestSocketRequest*> request_order;
1724 size_t completion_count; // unused
1725 TestSocketRequest req1(&request_order, &completion_count);
1726 int rv = req1.handle()->Init("a",
1727 params_,
1728 kDefaultPriority,
1729 &req1,
1730 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211731 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571732 EXPECT_EQ(ERR_IO_PENDING, rv);
1733
[email protected]2431756e2010-09-29 20:26:131734 TestSocketRequest req2(&request_order, &completion_count);
1735 rv = req2.handle()->Init("a",
1736 params_,
1737 kDefaultPriority,
1738 &req2,
1739 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211740 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571741 EXPECT_EQ(ERR_IO_PENDING, rv);
1742
1743 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321744 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571745
[email protected]2431756e2010-09-29 20:26:131746 TestSocketRequest req3(&request_order, &completion_count);
1747 rv = req3.handle()->Init("a",
1748 params_,
1749 kDefaultPriority,
1750 &req3,
1751 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211752 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571753 EXPECT_EQ(ERR_IO_PENDING, rv);
1754
1755 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1756 EXPECT_EQ(OK, req2.WaitForResult());
1757 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1758
[email protected]2431756e2010-09-29 20:26:131759 ASSERT_EQ(3U, request_order.size());
1760 EXPECT_EQ(&req1, request_order[0]);
1761 EXPECT_EQ(&req2, request_order[1]);
1762 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571763}
1764
[email protected]e6ec67b2010-06-16 00:12:461765TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571767 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321768 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571769
[email protected]2431756e2010-09-29 20:26:131770 ClientSocketHandle handle;
1771 TestCompletionCallback callback;
1772 int rv = handle.Init("a",
1773 params_,
1774 kDefaultPriority,
1775 &callback,
1776 pool_.get(),
1777 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571778 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131779 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571780
1781 MessageLoop::current()->RunAllPending();
1782
[email protected]2431756e2010-09-29 20:26:131783 ClientSocketHandle handle2;
1784 TestCompletionCallback callback2;
1785 rv = handle2.Init("a",
1786 params_,
1787 kDefaultPriority,
1788 &callback2, pool_.get(),
1789 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571790 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131791 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1792 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571793}
1794
[email protected]e772db3f2010-07-12 18:11:131795TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1796 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1797 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1798
[email protected]2431756e2010-09-29 20:26:131799 ClientSocketHandle handle;
1800 TestCompletionCallback callback;
1801 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1802 params_,
1803 kDefaultPriority,
1804 &callback, pool_.get(),
1805 BoundNetLog()));
1806 EXPECT_TRUE(handle.is_initialized());
1807 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131808}
1809
1810TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1811 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1812
1813 connect_job_factory_->set_job_type(
1814 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131815 ClientSocketHandle handle;
1816 TestCompletionCallback callback;
1817 EXPECT_EQ(ERR_IO_PENDING,
1818 handle.Init("a",
1819 params_,
1820 kDefaultPriority,
1821 &callback,
1822 pool_.get(),
1823 BoundNetLog()));
1824 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1825 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1826 EXPECT_TRUE(handle.is_initialized());
1827 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131828}
1829
[email protected]e60e47a2010-07-14 03:37:181830TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1831 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1832 connect_job_factory_->set_job_type(
1833 TestConnectJob::kMockAdditionalErrorStateJob);
1834
[email protected]2431756e2010-09-29 20:26:131835 ClientSocketHandle handle;
1836 TestCompletionCallback callback;
1837 EXPECT_EQ(ERR_CONNECTION_FAILED,
1838 handle.Init("a",
1839 params_,
1840 kDefaultPriority,
1841 &callback,
1842 pool_.get(),
1843 BoundNetLog()));
1844 EXPECT_FALSE(handle.is_initialized());
1845 EXPECT_FALSE(handle.socket());
1846 EXPECT_TRUE(handle.is_ssl_error());
1847 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181848}
1849
1850TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1851 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1852
1853 connect_job_factory_->set_job_type(
1854 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131855 ClientSocketHandle handle;
1856 TestCompletionCallback callback;
1857 EXPECT_EQ(ERR_IO_PENDING,
1858 handle.Init("a",
1859 params_,
1860 kDefaultPriority,
1861 &callback,
1862 pool_.get(),
1863 BoundNetLog()));
1864 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1865 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1866 EXPECT_FALSE(handle.is_initialized());
1867 EXPECT_FALSE(handle.socket());
1868 EXPECT_TRUE(handle.is_ssl_error());
1869 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181870}
1871
[email protected]4d3b05d2010-01-27 21:27:291872TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161873 CreatePoolWithIdleTimeouts(
1874 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1875 base::TimeDelta(), // Time out unused sockets immediately.
1876 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1877
1878 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1879
1880 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1881
[email protected]2431756e2010-09-29 20:26:131882 ClientSocketHandle handle;
1883 TestCompletionCallback callback;
1884 int rv = handle.Init("a",
1885 params_,
1886 LOWEST,
1887 &callback,
1888 pool_.get(),
1889 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161890 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131891 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161892
[email protected]2431756e2010-09-29 20:26:131893 ClientSocketHandle handle2;
1894 TestCompletionCallback callback2;
1895 rv = handle2.Init("a",
1896 params_,
1897 LOWEST,
1898 &callback2,
1899 pool_.get(),
1900 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161901 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131902 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161903
1904 // Cancel one of the requests. Wait for the other, which will get the first
1905 // job. Release the socket. Run the loop again to make sure the second
1906 // socket is sitting idle and the first one is released (since ReleaseSocket()
1907 // just posts a DoReleaseSocket() task).
1908
[email protected]2431756e2010-09-29 20:26:131909 handle.Reset();
1910 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011911 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131912 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1913 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471914
1915 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1916 // actually become pending until 2ms after they have been created. In order
1917 // to flush all tasks, we need to wait so that we know there are no
1918 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081919 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161920 MessageLoop::current()->RunAllPending();
1921
1922 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041923
[email protected]9bf28db2009-08-29 01:35:161924 // Invoke the idle socket cleanup check. Only one socket should be left, the
1925 // used socket. Request it to make sure that it's used.
1926
1927 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531928 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131929 rv = handle.Init("a",
1930 params_,
1931 LOWEST,
1932 &callback,
1933 pool_.get(),
1934 log.bound());
[email protected]9bf28db2009-08-29 01:35:161935 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131936 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:401937
1938 net::CapturingNetLog::EntryList entries;
1939 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:151940 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:401941 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161942}
1943
[email protected]2041cf342010-02-19 03:15:591944// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161945// because of multiple releasing disconnected sockets.
1946TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1947 CreatePoolWithIdleTimeouts(
1948 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1949 base::TimeDelta(), // Time out unused sockets immediately.
1950 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1951
1952 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1953
1954 // Startup 4 connect jobs. Two of them will be pending.
1955
[email protected]2431756e2010-09-29 20:26:131956 ClientSocketHandle handle;
1957 TestCompletionCallback callback;
1958 int rv = handle.Init("a",
1959 params_,
1960 LOWEST,
1961 &callback,
1962 pool_.get(),
1963 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161964 EXPECT_EQ(OK, rv);
1965
[email protected]2431756e2010-09-29 20:26:131966 ClientSocketHandle handle2;
1967 TestCompletionCallback callback2;
1968 rv = handle2.Init("a",
1969 params_,
1970 LOWEST,
1971 &callback2,
1972 pool_.get(),
1973 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161974 EXPECT_EQ(OK, rv);
1975
[email protected]2431756e2010-09-29 20:26:131976 ClientSocketHandle handle3;
1977 TestCompletionCallback callback3;
1978 rv = handle3.Init("a",
1979 params_,
1980 LOWEST,
1981 &callback3,
1982 pool_.get(),
1983 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161984 EXPECT_EQ(ERR_IO_PENDING, rv);
1985
[email protected]2431756e2010-09-29 20:26:131986 ClientSocketHandle handle4;
1987 TestCompletionCallback callback4;
1988 rv = handle4.Init("a",
1989 params_,
1990 LOWEST,
1991 &callback4,
1992 pool_.get(),
1993 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161994 EXPECT_EQ(ERR_IO_PENDING, rv);
1995
1996 // Release two disconnected sockets.
1997
[email protected]2431756e2010-09-29 20:26:131998 handle.socket()->Disconnect();
1999 handle.Reset();
2000 handle2.socket()->Disconnect();
2001 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162002
[email protected]2431756e2010-09-29 20:26:132003 EXPECT_EQ(OK, callback3.WaitForResult());
2004 EXPECT_FALSE(handle3.is_reused());
2005 EXPECT_EQ(OK, callback4.WaitForResult());
2006 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162007}
2008
[email protected]d7027bb2010-05-10 18:58:542009// Regression test for http://crbug.com/42267.
2010// When DoReleaseSocket() is processed for one socket, it is blocked because the
2011// other stalled groups all have releasing sockets, so no progress can be made.
2012TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2013 CreatePoolWithIdleTimeouts(
2014 4 /* socket limit */, 4 /* socket limit per group */,
2015 base::TimeDelta(), // Time out unused sockets immediately.
2016 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2017
2018 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2019
2020 // Max out the socket limit with 2 per group.
2021
[email protected]2431756e2010-09-29 20:26:132022 ClientSocketHandle handle_a[4];
2023 TestCompletionCallback callback_a[4];
2024 ClientSocketHandle handle_b[4];
2025 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542026
2027 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132028 EXPECT_EQ(OK, handle_a[i].Init("a",
2029 params_,
2030 LOWEST,
2031 &callback_a[i],
2032 pool_.get(),
2033 BoundNetLog()));
2034 EXPECT_EQ(OK, handle_b[i].Init("b",
2035 params_,
2036 LOWEST,
2037 &callback_b[i],
2038 pool_.get(),
2039 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542040 }
[email protected]b89f7e42010-05-20 20:37:002041
[email protected]d7027bb2010-05-10 18:58:542042 // Make 4 pending requests, 2 per group.
2043
2044 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132045 EXPECT_EQ(ERR_IO_PENDING,
2046 handle_a[i].Init("a",
2047 params_,
2048 LOWEST,
2049 &callback_a[i],
2050 pool_.get(),
2051 BoundNetLog()));
2052 EXPECT_EQ(ERR_IO_PENDING,
2053 handle_b[i].Init("b",
2054 params_,
2055 LOWEST,
2056 &callback_b[i],
2057 pool_.get(),
2058 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542059 }
2060
2061 // Release b's socket first. The order is important, because in
2062 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2063 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2064 // first, which has a releasing socket, so it refuses to start up another
2065 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132066 handle_b[0].socket()->Disconnect();
2067 handle_b[0].Reset();
2068 handle_a[0].socket()->Disconnect();
2069 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542070
2071 // Used to get stuck here.
2072 MessageLoop::current()->RunAllPending();
2073
[email protected]2431756e2010-09-29 20:26:132074 handle_b[1].socket()->Disconnect();
2075 handle_b[1].Reset();
2076 handle_a[1].socket()->Disconnect();
2077 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542078
2079 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132080 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2081 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542082 }
2083}
2084
[email protected]fd4fe0b2010-02-08 23:02:152085TEST_F(ClientSocketPoolBaseTest,
2086 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2087 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2088
2089 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2090
2091 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2092 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2093 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2094 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2095
[email protected]2431756e2010-09-29 20:26:132096 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2097 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2098 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152099
2100 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132101 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2102 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152103
[email protected]2431756e2010-09-29 20:26:132104 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2105 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2106 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152107
2108 EXPECT_EQ(1, GetOrderOfRequest(1));
2109 EXPECT_EQ(2, GetOrderOfRequest(2));
2110 EXPECT_EQ(3, GetOrderOfRequest(3));
2111 EXPECT_EQ(4, GetOrderOfRequest(4));
2112
2113 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132114 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152115}
2116
[email protected]4f1e4982010-03-02 18:31:042117class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2118 public:
[email protected]2431756e2010-09-29 20:26:132119 TestReleasingSocketRequest(TestClientSocketPool* pool,
2120 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182121 bool reset_releasing_handle)
2122 : pool_(pool),
2123 expected_result_(expected_result),
2124 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042125
2126 ClientSocketHandle* handle() { return &handle_; }
2127
2128 int WaitForResult() {
2129 return callback_.WaitForResult();
2130 }
2131
2132 virtual void RunWithParams(const Tuple1<int>& params) {
2133 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182134 if (reset_releasing_handle_)
2135 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272136 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132137 EXPECT_EQ(expected_result_, handle2_.Init("a",
2138 con_params,
2139 kDefaultPriority,
2140 &callback2_,
2141 pool_,
[email protected]e60e47a2010-07-14 03:37:182142 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042143 }
2144
2145 private:
[email protected]2431756e2010-09-29 20:26:132146 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182147 int expected_result_;
2148 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042149 ClientSocketHandle handle_;
2150 ClientSocketHandle handle2_;
2151 TestCompletionCallback callback_;
2152 TestCompletionCallback callback2_;
2153};
2154
[email protected]e60e47a2010-07-14 03:37:182155
2156TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2157 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2158
2159 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2160 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2161 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2162
[email protected]2431756e2010-09-29 20:26:132163 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182164 client_socket_factory_.allocation_count());
2165
2166 connect_job_factory_->set_job_type(
2167 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2168 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132169 EXPECT_EQ(ERR_IO_PENDING,
2170 req.handle()->Init("a",
2171 params_,
2172 kDefaultPriority,
2173 &req,
2174 pool_.get(),
2175 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182176 // The next job should complete synchronously
2177 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2178
2179 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2180 EXPECT_FALSE(req.handle()->is_initialized());
2181 EXPECT_FALSE(req.handle()->socket());
2182 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432183 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182184}
2185
[email protected]b6501d3d2010-06-03 23:53:342186// http://crbug.com/44724 regression test.
2187// We start releasing the pool when we flush on network change. When that
2188// happens, the only active references are in the ClientSocketHandles. When a
2189// ConnectJob completes and calls back into the last ClientSocketHandle, that
2190// callback can release the last reference and delete the pool. After the
2191// callback finishes, we go back to the stack frame within the now-deleted pool.
2192// Executing any code that refers to members of the now-deleted pool can cause
2193// crashes.
2194TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2195 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2196 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2197
2198 ClientSocketHandle handle;
2199 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132200 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2201 params_,
2202 kDefaultPriority,
2203 &callback,
2204 pool_.get(),
2205 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342206
[email protected]2431756e2010-09-29 20:26:132207 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342208
2209 // We'll call back into this now.
2210 callback.WaitForResult();
2211}
2212
[email protected]a7e38572010-06-07 18:22:242213TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2214 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2215 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2216
2217 ClientSocketHandle handle;
2218 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132219 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2220 params_,
2221 kDefaultPriority,
2222 &callback,
2223 pool_.get(),
2224 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242225 EXPECT_EQ(OK, callback.WaitForResult());
2226 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2227
2228 pool_->Flush();
2229
2230 handle.Reset();
2231 MessageLoop::current()->RunAllPending();
2232
[email protected]2431756e2010-09-29 20:26:132233 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2234 params_,
2235 kDefaultPriority,
2236 &callback,
2237 pool_.get(),
2238 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242239 EXPECT_EQ(OK, callback.WaitForResult());
2240 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2241}
2242
[email protected]06f92462010-08-31 19:24:142243class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2244 public:
2245 ConnectWithinCallback(
2246 const std::string& group_name,
2247 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132248 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142249 : group_name_(group_name), params_(params), pool_(pool) {}
2250
2251 ~ConnectWithinCallback() {}
2252
2253 virtual void RunWithParams(const Tuple1<int>& params) {
2254 callback_.RunWithParams(params);
2255 EXPECT_EQ(ERR_IO_PENDING,
2256 handle_.Init(group_name_,
2257 params_,
2258 kDefaultPriority,
2259 &nested_callback_,
2260 pool_,
2261 BoundNetLog()));
2262 }
2263
2264 int WaitForResult() {
2265 return callback_.WaitForResult();
2266 }
2267
2268 int WaitForNestedResult() {
2269 return nested_callback_.WaitForResult();
2270 }
2271
2272 private:
2273 const std::string group_name_;
2274 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132275 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142276 ClientSocketHandle handle_;
2277 TestCompletionCallback callback_;
2278 TestCompletionCallback nested_callback_;
2279};
2280
2281TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2282 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2283
2284 // First job will be waiting until it gets aborted.
2285 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2286
2287 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132288 ConnectWithinCallback callback("a", params_, pool_.get());
2289 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2290 params_,
2291 kDefaultPriority,
2292 &callback,
2293 pool_.get(),
2294 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142295
2296 // Second job will be started during the first callback, and will
2297 // asynchronously complete with OK.
2298 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2299 pool_->Flush();
2300 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2301 EXPECT_EQ(OK, callback.WaitForNestedResult());
2302}
2303
[email protected]25eea382010-07-10 23:55:262304// Cancel a pending socket request while we're at max sockets,
2305// and verify that the backup socket firing doesn't cause a crash.
2306TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2307 // Max 4 sockets globally, max 4 sockets per group.
2308 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222309 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262310
[email protected]4baaf9d2010-08-31 15:15:442311 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2312 // timer.
[email protected]25eea382010-07-10 23:55:262313 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2314 ClientSocketHandle handle;
2315 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132316 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2317 params_,
2318 kDefaultPriority,
2319 &callback,
2320 pool_.get(),
2321 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262322
2323 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2324 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2325 ClientSocketHandle handles[kDefaultMaxSockets];
2326 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2327 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132328 EXPECT_EQ(OK, handles[i].Init("bar",
2329 params_,
2330 kDefaultPriority,
2331 &callback,
2332 pool_.get(),
2333 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262334 }
2335
2336 MessageLoop::current()->RunAllPending();
2337
2338 // Cancel the pending request.
2339 handle.Reset();
2340
2341 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082342 base::PlatformThread::Sleep(
2343 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262344
2345 MessageLoop::current()->RunAllPending();
2346 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2347}
2348
[email protected]3f00be82010-09-27 19:50:022349TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442350 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2351 pool_->EnableConnectBackupJobs();
2352
2353 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2354 // timer.
2355 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2356 ClientSocketHandle handle;
2357 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132358 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2359 params_,
2360 kDefaultPriority,
2361 &callback,
2362 pool_.get(),
2363 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442364 ASSERT_TRUE(pool_->HasGroup("bar"));
2365 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2366
2367 // Cancel the socket request. This should cancel the backup timer. Wait for
2368 // the backup time to see if it indeed got canceled.
2369 handle.Reset();
2370 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082371 base::PlatformThread::Sleep(
2372 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442373 MessageLoop::current()->RunAllPending();
2374 ASSERT_TRUE(pool_->HasGroup("bar"));
2375 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2376}
2377
[email protected]3f00be82010-09-27 19:50:022378TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2379 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2380 pool_->EnableConnectBackupJobs();
2381
2382 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2383 // timer.
2384 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2385 ClientSocketHandle handle;
2386 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132387 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2388 params_,
2389 kDefaultPriority,
2390 &callback,
2391 pool_.get(),
2392 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022393 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2394 ClientSocketHandle handle2;
2395 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132396 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2397 params_,
2398 kDefaultPriority,
2399 &callback2,
2400 pool_.get(),
2401 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022402 ASSERT_TRUE(pool_->HasGroup("bar"));
2403 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2404
2405 // Cancel request 1 and then complete request 2. With the requests finished,
2406 // the backup timer should be cancelled.
2407 handle.Reset();
2408 EXPECT_EQ(OK, callback2.WaitForResult());
2409 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082410 base::PlatformThread::Sleep(
2411 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022412 MessageLoop::current()->RunAllPending();
2413}
2414
[email protected]eb5a99382010-07-11 03:18:262415// Test delayed socket binding for the case where we have two connects,
2416// and while one is waiting on a connect, the other frees up.
2417// The socket waiting on a connect should switch immediately to the freed
2418// up socket.
2419TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2421 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2422
2423 ClientSocketHandle handle1;
2424 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132425 EXPECT_EQ(ERR_IO_PENDING,
2426 handle1.Init("a",
2427 params_,
2428 kDefaultPriority,
2429 &callback,
2430 pool_.get(),
2431 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262432 EXPECT_EQ(OK, callback.WaitForResult());
2433
2434 // No idle sockets, no pending jobs.
2435 EXPECT_EQ(0, pool_->IdleSocketCount());
2436 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2437
2438 // Create a second socket to the same host, but this one will wait.
2439 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2440 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132441 EXPECT_EQ(ERR_IO_PENDING,
2442 handle2.Init("a",
2443 params_,
2444 kDefaultPriority,
2445 &callback,
2446 pool_.get(),
2447 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262448 // No idle sockets, and one connecting job.
2449 EXPECT_EQ(0, pool_->IdleSocketCount());
2450 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2451
2452 // Return the first handle to the pool. This will initiate the delayed
2453 // binding.
2454 handle1.Reset();
2455
2456 MessageLoop::current()->RunAllPending();
2457
2458 // Still no idle sockets, still one pending connect job.
2459 EXPECT_EQ(0, pool_->IdleSocketCount());
2460 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2461
2462 // The second socket connected, even though it was a Waiting Job.
2463 EXPECT_EQ(OK, callback.WaitForResult());
2464
2465 // And we can see there is still one job waiting.
2466 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2467
2468 // Finally, signal the waiting Connect.
2469 client_socket_factory_.SignalJobs();
2470 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2471
2472 MessageLoop::current()->RunAllPending();
2473}
2474
2475// Test delayed socket binding when a group is at capacity and one
2476// of the group's sockets frees up.
2477TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2478 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2479 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2480
2481 ClientSocketHandle handle1;
2482 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132483 EXPECT_EQ(ERR_IO_PENDING,
2484 handle1.Init("a",
2485 params_,
2486 kDefaultPriority,
2487 &callback,
2488 pool_.get(),
2489 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262490 EXPECT_EQ(OK, callback.WaitForResult());
2491
2492 // No idle sockets, no pending jobs.
2493 EXPECT_EQ(0, pool_->IdleSocketCount());
2494 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2495
2496 // Create a second socket to the same host, but this one will wait.
2497 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2498 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132499 EXPECT_EQ(ERR_IO_PENDING,
2500 handle2.Init("a",
2501 params_,
2502 kDefaultPriority,
2503 &callback,
2504 pool_.get(),
2505 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262506 // No idle sockets, and one connecting job.
2507 EXPECT_EQ(0, pool_->IdleSocketCount());
2508 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2509
2510 // Return the first handle to the pool. This will initiate the delayed
2511 // binding.
2512 handle1.Reset();
2513
2514 MessageLoop::current()->RunAllPending();
2515
2516 // Still no idle sockets, still one pending connect job.
2517 EXPECT_EQ(0, pool_->IdleSocketCount());
2518 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2519
2520 // The second socket connected, even though it was a Waiting Job.
2521 EXPECT_EQ(OK, callback.WaitForResult());
2522
2523 // And we can see there is still one job waiting.
2524 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2525
2526 // Finally, signal the waiting Connect.
2527 client_socket_factory_.SignalJobs();
2528 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2529
2530 MessageLoop::current()->RunAllPending();
2531}
2532
2533// Test out the case where we have one socket connected, one
2534// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512535// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262536// should complete, by taking the first socket's idle socket.
2537TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2538 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2539 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2540
2541 ClientSocketHandle handle1;
2542 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132543 EXPECT_EQ(ERR_IO_PENDING,
2544 handle1.Init("a",
2545 params_,
2546 kDefaultPriority,
2547 &callback,
2548 pool_.get(),
2549 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262550 EXPECT_EQ(OK, callback.WaitForResult());
2551
2552 // No idle sockets, no pending jobs.
2553 EXPECT_EQ(0, pool_->IdleSocketCount());
2554 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2555
2556 // Create a second socket to the same host, but this one will wait.
2557 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2558 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132559 EXPECT_EQ(ERR_IO_PENDING,
2560 handle2.Init("a",
2561 params_,
2562 kDefaultPriority,
2563 &callback,
2564 pool_.get(),
2565 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262566 // No idle sockets, and one connecting job.
2567 EXPECT_EQ(0, pool_->IdleSocketCount());
2568 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2569
2570 // Return the first handle to the pool. This will initiate the delayed
2571 // binding.
2572 handle1.Reset();
2573
2574 MessageLoop::current()->RunAllPending();
2575
2576 // Still no idle sockets, still one pending connect job.
2577 EXPECT_EQ(0, pool_->IdleSocketCount());
2578 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2579
2580 // The second socket connected, even though it was a Waiting Job.
2581 EXPECT_EQ(OK, callback.WaitForResult());
2582
2583 // And we can see there is still one job waiting.
2584 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2585
2586 // Finally, signal the waiting Connect.
2587 client_socket_factory_.SignalJobs();
2588 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2589
2590 MessageLoop::current()->RunAllPending();
2591}
2592
[email protected]2abfe90a2010-08-25 17:49:512593// Cover the case where on an available socket slot, we have one pending
2594// request that completes synchronously, thereby making the Group empty.
2595TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2596 const int kUnlimitedSockets = 100;
2597 const int kOneSocketPerGroup = 1;
2598 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2599
2600 // Make the first request asynchronous fail.
2601 // This will free up a socket slot later.
2602 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2603
2604 ClientSocketHandle handle1;
2605 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132606 EXPECT_EQ(ERR_IO_PENDING,
2607 handle1.Init("a",
2608 params_,
2609 kDefaultPriority,
2610 &callback1,
2611 pool_.get(),
2612 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512613 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2614
2615 // Make the second request synchronously fail. This should make the Group
2616 // empty.
2617 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2618 ClientSocketHandle handle2;
2619 TestCompletionCallback callback2;
2620 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2621 // when created.
[email protected]2431756e2010-09-29 20:26:132622 EXPECT_EQ(ERR_IO_PENDING,
2623 handle2.Init("a",
2624 params_,
2625 kDefaultPriority,
2626 &callback2,
2627 pool_.get(),
2628 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512629
2630 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2631
2632 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2633 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2634 EXPECT_FALSE(pool_->HasGroup("a"));
2635}
2636
[email protected]e1b54dc2010-10-06 21:27:222637TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2638 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2639
2640 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2641
2642 ClientSocketHandle handle1;
2643 TestCompletionCallback callback1;
2644 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2645 params_,
2646 kDefaultPriority,
2647 &callback1,
2648 pool_.get(),
2649 BoundNetLog()));
2650
2651 ClientSocketHandle handle2;
2652 TestCompletionCallback callback2;
2653 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2654 params_,
2655 kDefaultPriority,
2656 &callback2,
2657 pool_.get(),
2658 BoundNetLog()));
2659 ClientSocketHandle handle3;
2660 TestCompletionCallback callback3;
2661 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2662 params_,
2663 kDefaultPriority,
2664 &callback3,
2665 pool_.get(),
2666 BoundNetLog()));
2667
2668 EXPECT_EQ(OK, callback1.WaitForResult());
2669 EXPECT_EQ(OK, callback2.WaitForResult());
2670 EXPECT_EQ(OK, callback3.WaitForResult());
2671
2672 // Use the socket.
2673 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2674 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2675
2676 handle1.Reset();
2677 handle2.Reset();
2678 handle3.Reset();
2679
2680 EXPECT_EQ(OK, handle1.Init("a",
2681 params_,
2682 kDefaultPriority,
2683 &callback1,
2684 pool_.get(),
2685 BoundNetLog()));
2686 EXPECT_EQ(OK, handle2.Init("a",
2687 params_,
2688 kDefaultPriority,
2689 &callback2,
2690 pool_.get(),
2691 BoundNetLog()));
2692 EXPECT_EQ(OK, handle3.Init("a",
2693 params_,
2694 kDefaultPriority,
2695 &callback3,
2696 pool_.get(),
2697 BoundNetLog()));
2698
2699 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2700 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2701 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2702}
2703
[email protected]2c2bef152010-10-13 00:55:032704TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2705 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2706 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2707
2708 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2709
2710 ASSERT_TRUE(pool_->HasGroup("a"));
2711 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2712 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2713
2714 ClientSocketHandle handle1;
2715 TestCompletionCallback callback1;
2716 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2717 params_,
2718 kDefaultPriority,
2719 &callback1,
2720 pool_.get(),
2721 BoundNetLog()));
2722
2723 ClientSocketHandle handle2;
2724 TestCompletionCallback callback2;
2725 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2726 params_,
2727 kDefaultPriority,
2728 &callback2,
2729 pool_.get(),
2730 BoundNetLog()));
2731
2732 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2733 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2734
2735 EXPECT_EQ(OK, callback1.WaitForResult());
2736 EXPECT_EQ(OK, callback2.WaitForResult());
2737 handle1.Reset();
2738 handle2.Reset();
2739
2740 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2741 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2742}
2743
2744TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2745 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2747
2748 ClientSocketHandle handle1;
2749 TestCompletionCallback callback1;
2750 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2751 params_,
2752 kDefaultPriority,
2753 &callback1,
2754 pool_.get(),
2755 BoundNetLog()));
2756
2757 ASSERT_TRUE(pool_->HasGroup("a"));
2758 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2759 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2760
2761 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2762
2763 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2764 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2765
2766 ClientSocketHandle handle2;
2767 TestCompletionCallback callback2;
2768 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2769 params_,
2770 kDefaultPriority,
2771 &callback2,
2772 pool_.get(),
2773 BoundNetLog()));
2774
2775 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2776 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2777
2778 EXPECT_EQ(OK, callback1.WaitForResult());
2779 EXPECT_EQ(OK, callback2.WaitForResult());
2780 handle1.Reset();
2781 handle2.Reset();
2782
2783 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2784 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2785}
2786
2787TEST_F(ClientSocketPoolBaseTest,
2788 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2789 CreatePool(4, 4);
2790 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2791
2792 ClientSocketHandle handle1;
2793 TestCompletionCallback callback1;
2794 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2795 params_,
2796 kDefaultPriority,
2797 &callback1,
2798 pool_.get(),
2799 BoundNetLog()));
2800
2801 ClientSocketHandle handle2;
2802 TestCompletionCallback callback2;
2803 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2804 params_,
2805 kDefaultPriority,
2806 &callback2,
2807 pool_.get(),
2808 BoundNetLog()));
2809
2810 ClientSocketHandle handle3;
2811 TestCompletionCallback callback3;
2812 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2813 params_,
2814 kDefaultPriority,
2815 &callback3,
2816 pool_.get(),
2817 BoundNetLog()));
2818
2819 ASSERT_TRUE(pool_->HasGroup("a"));
2820 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2821 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2822
2823 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2824
2825 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2826 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2827
2828 EXPECT_EQ(OK, callback1.WaitForResult());
2829 EXPECT_EQ(OK, callback2.WaitForResult());
2830 EXPECT_EQ(OK, callback3.WaitForResult());
2831 handle1.Reset();
2832 handle2.Reset();
2833 handle3.Reset();
2834
2835 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2836 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2837}
2838
2839TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2840 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2841 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2842
2843 ASSERT_FALSE(pool_->HasGroup("a"));
2844
2845 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2846 BoundNetLog());
2847
2848 ASSERT_TRUE(pool_->HasGroup("a"));
2849 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2850
2851 ASSERT_FALSE(pool_->HasGroup("b"));
2852
2853 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2854 BoundNetLog());
2855
2856 ASSERT_FALSE(pool_->HasGroup("b"));
2857}
2858
2859TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2860 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2861 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2862
2863 ASSERT_FALSE(pool_->HasGroup("a"));
2864
2865 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2866 BoundNetLog());
2867
2868 ASSERT_TRUE(pool_->HasGroup("a"));
2869 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2870
2871 ASSERT_FALSE(pool_->HasGroup("b"));
2872
2873 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2874 BoundNetLog());
2875
2876 ASSERT_TRUE(pool_->HasGroup("b"));
2877 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2878}
2879
2880TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2881 CreatePool(4, 4);
2882 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2883
2884 ClientSocketHandle handle1;
2885 TestCompletionCallback callback1;
2886 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2887 params_,
2888 kDefaultPriority,
2889 &callback1,
2890 pool_.get(),
2891 BoundNetLog()));
2892 ASSERT_EQ(OK, callback1.WaitForResult());
2893 handle1.Reset();
2894
2895 ASSERT_TRUE(pool_->HasGroup("a"));
2896 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2897 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2898
2899 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2900
2901 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2902 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2903}
2904
2905TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2906 CreatePool(4, 4);
2907 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2908
2909 ClientSocketHandle handle1;
2910 TestCompletionCallback callback1;
2911 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2912 params_,
2913 kDefaultPriority,
2914 &callback1,
2915 pool_.get(),
2916 BoundNetLog()));
2917 ASSERT_EQ(OK, callback1.WaitForResult());
2918
2919 ASSERT_TRUE(pool_->HasGroup("a"));
2920 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2921 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2922 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2923
2924 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2925
2926 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2927 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2928 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2929}
2930
2931TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2932 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2933 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2934
2935 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2936 BoundNetLog());
2937
2938 ASSERT_TRUE(pool_->HasGroup("a"));
2939 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2940 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2941
2942 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2943 BoundNetLog());
2944
2945 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2946 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2947}
2948
[email protected]3c819f522010-12-02 02:03:122949TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
2950 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2951 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2952
2953 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2954 BoundNetLog());
2955
2956 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:522957
2958 connect_job_factory_->set_job_type(
2959 TestConnectJob::kMockAdditionalErrorStateJob);
2960 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2961 BoundNetLog());
2962
2963 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:122964}
2965
[email protected]2c2bef152010-10-13 00:55:032966TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2967 CreatePool(4, 4);
2968 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2969
2970 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2971
2972 ASSERT_TRUE(pool_->HasGroup("a"));
2973 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2974 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2975
2976 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2977 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2978 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2979
2980 ClientSocketHandle handle1;
2981 TestCompletionCallback callback1;
2982 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2983 params_,
2984 kDefaultPriority,
2985 &callback1,
2986 pool_.get(),
2987 BoundNetLog()));
2988 ASSERT_EQ(OK, callback1.WaitForResult());
2989
2990 ClientSocketHandle handle2;
2991 TestCompletionCallback callback2;
2992 int rv = handle2.Init("a",
2993 params_,
2994 kDefaultPriority,
2995 &callback2,
2996 pool_.get(),
2997 BoundNetLog());
2998 if (rv != OK) {
2999 EXPECT_EQ(ERR_IO_PENDING, rv);
3000 EXPECT_EQ(OK, callback2.WaitForResult());
3001 }
3002
3003 handle1.Reset();
3004 handle2.Reset();
3005
3006 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3007
3008 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3009 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3010 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3011}
3012
3013TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3014 CreatePool(4, 4);
3015 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3016
3017 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3018
3019 ASSERT_TRUE(pool_->HasGroup("a"));
3020 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3021 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3022
3023 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3024 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3025 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3026
3027 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3028 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3029 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3030
3031 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3032 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3033 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3034}
3035
3036TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3037 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3038 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3039
3040 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3041
3042 ASSERT_TRUE(pool_->HasGroup("a"));
3043 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3044 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3045
3046 ClientSocketHandle handle1;
3047 TestCompletionCallback callback1;
3048 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3049 params_,
3050 kDefaultPriority,
3051 &callback1,
3052 pool_.get(),
3053 BoundNetLog()));
3054
3055 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3056 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3057
3058 ASSERT_EQ(OK, callback1.WaitForResult());
3059
3060 handle1.Reset();
3061
3062 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3063}
3064
[email protected]dcbe168a2010-12-02 03:14:463065// http://crbug.com/64940 regression test.
3066TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3067 const int kMaxTotalSockets = 3;
3068 const int kMaxSocketsPerGroup = 2;
3069 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3070 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3071
3072 // Note that group name ordering matters here. "a" comes before "b", so
3073 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3074
3075 // Set up one idle socket in "a".
3076 ClientSocketHandle handle1;
3077 TestCompletionCallback callback1;
3078 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3079 params_,
3080 kDefaultPriority,
3081 &callback1,
3082 pool_.get(),
3083 BoundNetLog()));
3084
3085 ASSERT_EQ(OK, callback1.WaitForResult());
3086 handle1.Reset();
3087 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3088
3089 // Set up two active sockets in "b".
3090 ClientSocketHandle handle2;
3091 TestCompletionCallback callback2;
3092 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3093 params_,
3094 kDefaultPriority,
3095 &callback1,
3096 pool_.get(),
3097 BoundNetLog()));
3098 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3099 params_,
3100 kDefaultPriority,
3101 &callback2,
3102 pool_.get(),
3103 BoundNetLog()));
3104
3105 ASSERT_EQ(OK, callback1.WaitForResult());
3106 ASSERT_EQ(OK, callback2.WaitForResult());
3107 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3108 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3109
3110 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3111 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3112 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3113 // sockets for "a", and "b" should still have 2 active sockets.
3114
3115 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3116 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3117 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3118 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3119 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3120 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3121 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3122
3123 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3124 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3125 // "a" should result in closing 1 for "b".
3126 handle1.Reset();
3127 handle2.Reset();
3128 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3129 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3130
3131 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3132 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3133 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3134 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3135 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3136 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3137 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3138}
3139
[email protected]a9fc8fc2011-05-10 02:41:073140TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupTimer) {
3141 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3142 pool_->EnableConnectBackupJobs();
3143
3144 // Make the ConnectJob hang until it times out, shorten the timeout.
3145 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3146 connect_job_factory_->set_timeout_duration(
3147 base::TimeDelta::FromMilliseconds(500));
3148 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3149 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3150 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3151 MessageLoop::current()->RunAllPending();
3152
3153 // Make sure the backup timer doesn't fire, by making it a pending job instead
3154 // of a waiting job, so it *would* complete if the timer fired.
3155 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3156 base::PlatformThread::Sleep(1000);
3157 MessageLoop::current()->RunAllPending();
3158 EXPECT_FALSE(pool_->HasGroup("a"));
3159}
3160
3161TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupTimer) {
3162 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3163 pool_->EnableConnectBackupJobs();
3164
3165 // Make the ConnectJob hang forever.
3166 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3167 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3168 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3169 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3170 MessageLoop::current()->RunAllPending();
3171
3172 // Make the backup job be a pending job, so it completes normally.
3173 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3174 ClientSocketHandle handle;
3175 TestCompletionCallback callback;
3176 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3177 params_,
3178 kDefaultPriority,
3179 &callback,
3180 pool_.get(),
3181 BoundNetLog()));
3182 // Timer has started, but the other connect job shouldn't be created yet.
3183 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3184 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3185 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3186 ASSERT_EQ(OK, callback.WaitForResult());
3187
3188 // The hung connect job should still be there, but everything else should be
3189 // complete.
3190 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3191 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3192 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3193}
3194
[email protected]f6d1d6eb2009-06-24 20:16:093195} // namespace
3196
3197} // namespace net