blob: f8a21fbeff59da863ead9843689aa76b2efea55c [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]f3a1c642011-07-12 19:15:0315#include "base/values.h"
[email protected]d8eb84242010-09-25 02:25:0616#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5317#include "net/base/net_log.h"
18#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3119#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0920#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3521#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0922#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]3268023f2011-05-05 00:08:1027#include "net/socket/stream_socket.h"
[email protected]f6d1d6eb2009-06-24 20:16:0928#include "testing/gtest/include/gtest/gtest.h"
29
30namespace net {
31
32namespace {
33
[email protected]211d21722009-07-22 15:48:5334const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2035const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5236const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0137
[email protected]df4b4ef2010-07-12 18:25:2138class TestSocketParams : public base::RefCounted<TestSocketParams> {
[email protected]5acdce12011-03-30 13:00:2039 public:
40 bool ignore_limits() { return false; }
[email protected]df4b4ef2010-07-12 18:25:2141 private:
42 friend class base::RefCounted<TestSocketParams>;
43 ~TestSocketParams() {}
44};
[email protected]7fc5b09a2010-02-27 00:07:3845typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4946
[email protected]3268023f2011-05-05 00:08:1047class MockClientSocket : public StreamSocket {
[email protected]f6d1d6eb2009-06-24 20:16:0948 public:
[email protected]5e6efa52011-06-27 17:26:4149 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
50 num_bytes_read_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0951
[email protected]ab838892009-06-30 18:49:0552 // Socket methods:
53 virtual int Read(
[email protected]f1f3f0f82011-10-01 20:38:1054 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]5e6efa52011-06-27 17:26:4155 num_bytes_read_ += len;
56 return len;
[email protected]ab838892009-06-30 18:49:0557 }
58
59 virtual int Write(
[email protected]f1f3f0f82011-10-01 20:38:1060 IOBuffer* /* buf */, int len, OldCompletionCallback* /* callback */) {
[email protected]0f873e82010-09-02 16:09:0161 was_used_to_convey_data_ = true;
62 return len;
[email protected]ab838892009-06-30 18:49:0563 }
[email protected]06650c52010-06-03 00:49:1764 virtual bool SetReceiveBufferSize(int32 size) { return true; }
65 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0566
[email protected]3268023f2011-05-05 00:08:1067 // StreamSocket methods:
[email protected]ab838892009-06-30 18:49:0568
[email protected]f1f3f0f82011-10-01 20:38:1069 virtual int Connect(OldCompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0970 connected_ = true;
71 return OK;
72 }
[email protected]f6d1d6eb2009-06-24 20:16:0973
[email protected]ab838892009-06-30 18:49:0574 virtual void Disconnect() { connected_ = false; }
75 virtual bool IsConnected() const { return connected_; }
76 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0177
[email protected]ac9eec62010-02-20 18:50:3878 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1679 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0980 }
[email protected]f6d1d6eb2009-06-24 20:16:0981
[email protected]e7f74da2011-04-19 23:49:3582 virtual int GetLocalAddress(IPEndPoint* /* address */) const {
83 return ERR_UNEXPECTED;
84 }
85
[email protected]a2006ece2010-04-23 16:44:0286 virtual const BoundNetLog& NetLog() const {
87 return net_log_;
88 }
89
[email protected]9b5614a2010-08-25 20:29:4590 virtual void SetSubresourceSpeculation() {}
91 virtual void SetOmniboxSpeculation() {}
[email protected]5e6efa52011-06-27 17:26:4192 virtual bool WasEverUsed() const {
93 return was_used_to_convey_data_ || num_bytes_read_ > 0;
94 }
[email protected]7f7e92392010-10-26 18:29:2995 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]5e6efa52011-06-27 17:26:4196 virtual int64 NumBytesRead() const { return num_bytes_read_; }
97 virtual base::TimeDelta GetConnectTimeMicros() const {
98 static const base::TimeDelta kDummyConnectTimeMicros =
99 base::TimeDelta::FromMicroseconds(10);
100 return kDummyConnectTimeMicros; // Dummy value.
101 }
[email protected]9b5614a2010-08-25 20:29:45102
[email protected]f6d1d6eb2009-06-24 20:16:09103 private:
104 bool connected_;
[email protected]a2006ece2010-04-23 16:44:02105 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:01106 bool was_used_to_convey_data_;
[email protected]5e6efa52011-06-27 17:26:41107 int num_bytes_read_;
[email protected]f6d1d6eb2009-06-24 20:16:09108
[email protected]ab838892009-06-30 18:49:05109 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:09110};
111
[email protected]5fc08e32009-07-15 17:09:57112class TestConnectJob;
113
[email protected]f6d1d6eb2009-06-24 20:16:09114class MockClientSocketFactory : public ClientSocketFactory {
115 public:
[email protected]ab838892009-06-30 18:49:05116 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:09117
[email protected]98b0e582011-06-22 14:31:41118 virtual DatagramClientSocket* CreateDatagramClientSocket(
[email protected]5370c012011-06-29 03:47:04119 DatagramSocket::BindType bind_type,
120 const RandIntCallback& rand_int_cb,
[email protected]98b0e582011-06-22 14:31:41121 NetLog* net_log,
122 const NetLog::Source& source) {
123 NOTREACHED();
124 return NULL;
125 }
126
[email protected]3268023f2011-05-05 00:08:10127 virtual StreamSocket* CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07128 const AddressList& addresses,
129 NetLog* /* net_log */,
130 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09131 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05132 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09133 }
134
135 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18136 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27137 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21138 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12139 SSLHostInfo* ssl_host_info,
[email protected]feb79bcd2011-07-21 16:55:17140 const SSLClientSocketContext& context) {
[email protected]f6d1d6eb2009-06-24 20:16:09141 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21142 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09143 return NULL;
144 }
145
[email protected]25f47352011-02-25 16:31:59146 virtual void ClearSSLSessionCache() {
147 NOTIMPLEMENTED();
148 }
149
[email protected]5fc08e32009-07-15 17:09:57150 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
151 void SignalJobs();
152
[email protected]f6d1d6eb2009-06-24 20:16:09153 int allocation_count() const { return allocation_count_; }
154
[email protected]f6d1d6eb2009-06-24 20:16:09155 private:
156 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57157 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09158};
159
[email protected]ab838892009-06-30 18:49:05160class TestConnectJob : public ConnectJob {
161 public:
162 enum JobType {
163 kMockJob,
164 kMockFailingJob,
165 kMockPendingJob,
166 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57167 kMockWaitingJob,
168 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13169 kMockRecoverableJob,
170 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18171 kMockAdditionalErrorStateJob,
172 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05173 };
174
[email protected]994d4932010-07-12 17:55:13175 // The kMockPendingJob uses a slight delay before allowing the connect
176 // to complete.
177 static const int kPendingConnectDelay = 2;
178
[email protected]ab838892009-06-30 18:49:05179 TestConnectJob(JobType job_type,
180 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49181 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34182 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05183 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30184 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17185 NetLog* net_log)
186 : ConnectJob(group_name, timeout_duration, delegate,
187 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58188 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05189 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21190 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18191 load_state_(LOAD_STATE_IDLE),
192 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05193
[email protected]974ebd62009-08-03 23:14:34194 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13195 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34196 }
197
[email protected]46451352009-09-01 14:54:21198 virtual LoadState GetLoadState() const { return load_state_; }
199
[email protected]e60e47a2010-07-14 03:37:18200 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
201 if (store_additional_error_state_) {
202 // Set all of the additional error state fields in some way.
203 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43204 HttpResponseInfo info;
205 info.headers = new HttpResponseHeaders("");
206 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18207 }
208 }
209
[email protected]974ebd62009-08-03 23:14:34210 private:
[email protected]ab838892009-06-30 18:49:05211 // ConnectJob methods:
212
[email protected]974ebd62009-08-03 23:14:34213 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05214 AddressList ignored;
[email protected]ab739042011-04-07 15:22:28215 client_socket_factory_->CreateTransportClientSocket(
[email protected]0a0b7682010-08-25 17:08:07216 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40217 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05218 switch (job_type_) {
219 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13220 return DoConnect(true /* successful */, false /* sync */,
221 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05222 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13223 return DoConnect(false /* error */, false /* sync */,
224 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05225 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57226 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47227
228 // Depending on execution timings, posting a delayed task can result
229 // in the task getting executed the at the earliest possible
230 // opportunity or only after returning once from the message loop and
231 // then a second call into the message loop. In order to make behavior
232 // more deterministic, we change the default delay to 2ms. This should
233 // always require us to wait for the second call into the message loop.
234 //
235 // N.B. The correct fix for this and similar timing problems is to
236 // abstract time for the purpose of unittests. Unfortunately, we have
237 // a lot of third-party components that directly call the various
238 // time functions, so this change would be rather invasive.
239 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05240 FROM_HERE,
241 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47242 &TestConnectJob::DoConnect,
243 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13244 true /* async */,
245 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13246 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05247 return ERR_IO_PENDING;
248 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57249 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47250 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05251 FROM_HERE,
252 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47253 &TestConnectJob::DoConnect,
254 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13255 true /* async */,
256 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47257 2);
[email protected]ab838892009-06-30 18:49:05258 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57259 case kMockWaitingJob:
260 client_socket_factory_->WaitForSignal(this);
261 waiting_success_ = true;
262 return ERR_IO_PENDING;
263 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46264 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57265 FROM_HERE,
266 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46267 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57268 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13269 case kMockRecoverableJob:
270 return DoConnect(false /* error */, false /* sync */,
271 true /* recoverable */);
272 case kMockPendingRecoverableJob:
273 set_load_state(LOAD_STATE_CONNECTING);
274 MessageLoop::current()->PostDelayedTask(
275 FROM_HERE,
276 method_factory_.NewRunnableMethod(
277 &TestConnectJob::DoConnect,
278 false /* error */,
279 true /* async */,
280 true /* recoverable */),
281 2);
282 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18283 case kMockAdditionalErrorStateJob:
284 store_additional_error_state_ = true;
285 return DoConnect(false /* error */, false /* sync */,
286 false /* recoverable */);
287 case kMockPendingAdditionalErrorStateJob:
288 set_load_state(LOAD_STATE_CONNECTING);
289 store_additional_error_state_ = true;
290 MessageLoop::current()->PostDelayedTask(
291 FROM_HERE,
292 method_factory_.NewRunnableMethod(
293 &TestConnectJob::DoConnect,
294 false /* error */,
295 true /* async */,
296 false /* recoverable */),
297 2);
298 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05299 default:
300 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40301 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05302 return ERR_FAILED;
303 }
304 }
305
[email protected]46451352009-09-01 14:54:21306 void set_load_state(LoadState load_state) { load_state_ = load_state; }
307
[email protected]e772db3f2010-07-12 18:11:13308 int DoConnect(bool succeed, bool was_async, bool recoverable) {
309 int result = OK;
[email protected]ab838892009-06-30 18:49:05310 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02311 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13312 } else if (recoverable) {
313 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40314 } else {
[email protected]e772db3f2010-07-12 18:11:13315 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40316 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05317 }
[email protected]2ab05b52009-07-01 23:57:58318
319 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30320 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05321 return result;
322 }
323
[email protected]cfa8228c2010-06-17 01:07:56324 // This function helps simulate the progress of load states on a ConnectJob.
325 // Each time it is called it advances the load state and posts a task to be
326 // called again. It stops at the last connecting load state (the one
327 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57328 void AdvanceLoadState(LoadState state) {
329 int tmp = state;
330 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56331 if (tmp < LOAD_STATE_SENDING_REQUEST) {
332 state = static_cast<LoadState>(tmp);
333 set_load_state(state);
334 MessageLoop::current()->PostTask(
335 FROM_HERE,
336 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
337 state));
338 }
[email protected]5fc08e32009-07-15 17:09:57339 }
340
341 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05342 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57343 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05344 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21345 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18346 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05347
348 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
349};
350
[email protected]d80a4322009-08-14 07:07:49351class TestConnectJobFactory
352 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05353 public:
[email protected]5fc08e32009-07-15 17:09:57354 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05355 : job_type_(TestConnectJob::kMockJob),
356 client_socket_factory_(client_socket_factory) {}
357
358 virtual ~TestConnectJobFactory() {}
359
360 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
361
[email protected]974ebd62009-08-03 23:14:34362 void set_timeout_duration(base::TimeDelta timeout_duration) {
363 timeout_duration_ = timeout_duration;
364 }
365
[email protected]ab838892009-06-30 18:49:05366 // ConnectJobFactory methods:
367
368 virtual ConnectJob* NewConnectJob(
369 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49370 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17371 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05372 return new TestConnectJob(job_type_,
373 group_name,
374 request,
[email protected]974ebd62009-08-03 23:14:34375 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05376 delegate,
[email protected]fd7b7c92009-08-20 19:38:30377 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17378 NULL);
[email protected]ab838892009-06-30 18:49:05379 }
380
[email protected]a796bcec2010-03-22 17:17:26381 virtual base::TimeDelta ConnectionTimeout() const {
382 return timeout_duration_;
383 }
384
[email protected]ab838892009-06-30 18:49:05385 private:
386 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34387 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57388 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05389
390 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
391};
392
393class TestClientSocketPool : public ClientSocketPool {
394 public:
395 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53396 int max_sockets,
[email protected]ab838892009-06-30 18:49:05397 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13398 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16399 base::TimeDelta unused_idle_socket_timeout,
400 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49401 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00402 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16403 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38404 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05405
[email protected]2431756e2010-09-29 20:26:13406 virtual ~TestClientSocketPool() {}
407
[email protected]ab838892009-06-30 18:49:05408 virtual int RequestSocket(
409 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49410 const void* params,
[email protected]ac790b42009-12-02 04:31:31411 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05412 ClientSocketHandle* handle,
[email protected]f1f3f0f82011-10-01 20:38:10413 OldCompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53414 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21415 const scoped_refptr<TestSocketParams>* casted_socket_params =
416 static_cast<const scoped_refptr<TestSocketParams>*>(params);
417 return base_.RequestSocket(group_name, *casted_socket_params, priority,
418 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05419 }
420
[email protected]2c2bef152010-10-13 00:55:03421 virtual void RequestSockets(const std::string& group_name,
422 const void* params,
423 int num_sockets,
424 const BoundNetLog& net_log) {
425 const scoped_refptr<TestSocketParams>* casted_params =
426 static_cast<const scoped_refptr<TestSocketParams>*>(params);
427
428 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
429 }
430
[email protected]ab838892009-06-30 18:49:05431 virtual void CancelRequest(
432 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21433 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49434 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05435 }
436
437 virtual void ReleaseSocket(
438 const std::string& group_name,
[email protected]3268023f2011-05-05 00:08:10439 StreamSocket* socket,
[email protected]a7e38572010-06-07 18:22:24440 int id) {
441 base_.ReleaseSocket(group_name, socket, id);
442 }
443
444 virtual void Flush() {
445 base_.Flush();
[email protected]ab838892009-06-30 18:49:05446 }
447
448 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49449 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05450 }
451
[email protected]d80a4322009-08-14 07:07:49452 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05453
454 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49455 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05456 }
457
458 virtual LoadState GetLoadState(const std::string& group_name,
459 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49460 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05461 }
462
[email protected]ba00b492010-09-08 14:53:38463 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
464 const std::string& type,
465 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27466 return base_.GetInfoAsValue(name, type);
467 }
468
[email protected]a796bcec2010-03-22 17:17:26469 virtual base::TimeDelta ConnectionTimeout() const {
470 return base_.ConnectionTimeout();
471 }
472
[email protected]2431756e2010-09-29 20:26:13473 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00474 return base_.histograms();
475 }
[email protected]a796bcec2010-03-22 17:17:26476
[email protected]d80a4322009-08-14 07:07:49477 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20478
[email protected]974ebd62009-08-03 23:14:34479 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49480 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34481 }
482
[email protected]2c2bef152010-10-13 00:55:03483 int NumActiveSocketsInGroup(const std::string& group_name) const {
484 return base_.NumActiveSocketsInGroup(group_name);
485 }
486
[email protected]2abfe90a2010-08-25 17:49:51487 bool HasGroup(const std::string& group_name) const {
488 return base_.HasGroup(group_name);
489 }
490
[email protected]9bf28db2009-08-29 01:35:16491 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
492
[email protected]06d94042010-08-25 01:45:22493 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54494
[email protected]ab838892009-06-30 18:49:05495 private:
[email protected]d80a4322009-08-14 07:07:49496 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05497
498 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
499};
500
[email protected]a937a06d2009-08-19 21:19:24501} // namespace
502
[email protected]7fc5b09a2010-02-27 00:07:38503REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24504
505namespace {
506
[email protected]5fc08e32009-07-15 17:09:57507void MockClientSocketFactory::SignalJobs() {
508 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
509 it != waiting_jobs_.end(); ++it) {
510 (*it)->Signal();
511 }
512 waiting_jobs_.clear();
513}
514
[email protected]974ebd62009-08-03 23:14:34515class TestConnectJobDelegate : public ConnectJob::Delegate {
516 public:
517 TestConnectJobDelegate()
518 : have_result_(false), waiting_for_result_(false), result_(OK) {}
519 virtual ~TestConnectJobDelegate() {}
520
521 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
522 result_ = result;
[email protected]3268023f2011-05-05 00:08:10523 scoped_ptr<StreamSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07524 // socket.get() should be NULL iff result != OK
525 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34526 delete job;
527 have_result_ = true;
528 if (waiting_for_result_)
529 MessageLoop::current()->Quit();
530 }
531
532 int WaitForResult() {
533 DCHECK(!waiting_for_result_);
534 while (!have_result_) {
535 waiting_for_result_ = true;
536 MessageLoop::current()->Run();
537 waiting_for_result_ = false;
538 }
539 have_result_ = false; // auto-reset for next callback
540 return result_;
541 }
542
543 private:
544 bool have_result_;
545 bool waiting_for_result_;
546 int result_;
547};
548
[email protected]2431756e2010-09-29 20:26:13549class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09550 protected:
[email protected]b89f7e42010-05-20 20:37:00551 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21552 : params_(new TestSocketParams()),
[email protected]636b8252011-04-08 19:56:54553 histograms_("ClientSocketPoolTest") {
554 connect_backup_jobs_enabled_ =
555 internal::ClientSocketPoolBaseHelper::connect_backup_jobs_enabled();
556 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true);
[email protected]64770b7d2011-11-16 04:30:41557 cleanup_timer_enabled_ =
558 internal::ClientSocketPoolBaseHelper::cleanup_timer_enabled();
[email protected]636b8252011-04-08 19:56:54559 }
[email protected]2431756e2010-09-29 20:26:13560
[email protected]636b8252011-04-08 19:56:54561 virtual ~ClientSocketPoolBaseTest() {
562 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
563 connect_backup_jobs_enabled_);
[email protected]64770b7d2011-11-16 04:30:41564 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(
565 cleanup_timer_enabled_);
[email protected]636b8252011-04-08 19:56:54566 }
[email protected]c9d6a1d2009-07-14 16:15:20567
[email protected]211d21722009-07-22 15:48:53568 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16569 CreatePoolWithIdleTimeouts(
570 max_sockets,
571 max_sockets_per_group,
[email protected]82b8c962011-10-12 09:17:30572 ClientSocketPool::unused_idle_socket_timeout(),
573 ClientSocketPool::used_idle_socket_timeout());
[email protected]9bf28db2009-08-29 01:35:16574 }
575
576 void CreatePoolWithIdleTimeouts(
577 int max_sockets, int max_sockets_per_group,
578 base::TimeDelta unused_idle_socket_timeout,
579 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20580 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04581 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13582 pool_.reset(new TestClientSocketPool(max_sockets,
583 max_sockets_per_group,
584 &histograms_,
585 unused_idle_socket_timeout,
586 used_idle_socket_timeout,
587 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20588 }
[email protected]f6d1d6eb2009-06-24 20:16:09589
[email protected]ac790b42009-12-02 04:31:31590 int StartRequest(const std::string& group_name,
591 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13592 return test_base_.StartRequestUsingPool<
593 TestClientSocketPool, TestSocketParams>(
594 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09595 }
596
[email protected]2431756e2010-09-29 20:26:13597 int GetOrderOfRequest(size_t index) const {
598 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09599 }
600
[email protected]2431756e2010-09-29 20:26:13601 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
602 return test_base_.ReleaseOneConnection(keep_alive);
603 }
604
605 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
606 test_base_.ReleaseAllConnections(keep_alive);
607 }
608
609 TestSocketRequest* request(int i) { return test_base_.request(i); }
610 size_t requests_size() const { return test_base_.requests_size(); }
611 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
612 size_t completion_count() const { return test_base_.completion_count(); }
613
[email protected]636b8252011-04-08 19:56:54614 bool connect_backup_jobs_enabled_;
[email protected]64770b7d2011-11-16 04:30:41615 bool cleanup_timer_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09616 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04617 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21618 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13619 ClientSocketPoolHistograms histograms_;
620 scoped_ptr<TestClientSocketPool> pool_;
621 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09622};
623
[email protected]5e6efa52011-06-27 17:26:41624TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
625 CreatePool(4, 4);
626 net::SetSocketReusePolicy(0);
627
628 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
629 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
630 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
631 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
632
633 std::map<int, StreamSocket*> sockets_;
634 for (size_t i = 0; i < test_base_.requests_size(); i++) {
635 TestSocketRequest* req = test_base_.request(i);
636 StreamSocket* s = req->handle()->socket();
637 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
638 CHECK(sock);
639 sockets_[i] = sock;
640 sock->Read(NULL, 1024 - i, NULL);
641 }
642
643 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
644
645 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
646 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
647
648 // First socket is warmest.
649 EXPECT_EQ(sockets_[0], req->handle()->socket());
650
651 // Test that NumBytes are as expected.
652 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
653 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
654 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
655 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
656
657 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
658}
659
660TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
661 CreatePool(4, 4);
662 net::SetSocketReusePolicy(2);
663
664 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
665 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
666 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
667 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
668
669 std::map<int, StreamSocket*> sockets_;
670 for (size_t i = 0; i < test_base_.requests_size(); i++) {
671 TestSocketRequest* req = test_base_.request(i);
672 StreamSocket* s = req->handle()->socket();
673 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
674 CHECK(sock);
675 sockets_[i] = sock;
676 sock->Read(NULL, 1024 - i, NULL);
677 }
678
679 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
680
681 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
682 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
683
684 // Last socket is most recently accessed.
685 EXPECT_EQ(sockets_[3], req->handle()->socket());
686 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
687}
688
[email protected]974ebd62009-08-03 23:14:34689// Even though a timeout is specified, it doesn't time out on a synchronous
690// completion.
691TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
692 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06693 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49694 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03695 &ignored, NULL, kDefaultPriority,
696 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20697 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34698 scoped_ptr<TestConnectJob> job(
699 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12700 "a",
[email protected]974ebd62009-08-03 23:14:34701 request,
702 base::TimeDelta::FromMicroseconds(1),
703 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30704 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17705 NULL));
[email protected]974ebd62009-08-03 23:14:34706 EXPECT_EQ(OK, job->Connect());
707}
708
709TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
710 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06711 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17712 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53713
[email protected]d80a4322009-08-14 07:07:49714 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03715 &ignored, NULL, kDefaultPriority,
716 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20717 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34718 // Deleted by TestConnectJobDelegate.
719 TestConnectJob* job =
720 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12721 "a",
[email protected]974ebd62009-08-03 23:14:34722 request,
723 base::TimeDelta::FromMicroseconds(1),
724 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30725 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17726 &log);
[email protected]974ebd62009-08-03 23:14:34727 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08728 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34729 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30730
[email protected]b2fcd0e2010-12-01 15:19:40731 net::CapturingNetLog::EntryList entries;
732 log.GetEntries(&entries);
733
734 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46735 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40736 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17737 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40738 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46739 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40740 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17741 NetLog::PHASE_NONE));
742 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40743 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53744 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46745 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40746 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17747 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40748 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34749}
750
[email protected]5fc08e32009-07-15 17:09:57751TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53752 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20753
[email protected]f1f3f0f82011-10-01 20:38:10754 TestOldCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06755 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53756 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
757
[email protected]2431756e2010-09-29 20:26:13758 EXPECT_EQ(OK,
759 handle.Init("a",
760 params_,
761 kDefaultPriority,
762 &callback,
763 pool_.get(),
764 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09765 EXPECT_TRUE(handle.is_initialized());
766 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09767 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30768
[email protected]b2fcd0e2010-12-01 15:19:40769 net::CapturingNetLog::EntryList entries;
770 log.GetEntries(&entries);
771
772 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46773 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40774 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53775 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40776 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17777 NetLog::PHASE_NONE));
778 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40779 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53780 NetLog::PHASE_NONE));
781 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40782 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09783}
784
[email protected]ab838892009-06-30 18:49:05785TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53786 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20787
[email protected]ab838892009-06-30 18:49:05788 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53789 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
790
[email protected]2431756e2010-09-29 20:26:13791 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:10792 TestOldCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18793 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13794 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43795 HttpResponseInfo info;
796 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13797 handle.set_ssl_error_response_info(info);
798 EXPECT_EQ(ERR_CONNECTION_FAILED,
799 handle.Init("a",
800 params_,
801 kDefaultPriority,
802 &callback,
803 pool_.get(),
804 log.bound()));
805 EXPECT_FALSE(handle.socket());
806 EXPECT_FALSE(handle.is_ssl_error());
807 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30808
[email protected]b2fcd0e2010-12-01 15:19:40809 net::CapturingNetLog::EntryList entries;
810 log.GetEntries(&entries);
811
812 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27813 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40814 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17815 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40816 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17817 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02818 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40819 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09820}
821
[email protected]211d21722009-07-22 15:48:53822TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
824
[email protected]9e743cd2010-03-16 07:03:53825 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30826
[email protected]211d21722009-07-22 15:48:53827 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
828 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
829 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
830 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
831
[email protected]2431756e2010-09-29 20:26:13832 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53833 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13834 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53835
836 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
837 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
838 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
839
[email protected]2431756e2010-09-29 20:26:13840 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53841
[email protected]2431756e2010-09-29 20:26:13842 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53843 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13844 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53845
846 EXPECT_EQ(1, GetOrderOfRequest(1));
847 EXPECT_EQ(2, GetOrderOfRequest(2));
848 EXPECT_EQ(3, GetOrderOfRequest(3));
849 EXPECT_EQ(4, GetOrderOfRequest(4));
850 EXPECT_EQ(5, GetOrderOfRequest(5));
851 EXPECT_EQ(6, GetOrderOfRequest(6));
852 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17853
854 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13855 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53856}
857
858TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
859 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
860
[email protected]9e743cd2010-03-16 07:03:53861 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30862
[email protected]211d21722009-07-22 15:48:53863 // Reach all limits: max total sockets, and max sockets per group.
864 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
865 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
866 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
867 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
868
[email protected]2431756e2010-09-29 20:26:13869 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53870 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13871 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53872
873 // Now create a new group and verify that we don't starve it.
874 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
875
[email protected]2431756e2010-09-29 20:26:13876 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53877
[email protected]2431756e2010-09-29 20:26:13878 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53879 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13880 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53881
882 EXPECT_EQ(1, GetOrderOfRequest(1));
883 EXPECT_EQ(2, GetOrderOfRequest(2));
884 EXPECT_EQ(3, GetOrderOfRequest(3));
885 EXPECT_EQ(4, GetOrderOfRequest(4));
886 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17887
888 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13889 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53890}
891
892TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
893 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
894
[email protected]ac790b42009-12-02 04:31:31895 EXPECT_EQ(OK, StartRequest("b", LOWEST));
896 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
897 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
898 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53899
[email protected]2431756e2010-09-29 20:26:13900 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53901 client_socket_factory_.allocation_count());
902
[email protected]ac790b42009-12-02 04:31:31903 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
904 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
905 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53906
[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(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53910
911 // First 4 requests don't have to wait, and finish in order.
912 EXPECT_EQ(1, GetOrderOfRequest(1));
913 EXPECT_EQ(2, GetOrderOfRequest(2));
914 EXPECT_EQ(3, GetOrderOfRequest(3));
915 EXPECT_EQ(4, GetOrderOfRequest(4));
916
[email protected]ac790b42009-12-02 04:31:31917 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
918 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53919 EXPECT_EQ(7, GetOrderOfRequest(5));
920 EXPECT_EQ(6, GetOrderOfRequest(6));
921 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17922
923 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13924 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53925}
926
927TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
928 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
929
[email protected]ac790b42009-12-02 04:31:31930 EXPECT_EQ(OK, StartRequest("a", LOWEST));
931 EXPECT_EQ(OK, StartRequest("a", LOW));
932 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
933 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53934
[email protected]2431756e2010-09-29 20:26:13935 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53936 client_socket_factory_.allocation_count());
937
[email protected]ac790b42009-12-02 04:31:31938 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
939 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
940 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53941
[email protected]2431756e2010-09-29 20:26:13942 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53943
[email protected]2431756e2010-09-29 20:26:13944 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53945 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13946 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53947
948 // First 4 requests don't have to wait, and finish in order.
949 EXPECT_EQ(1, GetOrderOfRequest(1));
950 EXPECT_EQ(2, GetOrderOfRequest(2));
951 EXPECT_EQ(3, GetOrderOfRequest(3));
952 EXPECT_EQ(4, GetOrderOfRequest(4));
953
954 // Request ("b", 7) has the highest priority, but we can't make new socket for
955 // group "b", because it has reached the per-group limit. Then we make
956 // socket for ("c", 6), because it has higher priority than ("a", 4),
957 // and we still can't make a socket for group "b".
958 EXPECT_EQ(5, GetOrderOfRequest(5));
959 EXPECT_EQ(6, GetOrderOfRequest(6));
960 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17961
962 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13963 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53964}
965
966// Make sure that we count connecting sockets against the total limit.
967TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
968 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
969
970 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
971 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
972 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
973
974 // Create one asynchronous request.
975 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
976 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
977
[email protected]6b175382009-10-13 06:47:47978 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
979 // actually become pending until 2ms after they have been created. In order
980 // to flush all tasks, we need to wait so that we know there are no
981 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08982 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47983 MessageLoop::current()->RunAllPending();
984
[email protected]211d21722009-07-22 15:48:53985 // The next synchronous request should wait for its turn.
986 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
987 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
988
[email protected]2431756e2010-09-29 20:26:13989 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53990
[email protected]2431756e2010-09-29 20:26:13991 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53992 client_socket_factory_.allocation_count());
993
994 EXPECT_EQ(1, GetOrderOfRequest(1));
995 EXPECT_EQ(2, GetOrderOfRequest(2));
996 EXPECT_EQ(3, GetOrderOfRequest(3));
997 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17998 EXPECT_EQ(5, GetOrderOfRequest(5));
999
1000 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131001 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:531002}
1003
[email protected]6427fe22010-04-16 22:27:411004TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1005 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1006 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1007
1008 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1009 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1010 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1011 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1012
1013 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1014
1015 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1016
1017 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1018 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1019
1020 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1021
[email protected]2431756e2010-09-29 20:26:131022 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411023 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131024 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411025 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131026 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1027 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411028 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1029}
1030
[email protected]d7027bb2010-05-10 18:58:541031TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1032 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1033 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1034
1035 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101036 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131037 EXPECT_EQ(ERR_IO_PENDING,
1038 handle.Init("a",
1039 params_,
1040 kDefaultPriority,
1041 &callback,
1042 pool_.get(),
1043 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541044
1045 ClientSocketHandle handles[4];
1046 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101047 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131048 EXPECT_EQ(ERR_IO_PENDING,
1049 handles[i].Init("b",
1050 params_,
1051 kDefaultPriority,
1052 &callback,
1053 pool_.get(),
1054 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541055 }
1056
1057 // One will be stalled, cancel all the handles now.
1058 // This should hit the OnAvailableSocketSlot() code where we previously had
1059 // stalled groups, but no longer have any.
1060 for (size_t i = 0; i < arraysize(handles); ++i)
1061 handles[i].Reset();
1062}
1063
[email protected]eb5a99382010-07-11 03:18:261064TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541065 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1066 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1067
[email protected]eb5a99382010-07-11 03:18:261068 {
1069 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]f1f3f0f82011-10-01 20:38:101070 TestOldCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261071 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131072 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1073 params_,
[email protected]e83326f2010-07-31 17:29:251074 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:131075 &callbacks[i],
1076 pool_.get(),
1077 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261078 }
1079
1080 // Force a stalled group.
1081 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101082 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131083 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1084 params_,
1085 kDefaultPriority,
1086 &callback,
1087 pool_.get(),
1088 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261089
1090 // Cancel the stalled request.
1091 stalled_handle.Reset();
1092
1093 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1094 EXPECT_EQ(0, pool_->IdleSocketCount());
1095
1096 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541097 }
1098
[email protected]43a21b82010-06-10 21:30:541099 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1100 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261101}
[email protected]43a21b82010-06-10 21:30:541102
[email protected]eb5a99382010-07-11 03:18:261103TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1104 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1105 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1106
1107 {
1108 ClientSocketHandle handles[kDefaultMaxSockets];
1109 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101110 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131111 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1112 params_,
1113 kDefaultPriority,
1114 &callback,
1115 pool_.get(),
1116 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261117 }
1118
1119 // Force a stalled group.
1120 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1121 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101122 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131123 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1124 params_,
1125 kDefaultPriority,
1126 &callback,
1127 pool_.get(),
1128 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261129
1130 // Since it is stalled, it should have no connect jobs.
1131 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1132
1133 // Cancel the stalled request.
1134 handles[0].Reset();
1135
[email protected]eb5a99382010-07-11 03:18:261136 // Now we should have a connect job.
1137 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1138
1139 // The stalled socket should connect.
1140 EXPECT_EQ(OK, callback.WaitForResult());
1141
1142 EXPECT_EQ(kDefaultMaxSockets + 1,
1143 client_socket_factory_.allocation_count());
1144 EXPECT_EQ(0, pool_->IdleSocketCount());
1145 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1146
1147 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541148 }
1149
[email protected]eb5a99382010-07-11 03:18:261150 EXPECT_EQ(1, pool_->IdleSocketCount());
1151}
[email protected]43a21b82010-06-10 21:30:541152
[email protected]eb5a99382010-07-11 03:18:261153TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1154 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1155 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541156
[email protected]eb5a99382010-07-11 03:18:261157 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101158 TestOldCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261159 {
1160 ClientSocketHandle handles[kDefaultMaxSockets];
1161 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101162 TestOldCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401163 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1164 "Take 2: %d", i),
1165 params_,
1166 kDefaultPriority,
1167 &callback,
1168 pool_.get(),
1169 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261170 }
1171
1172 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1173 EXPECT_EQ(0, pool_->IdleSocketCount());
1174
1175 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131176 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1177 params_,
1178 kDefaultPriority,
1179 &callback,
1180 pool_.get(),
1181 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261182
1183 // Dropping out of scope will close all handles and return them to idle.
1184 }
[email protected]43a21b82010-06-10 21:30:541185
1186 // But if we wait for it, the released idle sockets will be closed in
1187 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101188 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261189
1190 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1191 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541192}
1193
1194// Regression test for http://crbug.com/40952.
1195TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1196 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221197 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541198 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1199
1200 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1201 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101202 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131203 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1204 params_,
1205 kDefaultPriority,
1206 &callback,
1207 pool_.get(),
1208 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541209 }
1210
1211 // Flush all the DoReleaseSocket tasks.
1212 MessageLoop::current()->RunAllPending();
1213
1214 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1215 // reuse a socket.
1216 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1217 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101218 TestOldCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541219
1220 // "0" is special here, since it should be the first entry in the sorted map,
1221 // which is the one which we would close an idle socket for. We shouldn't
1222 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131223 EXPECT_EQ(OK, handle.Init("0",
1224 params_,
1225 kDefaultPriority,
1226 &callback,
1227 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211228 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541229
1230 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1231 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1232}
1233
[email protected]ab838892009-06-30 18:49:051234TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531235 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091236
[email protected]c9d6a1d2009-07-14 16:15:201237 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1238 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031239 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311240 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1241 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1242 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1243 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1244 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091245
[email protected]2431756e2010-09-29 20:26:131246 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091247
[email protected]c9d6a1d2009-07-14 16:15:201248 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1249 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131250 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1251 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091252
[email protected]c9d6a1d2009-07-14 16:15:201253 EXPECT_EQ(1, GetOrderOfRequest(1));
1254 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031255 EXPECT_EQ(8, GetOrderOfRequest(3));
1256 EXPECT_EQ(6, GetOrderOfRequest(4));
1257 EXPECT_EQ(4, GetOrderOfRequest(5));
1258 EXPECT_EQ(3, GetOrderOfRequest(6));
1259 EXPECT_EQ(5, GetOrderOfRequest(7));
1260 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171261
1262 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131263 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091264}
1265
[email protected]ab838892009-06-30 18:49:051266TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091268
[email protected]c9d6a1d2009-07-14 16:15:201269 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1270 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311271 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1272 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1273 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1274 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1275 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091276
[email protected]2431756e2010-09-29 20:26:131277 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091278
[email protected]2431756e2010-09-29 20:26:131279 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1280 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201281
[email protected]2431756e2010-09-29 20:26:131282 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201283 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131284 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1285 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091286}
1287
1288// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051289// The pending connect job will be cancelled and should not call back into
1290// ClientSocketPoolBase.
1291TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531292 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201293
[email protected]ab838892009-06-30 18:49:051294 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131295 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101296 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131297 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1298 params_,
1299 kDefaultPriority,
1300 &callback,
1301 pool_.get(),
1302 BoundNetLog()));
1303 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091304}
1305
[email protected]ab838892009-06-30 18:49:051306TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531307 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201308
[email protected]ab838892009-06-30 18:49:051309 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061310 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101311 TestOldCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091312
[email protected]2431756e2010-09-29 20:26:131313 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1314 params_,
1315 kDefaultPriority,
1316 &callback,
1317 pool_.get(),
1318 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091319
1320 handle.Reset();
1321
[email protected]f1f3f0f82011-10-01 20:38:101322 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131323 EXPECT_EQ(ERR_IO_PENDING,
1324 handle.Init("a",
1325 params_,
1326 kDefaultPriority,
1327 &callback2,
1328 pool_.get(),
1329 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091330
1331 EXPECT_EQ(OK, callback2.WaitForResult());
1332 EXPECT_FALSE(callback.have_result());
1333
1334 handle.Reset();
1335}
1336
[email protected]ab838892009-06-30 18:49:051337TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531338 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091339
[email protected]c9d6a1d2009-07-14 16:15:201340 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1341 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311342 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1343 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1344 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1345 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1346 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091347
1348 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201349 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131350 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1351 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091352
[email protected]2431756e2010-09-29 20:26:131353 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091354
[email protected]c9d6a1d2009-07-14 16:15:201355 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1356 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131357 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1358 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091359
[email protected]c9d6a1d2009-07-14 16:15:201360 EXPECT_EQ(1, GetOrderOfRequest(1));
1361 EXPECT_EQ(2, GetOrderOfRequest(2));
1362 EXPECT_EQ(5, GetOrderOfRequest(3));
1363 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131364 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1365 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201366 EXPECT_EQ(4, GetOrderOfRequest(6));
1367 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171368
1369 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131370 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091371}
1372
1373class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1374 public:
[email protected]2ab05b52009-07-01 23:57:581375 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241376 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581377 TestConnectJobFactory* test_connect_job_factory,
1378 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091379 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061380 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581381 within_callback_(false),
1382 test_connect_job_factory_(test_connect_job_factory),
1383 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091384
1385 virtual void RunWithParams(const Tuple1<int>& params) {
1386 callback_.RunWithParams(params);
1387 ASSERT_EQ(OK, params.a);
1388
1389 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581390 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111391
1392 // Don't allow reuse of the socket. Disconnect it and then release it and
1393 // run through the MessageLoop once to get it completely released.
1394 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091395 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111396 {
1397 MessageLoop::ScopedNestableTaskAllower nestable(
1398 MessageLoop::current());
1399 MessageLoop::current()->RunAllPending();
1400 }
[email protected]f6d1d6eb2009-06-24 20:16:091401 within_callback_ = true;
[email protected]f1f3f0f82011-10-01 20:38:101402 TestOldCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271403 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131404 int rv = handle_->Init("a",
1405 params,
1406 kDefaultPriority,
1407 &next_job_callback,
1408 pool_,
1409 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581410 switch (next_job_type_) {
1411 case TestConnectJob::kMockJob:
1412 EXPECT_EQ(OK, rv);
1413 break;
1414 case TestConnectJob::kMockPendingJob:
1415 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471416
1417 // For pending jobs, wait for new socket to be created. This makes
1418 // sure there are no more pending operations nor any unclosed sockets
1419 // when the test finishes.
1420 // We need to give it a little bit of time to run, so that all the
1421 // operations that happen on timers (e.g. cleanup of idle
1422 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111423 {
1424 MessageLoop::ScopedNestableTaskAllower nestable(
1425 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081426 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111427 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1428 }
[email protected]2ab05b52009-07-01 23:57:581429 break;
1430 default:
1431 FAIL() << "Unexpected job type: " << next_job_type_;
1432 break;
1433 }
[email protected]f6d1d6eb2009-06-24 20:16:091434 }
1435 }
1436
1437 int WaitForResult() {
1438 return callback_.WaitForResult();
1439 }
1440
1441 private:
1442 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131443 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091444 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581445 TestConnectJobFactory* const test_connect_job_factory_;
1446 TestConnectJob::JobType next_job_type_;
[email protected]f1f3f0f82011-10-01 20:38:101447 TestOldCompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091448};
1449
[email protected]2ab05b52009-07-01 23:57:581450TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531451 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201452
[email protected]0b7648c2009-07-06 20:14:011453 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061454 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581455 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061456 &handle, pool_.get(), connect_job_factory_,
1457 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131458 int rv = handle.Init("a",
1459 params_,
1460 kDefaultPriority,
1461 &callback,
1462 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211463 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091464 ASSERT_EQ(ERR_IO_PENDING, rv);
1465
1466 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581467}
[email protected]f6d1d6eb2009-06-24 20:16:091468
[email protected]2ab05b52009-07-01 23:57:581469TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531470 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201471
[email protected]0b7648c2009-07-06 20:14:011472 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061473 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581474 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061475 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131476 int rv = handle.Init("a",
1477 params_,
1478 kDefaultPriority,
1479 &callback,
1480 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211481 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581482 ASSERT_EQ(ERR_IO_PENDING, rv);
1483
1484 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091485}
1486
1487// Make sure that pending requests get serviced after active requests get
1488// cancelled.
[email protected]ab838892009-06-30 18:49:051489TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531490 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201491
[email protected]0b7648c2009-07-06 20:14:011492 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091493
[email protected]c9d6a1d2009-07-14 16:15:201494 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1495 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1496 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1497 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1498 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1499 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1500 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091501
[email protected]c9d6a1d2009-07-14 16:15:201502 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1503 // Let's cancel them.
1504 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131505 ASSERT_FALSE(request(i)->handle()->is_initialized());
1506 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091507 }
1508
[email protected]f6d1d6eb2009-06-24 20:16:091509 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131510 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1511 EXPECT_EQ(OK, request(i)->WaitForResult());
1512 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091513 }
1514
[email protected]2431756e2010-09-29 20:26:131515 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1516 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091517}
1518
1519// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051520TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531521 const size_t kMaxSockets = 5;
1522 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201523
[email protected]0b7648c2009-07-06 20:14:011524 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091525
[email protected]211d21722009-07-22 15:48:531526 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1527 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091528
1529 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531530 for (size_t i = 0; i < kNumberOfRequests; ++i)
1531 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091532
[email protected]211d21722009-07-22 15:48:531533 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131534 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091535}
1536
[email protected]5fc08e32009-07-15 17:09:571537TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531538 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571539
1540 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1541
[email protected]2431756e2010-09-29 20:26:131542 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101543 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131544 int rv = handle.Init("a",
1545 params_,
1546 kDefaultPriority,
1547 &callback,
1548 pool_.get(),
1549 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571550 EXPECT_EQ(ERR_IO_PENDING, rv);
1551
1552 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131553 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571554
[email protected]2431756e2010-09-29 20:26:131555 rv = handle.Init("a",
1556 params_,
1557 kDefaultPriority,
1558 &callback,
1559 pool_.get(),
1560 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571561 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131562 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571563
[email protected]2431756e2010-09-29 20:26:131564 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571565 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1566}
1567
[email protected]2b7523d2009-07-29 20:29:231568// Regression test for http://crbug.com/17985.
1569TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1570 const int kMaxSockets = 3;
1571 const int kMaxSocketsPerGroup = 2;
1572 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1573
[email protected]ac790b42009-12-02 04:31:311574 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231575
1576 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1577 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1578
1579 // This is going to be a pending request in an otherwise empty group.
1580 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1581
1582 // Reach the maximum socket limit.
1583 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1584
1585 // Create a stalled group with high priorities.
1586 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1587 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231588
[email protected]eb5a99382010-07-11 03:18:261589 // Release the first two sockets from "a". Because this is a keepalive,
1590 // the first release will unblock the pending request for "a". The
1591 // second release will unblock a request for "c", becaue it is the next
1592 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131593 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1594 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231595
1596 // Closing idle sockets should not get us into trouble, but in the bug
1597 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411598 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541599 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261600
1601 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231602}
1603
[email protected]4d3b05d2010-01-27 21:27:291604TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531605 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571606
1607 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131608 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101609 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531610 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131611 int rv = handle.Init("a",
1612 params_,
1613 LOWEST,
1614 &callback,
1615 pool_.get(),
1616 log.bound());
[email protected]5fc08e32009-07-15 17:09:571617 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131618 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1619 EXPECT_EQ(OK, callback.WaitForResult());
1620 EXPECT_TRUE(handle.is_initialized());
1621 EXPECT_TRUE(handle.socket());
1622 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301623
[email protected]b2fcd0e2010-12-01 15:19:401624 net::CapturingNetLog::EntryList entries;
1625 log.GetEntries(&entries);
1626
1627 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461628 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401629 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171630 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401631 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171632 NetLog::PHASE_NONE));
1633 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401634 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171635 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461636 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401637 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571638}
1639
[email protected]4d3b05d2010-01-27 21:27:291640TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571641 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571643
1644 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131645 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101646 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531647 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181648 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131649 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431650 HttpResponseInfo info;
1651 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131652 handle.set_ssl_error_response_info(info);
1653 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1654 params_,
1655 kDefaultPriority,
1656 &callback,
1657 pool_.get(),
1658 log.bound()));
1659 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1660 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1661 EXPECT_FALSE(handle.is_ssl_error());
1662 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301663
[email protected]b2fcd0e2010-12-01 15:19:401664 net::CapturingNetLog::EntryList entries;
1665 log.GetEntries(&entries);
1666
1667 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461668 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401669 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171670 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401671 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171672 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321673 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401674 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571675}
1676
[email protected]4d3b05d2010-01-27 21:27:291677TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101678 // TODO(eroman): Add back the log expectations! Removed them because the
1679 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531680 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571681
1682 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131683 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101684 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131685 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101686 TestOldCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571687
[email protected]2431756e2010-09-29 20:26:131688 EXPECT_EQ(ERR_IO_PENDING,
1689 handle.Init("a",
1690 params_,
1691 kDefaultPriority,
1692 &callback,
1693 pool_.get(),
1694 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531695 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131696 EXPECT_EQ(ERR_IO_PENDING,
1697 handle2.Init("a",
1698 params_,
1699 kDefaultPriority,
1700 &callback2,
1701 pool_.get(),
1702 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571703
[email protected]2431756e2010-09-29 20:26:131704 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571705
[email protected]fd7b7c92009-08-20 19:38:301706
1707 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301708
[email protected]2431756e2010-09-29 20:26:131709 EXPECT_EQ(OK, callback2.WaitForResult());
1710 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301711
1712 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531713 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571714}
1715
[email protected]4d3b05d2010-01-27 21:27:291716TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1718
[email protected]17a0c6c2009-08-04 00:07:041719 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1720
[email protected]ac790b42009-12-02 04:31:311721 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1722 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1723 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1724 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341725
1726 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131727 (*requests())[2]->handle()->Reset();
1728 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341729 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1730
[email protected]2431756e2010-09-29 20:26:131731 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341732 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1733
[email protected]2431756e2010-09-29 20:26:131734 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261735 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341736}
1737
[email protected]5fc08e32009-07-15 17:09:571738// When requests and ConnectJobs are not coupled, the request will get serviced
1739// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291740TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531741 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571742
1743 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321744 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571745
[email protected]2431756e2010-09-29 20:26:131746 std::vector<TestSocketRequest*> request_order;
1747 size_t completion_count; // unused
1748 TestSocketRequest req1(&request_order, &completion_count);
1749 int rv = req1.handle()->Init("a",
1750 params_,
1751 kDefaultPriority,
1752 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211753 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571754 EXPECT_EQ(ERR_IO_PENDING, rv);
1755 EXPECT_EQ(OK, req1.WaitForResult());
1756
1757 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1758 // without a job.
1759 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1760
[email protected]2431756e2010-09-29 20:26:131761 TestSocketRequest req2(&request_order, &completion_count);
1762 rv = req2.handle()->Init("a",
1763 params_,
1764 kDefaultPriority,
1765 &req2,
1766 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211767 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571768 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131769 TestSocketRequest req3(&request_order, &completion_count);
1770 rv = req3.handle()->Init("a",
1771 params_,
1772 kDefaultPriority,
1773 &req3,
1774 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211775 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571776 EXPECT_EQ(ERR_IO_PENDING, rv);
1777
1778 // Both Requests 2 and 3 are pending. We release socket 1 which should
1779 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331780 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261781 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331782 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571783 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331784 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571785
1786 // Signal job 2, which should service request 3.
1787
1788 client_socket_factory_.SignalJobs();
1789 EXPECT_EQ(OK, req3.WaitForResult());
1790
[email protected]2431756e2010-09-29 20:26:131791 ASSERT_EQ(3U, request_order.size());
1792 EXPECT_EQ(&req1, request_order[0]);
1793 EXPECT_EQ(&req2, request_order[1]);
1794 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571795 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1796}
1797
1798// The requests are not coupled to the jobs. So, the requests should finish in
1799// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291800TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531801 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571802 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321803 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571804
[email protected]2431756e2010-09-29 20:26:131805 std::vector<TestSocketRequest*> request_order;
1806 size_t completion_count; // unused
1807 TestSocketRequest req1(&request_order, &completion_count);
1808 int rv = req1.handle()->Init("a",
1809 params_,
1810 kDefaultPriority,
1811 &req1,
1812 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211813 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571814 EXPECT_EQ(ERR_IO_PENDING, rv);
1815
[email protected]2431756e2010-09-29 20:26:131816 TestSocketRequest req2(&request_order, &completion_count);
1817 rv = req2.handle()->Init("a",
1818 params_,
1819 kDefaultPriority,
1820 &req2,
1821 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211822 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571823 EXPECT_EQ(ERR_IO_PENDING, rv);
1824
1825 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321826 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571827
[email protected]2431756e2010-09-29 20:26:131828 TestSocketRequest req3(&request_order, &completion_count);
1829 rv = req3.handle()->Init("a",
1830 params_,
1831 kDefaultPriority,
1832 &req3,
1833 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211834 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571835 EXPECT_EQ(ERR_IO_PENDING, rv);
1836
1837 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1838 EXPECT_EQ(OK, req2.WaitForResult());
1839 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1840
[email protected]2431756e2010-09-29 20:26:131841 ASSERT_EQ(3U, request_order.size());
1842 EXPECT_EQ(&req1, request_order[0]);
1843 EXPECT_EQ(&req2, request_order[1]);
1844 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571845}
1846
[email protected]e6ec67b2010-06-16 00:12:461847TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531848 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571849 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321850 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571851
[email protected]2431756e2010-09-29 20:26:131852 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101853 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131854 int rv = handle.Init("a",
1855 params_,
1856 kDefaultPriority,
1857 &callback,
1858 pool_.get(),
1859 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571860 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131861 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571862
1863 MessageLoop::current()->RunAllPending();
1864
[email protected]2431756e2010-09-29 20:26:131865 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101866 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131867 rv = handle2.Init("a",
1868 params_,
1869 kDefaultPriority,
1870 &callback2, pool_.get(),
1871 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571872 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131873 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1874 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571875}
1876
[email protected]e772db3f2010-07-12 18:11:131877TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1878 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1879 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1880
[email protected]2431756e2010-09-29 20:26:131881 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101882 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131883 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1884 params_,
1885 kDefaultPriority,
1886 &callback, pool_.get(),
1887 BoundNetLog()));
1888 EXPECT_TRUE(handle.is_initialized());
1889 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131890}
1891
1892TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1893 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1894
1895 connect_job_factory_->set_job_type(
1896 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131897 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101898 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131899 EXPECT_EQ(ERR_IO_PENDING,
1900 handle.Init("a",
1901 params_,
1902 kDefaultPriority,
1903 &callback,
1904 pool_.get(),
1905 BoundNetLog()));
1906 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1907 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1908 EXPECT_TRUE(handle.is_initialized());
1909 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131910}
1911
[email protected]e60e47a2010-07-14 03:37:181912TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1913 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1914 connect_job_factory_->set_job_type(
1915 TestConnectJob::kMockAdditionalErrorStateJob);
1916
[email protected]2431756e2010-09-29 20:26:131917 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101918 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131919 EXPECT_EQ(ERR_CONNECTION_FAILED,
1920 handle.Init("a",
1921 params_,
1922 kDefaultPriority,
1923 &callback,
1924 pool_.get(),
1925 BoundNetLog()));
1926 EXPECT_FALSE(handle.is_initialized());
1927 EXPECT_FALSE(handle.socket());
1928 EXPECT_TRUE(handle.is_ssl_error());
1929 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181930}
1931
1932TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1933 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1934
1935 connect_job_factory_->set_job_type(
1936 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131937 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101938 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131939 EXPECT_EQ(ERR_IO_PENDING,
1940 handle.Init("a",
1941 params_,
1942 kDefaultPriority,
1943 &callback,
1944 pool_.get(),
1945 BoundNetLog()));
1946 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1947 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1948 EXPECT_FALSE(handle.is_initialized());
1949 EXPECT_FALSE(handle.socket());
1950 EXPECT_TRUE(handle.is_ssl_error());
1951 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181952}
1953
[email protected]64770b7d2011-11-16 04:30:411954TEST_F(ClientSocketPoolBaseTest, DisableCleanupTimer) {
1955 // Disable cleanup timer.
1956 internal::ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(false);
1957
1958 CreatePoolWithIdleTimeouts(
1959 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1960 base::TimeDelta::FromMilliseconds(10), // Time out unused sockets
1961 base::TimeDelta::FromMilliseconds(10)); // Time out used sockets
1962
1963 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1964
1965 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1966
1967 ClientSocketHandle handle;
1968 TestOldCompletionCallback callback;
1969 int rv = handle.Init("a",
1970 params_,
1971 LOWEST,
1972 &callback,
1973 pool_.get(),
1974 BoundNetLog());
1975 EXPECT_EQ(ERR_IO_PENDING, rv);
1976 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1977
1978 ClientSocketHandle handle2;
1979 TestOldCompletionCallback callback2;
1980 rv = handle2.Init("a",
1981 params_,
1982 LOWEST,
1983 &callback2,
1984 pool_.get(),
1985 BoundNetLog());
1986 EXPECT_EQ(ERR_IO_PENDING, rv);
1987 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
1988
1989 // Cancel one of the requests. Wait for the other, which will get the first
1990 // job. Release the socket. Run the loop again to make sure the second
1991 // socket is sitting idle and the first one is released (since ReleaseSocket()
1992 // just posts a DoReleaseSocket() task).
1993
1994 handle.Reset();
1995 EXPECT_EQ(OK, callback2.WaitForResult());
1996 // Use the socket.
1997 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1998 handle2.Reset();
1999
2000 // The idle socket timeout value was set to 10 milliseconds. Wait 20
2001 // milliseconds so the sockets timeout.
2002 base::PlatformThread::Sleep(20);
2003 MessageLoop::current()->RunAllPending();
2004
2005 ASSERT_EQ(2, pool_->IdleSocketCount());
2006
2007 // Request a new socket. This should cleanup the unused and timed out ones.
2008 // A new socket will be created rather than reusing the idle one.
2009 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2010 rv = handle.Init("a",
2011 params_,
2012 LOWEST,
2013 &callback,
2014 pool_.get(),
2015 log.bound());
2016 EXPECT_EQ(ERR_IO_PENDING, rv);
2017 EXPECT_EQ(OK, callback.WaitForResult());
2018 EXPECT_FALSE(handle.is_reused());
2019
2020 // Make sure the idle socket is closed
2021 ASSERT_TRUE(pool_->HasGroup("a"));
2022 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2023 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2024
2025 net::CapturingNetLog::EntryList entries;
2026 log.GetEntries(&entries);
2027 EXPECT_FALSE(LogContainsEntryWithType(
2028 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
2029}
2030
[email protected]4d3b05d2010-01-27 21:27:292031TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:162032 CreatePoolWithIdleTimeouts(
2033 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2034 base::TimeDelta(), // Time out unused sockets immediately.
2035 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2036
2037 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2038
2039 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
2040
[email protected]2431756e2010-09-29 20:26:132041 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102042 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132043 int rv = handle.Init("a",
2044 params_,
2045 LOWEST,
2046 &callback,
2047 pool_.get(),
2048 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162049 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132050 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:162051
[email protected]2431756e2010-09-29 20:26:132052 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102053 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132054 rv = handle2.Init("a",
2055 params_,
2056 LOWEST,
2057 &callback2,
2058 pool_.get(),
2059 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:162060 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:132061 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:162062
2063 // Cancel one of the requests. Wait for the other, which will get the first
2064 // job. Release the socket. Run the loop again to make sure the second
2065 // socket is sitting idle and the first one is released (since ReleaseSocket()
2066 // just posts a DoReleaseSocket() task).
2067
[email protected]2431756e2010-09-29 20:26:132068 handle.Reset();
2069 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:012070 // Use the socket.
[email protected]2431756e2010-09-29 20:26:132071 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
2072 handle2.Reset();
[email protected]6b175382009-10-13 06:47:472073
2074 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
2075 // actually become pending until 2ms after they have been created. In order
2076 // to flush all tasks, we need to wait so that we know there are no
2077 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:082078 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:162079 MessageLoop::current()->RunAllPending();
2080
2081 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042082
[email protected]9bf28db2009-08-29 01:35:162083 // Invoke the idle socket cleanup check. Only one socket should be left, the
2084 // used socket. Request it to make sure that it's used.
2085
2086 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532087 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132088 rv = handle.Init("a",
2089 params_,
2090 LOWEST,
2091 &callback,
2092 pool_.get(),
2093 log.bound());
[email protected]9bf28db2009-08-29 01:35:162094 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132095 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402096
2097 net::CapturingNetLog::EntryList entries;
2098 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152099 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402100 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162101}
2102
[email protected]2041cf342010-02-19 03:15:592103// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162104// because of multiple releasing disconnected sockets.
2105TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2106 CreatePoolWithIdleTimeouts(
2107 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2108 base::TimeDelta(), // Time out unused sockets immediately.
2109 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2110
2111 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2112
2113 // Startup 4 connect jobs. Two of them will be pending.
2114
[email protected]2431756e2010-09-29 20:26:132115 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102116 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132117 int rv = handle.Init("a",
2118 params_,
2119 LOWEST,
2120 &callback,
2121 pool_.get(),
2122 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162123 EXPECT_EQ(OK, rv);
2124
[email protected]2431756e2010-09-29 20:26:132125 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102126 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132127 rv = handle2.Init("a",
2128 params_,
2129 LOWEST,
2130 &callback2,
2131 pool_.get(),
2132 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162133 EXPECT_EQ(OK, rv);
2134
[email protected]2431756e2010-09-29 20:26:132135 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102136 TestOldCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132137 rv = handle3.Init("a",
2138 params_,
2139 LOWEST,
2140 &callback3,
2141 pool_.get(),
2142 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162143 EXPECT_EQ(ERR_IO_PENDING, rv);
2144
[email protected]2431756e2010-09-29 20:26:132145 ClientSocketHandle handle4;
[email protected]f1f3f0f82011-10-01 20:38:102146 TestOldCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132147 rv = handle4.Init("a",
2148 params_,
2149 LOWEST,
2150 &callback4,
2151 pool_.get(),
2152 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162153 EXPECT_EQ(ERR_IO_PENDING, rv);
2154
2155 // Release two disconnected sockets.
2156
[email protected]2431756e2010-09-29 20:26:132157 handle.socket()->Disconnect();
2158 handle.Reset();
2159 handle2.socket()->Disconnect();
2160 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162161
[email protected]2431756e2010-09-29 20:26:132162 EXPECT_EQ(OK, callback3.WaitForResult());
2163 EXPECT_FALSE(handle3.is_reused());
2164 EXPECT_EQ(OK, callback4.WaitForResult());
2165 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162166}
2167
[email protected]d7027bb2010-05-10 18:58:542168// Regression test for http://crbug.com/42267.
2169// When DoReleaseSocket() is processed for one socket, it is blocked because the
2170// other stalled groups all have releasing sockets, so no progress can be made.
2171TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2172 CreatePoolWithIdleTimeouts(
2173 4 /* socket limit */, 4 /* socket limit per group */,
2174 base::TimeDelta(), // Time out unused sockets immediately.
2175 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2176
2177 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2178
2179 // Max out the socket limit with 2 per group.
2180
[email protected]2431756e2010-09-29 20:26:132181 ClientSocketHandle handle_a[4];
[email protected]f1f3f0f82011-10-01 20:38:102182 TestOldCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132183 ClientSocketHandle handle_b[4];
[email protected]f1f3f0f82011-10-01 20:38:102184 TestOldCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542185
2186 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132187 EXPECT_EQ(OK, handle_a[i].Init("a",
2188 params_,
2189 LOWEST,
2190 &callback_a[i],
2191 pool_.get(),
2192 BoundNetLog()));
2193 EXPECT_EQ(OK, handle_b[i].Init("b",
2194 params_,
2195 LOWEST,
2196 &callback_b[i],
2197 pool_.get(),
2198 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542199 }
[email protected]b89f7e42010-05-20 20:37:002200
[email protected]d7027bb2010-05-10 18:58:542201 // Make 4 pending requests, 2 per group.
2202
2203 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132204 EXPECT_EQ(ERR_IO_PENDING,
2205 handle_a[i].Init("a",
2206 params_,
2207 LOWEST,
2208 &callback_a[i],
2209 pool_.get(),
2210 BoundNetLog()));
2211 EXPECT_EQ(ERR_IO_PENDING,
2212 handle_b[i].Init("b",
2213 params_,
2214 LOWEST,
2215 &callback_b[i],
2216 pool_.get(),
2217 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542218 }
2219
2220 // Release b's socket first. The order is important, because in
2221 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2222 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2223 // first, which has a releasing socket, so it refuses to start up another
2224 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132225 handle_b[0].socket()->Disconnect();
2226 handle_b[0].Reset();
2227 handle_a[0].socket()->Disconnect();
2228 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542229
2230 // Used to get stuck here.
2231 MessageLoop::current()->RunAllPending();
2232
[email protected]2431756e2010-09-29 20:26:132233 handle_b[1].socket()->Disconnect();
2234 handle_b[1].Reset();
2235 handle_a[1].socket()->Disconnect();
2236 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542237
2238 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132239 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2240 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542241 }
2242}
2243
[email protected]fd4fe0b2010-02-08 23:02:152244TEST_F(ClientSocketPoolBaseTest,
2245 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2246 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2247
2248 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2249
2250 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2251 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2252 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2253 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2254
[email protected]2431756e2010-09-29 20:26:132255 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2256 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2257 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152258
2259 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132260 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2261 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152262
[email protected]2431756e2010-09-29 20:26:132263 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2264 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2265 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152266
2267 EXPECT_EQ(1, GetOrderOfRequest(1));
2268 EXPECT_EQ(2, GetOrderOfRequest(2));
2269 EXPECT_EQ(3, GetOrderOfRequest(3));
2270 EXPECT_EQ(4, GetOrderOfRequest(4));
2271
2272 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132273 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152274}
2275
[email protected]4f1e4982010-03-02 18:31:042276class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2277 public:
[email protected]2431756e2010-09-29 20:26:132278 TestReleasingSocketRequest(TestClientSocketPool* pool,
2279 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182280 bool reset_releasing_handle)
2281 : pool_(pool),
2282 expected_result_(expected_result),
2283 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042284
2285 ClientSocketHandle* handle() { return &handle_; }
2286
2287 int WaitForResult() {
2288 return callback_.WaitForResult();
2289 }
2290
2291 virtual void RunWithParams(const Tuple1<int>& params) {
2292 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182293 if (reset_releasing_handle_)
2294 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272295 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132296 EXPECT_EQ(expected_result_, handle2_.Init("a",
2297 con_params,
2298 kDefaultPriority,
2299 &callback2_,
2300 pool_,
[email protected]e60e47a2010-07-14 03:37:182301 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042302 }
2303
2304 private:
[email protected]2431756e2010-09-29 20:26:132305 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182306 int expected_result_;
2307 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042308 ClientSocketHandle handle_;
2309 ClientSocketHandle handle2_;
[email protected]f1f3f0f82011-10-01 20:38:102310 TestOldCompletionCallback callback_;
2311 TestOldCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042312};
2313
[email protected]e60e47a2010-07-14 03:37:182314
2315TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2316 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2317
2318 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2319 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2320 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2321
[email protected]2431756e2010-09-29 20:26:132322 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182323 client_socket_factory_.allocation_count());
2324
2325 connect_job_factory_->set_job_type(
2326 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2327 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132328 EXPECT_EQ(ERR_IO_PENDING,
2329 req.handle()->Init("a",
2330 params_,
2331 kDefaultPriority,
2332 &req,
2333 pool_.get(),
2334 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182335 // The next job should complete synchronously
2336 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2337
2338 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2339 EXPECT_FALSE(req.handle()->is_initialized());
2340 EXPECT_FALSE(req.handle()->socket());
2341 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432342 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182343}
2344
[email protected]b6501d3d2010-06-03 23:53:342345// http://crbug.com/44724 regression test.
2346// We start releasing the pool when we flush on network change. When that
2347// happens, the only active references are in the ClientSocketHandles. When a
2348// ConnectJob completes and calls back into the last ClientSocketHandle, that
2349// callback can release the last reference and delete the pool. After the
2350// callback finishes, we go back to the stack frame within the now-deleted pool.
2351// Executing any code that refers to members of the now-deleted pool can cause
2352// crashes.
2353TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2354 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2355 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2356
2357 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102358 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132359 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2360 params_,
2361 kDefaultPriority,
2362 &callback,
2363 pool_.get(),
2364 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342365
[email protected]2431756e2010-09-29 20:26:132366 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342367
2368 // We'll call back into this now.
2369 callback.WaitForResult();
2370}
2371
[email protected]a7e38572010-06-07 18:22:242372TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2373 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2374 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2375
2376 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102377 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132378 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2379 params_,
2380 kDefaultPriority,
2381 &callback,
2382 pool_.get(),
2383 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242384 EXPECT_EQ(OK, callback.WaitForResult());
2385 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2386
2387 pool_->Flush();
2388
2389 handle.Reset();
2390 MessageLoop::current()->RunAllPending();
2391
[email protected]2431756e2010-09-29 20:26:132392 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2393 params_,
2394 kDefaultPriority,
2395 &callback,
2396 pool_.get(),
2397 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242398 EXPECT_EQ(OK, callback.WaitForResult());
2399 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2400}
2401
[email protected]06f92462010-08-31 19:24:142402class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2403 public:
2404 ConnectWithinCallback(
2405 const std::string& group_name,
2406 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132407 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142408 : group_name_(group_name), params_(params), pool_(pool) {}
2409
2410 ~ConnectWithinCallback() {}
2411
2412 virtual void RunWithParams(const Tuple1<int>& params) {
2413 callback_.RunWithParams(params);
2414 EXPECT_EQ(ERR_IO_PENDING,
2415 handle_.Init(group_name_,
2416 params_,
2417 kDefaultPriority,
2418 &nested_callback_,
2419 pool_,
2420 BoundNetLog()));
2421 }
2422
2423 int WaitForResult() {
2424 return callback_.WaitForResult();
2425 }
2426
2427 int WaitForNestedResult() {
2428 return nested_callback_.WaitForResult();
2429 }
2430
2431 private:
2432 const std::string group_name_;
2433 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132434 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142435 ClientSocketHandle handle_;
[email protected]f1f3f0f82011-10-01 20:38:102436 TestOldCompletionCallback callback_;
2437 TestOldCompletionCallback nested_callback_;
[email protected]06f92462010-08-31 19:24:142438};
2439
2440TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2441 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2442
2443 // First job will be waiting until it gets aborted.
2444 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2445
2446 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132447 ConnectWithinCallback callback("a", params_, pool_.get());
2448 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2449 params_,
2450 kDefaultPriority,
2451 &callback,
2452 pool_.get(),
2453 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142454
2455 // Second job will be started during the first callback, and will
2456 // asynchronously complete with OK.
2457 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2458 pool_->Flush();
2459 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2460 EXPECT_EQ(OK, callback.WaitForNestedResult());
2461}
2462
[email protected]25eea382010-07-10 23:55:262463// Cancel a pending socket request while we're at max sockets,
2464// and verify that the backup socket firing doesn't cause a crash.
2465TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2466 // Max 4 sockets globally, max 4 sockets per group.
2467 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222468 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262469
[email protected]4baaf9d2010-08-31 15:15:442470 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2471 // timer.
[email protected]25eea382010-07-10 23:55:262472 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2473 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102474 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132475 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2476 params_,
2477 kDefaultPriority,
2478 &callback,
2479 pool_.get(),
2480 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262481
2482 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2483 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2484 ClientSocketHandle handles[kDefaultMaxSockets];
2485 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:102486 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132487 EXPECT_EQ(OK, handles[i].Init("bar",
2488 params_,
2489 kDefaultPriority,
2490 &callback,
2491 pool_.get(),
2492 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262493 }
2494
2495 MessageLoop::current()->RunAllPending();
2496
2497 // Cancel the pending request.
2498 handle.Reset();
2499
2500 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082501 base::PlatformThread::Sleep(
2502 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262503
2504 MessageLoop::current()->RunAllPending();
2505 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2506}
2507
[email protected]3f00be82010-09-27 19:50:022508TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442509 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2510 pool_->EnableConnectBackupJobs();
2511
2512 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2513 // timer.
2514 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2515 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102516 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132517 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2518 params_,
2519 kDefaultPriority,
2520 &callback,
2521 pool_.get(),
2522 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442523 ASSERT_TRUE(pool_->HasGroup("bar"));
2524 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2525
2526 // Cancel the socket request. This should cancel the backup timer. Wait for
2527 // the backup time to see if it indeed got canceled.
2528 handle.Reset();
2529 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082530 base::PlatformThread::Sleep(
2531 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442532 MessageLoop::current()->RunAllPending();
2533 ASSERT_TRUE(pool_->HasGroup("bar"));
2534 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2535}
2536
[email protected]3f00be82010-09-27 19:50:022537TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2538 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2539 pool_->EnableConnectBackupJobs();
2540
2541 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2542 // timer.
2543 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2544 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102545 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132546 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2547 params_,
2548 kDefaultPriority,
2549 &callback,
2550 pool_.get(),
2551 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022552 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2553 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102554 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132555 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2556 params_,
2557 kDefaultPriority,
2558 &callback2,
2559 pool_.get(),
2560 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022561 ASSERT_TRUE(pool_->HasGroup("bar"));
2562 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2563
2564 // Cancel request 1 and then complete request 2. With the requests finished,
2565 // the backup timer should be cancelled.
2566 handle.Reset();
2567 EXPECT_EQ(OK, callback2.WaitForResult());
2568 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082569 base::PlatformThread::Sleep(
2570 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022571 MessageLoop::current()->RunAllPending();
2572}
2573
[email protected]eb5a99382010-07-11 03:18:262574// Test delayed socket binding for the case where we have two connects,
2575// and while one is waiting on a connect, the other frees up.
2576// The socket waiting on a connect should switch immediately to the freed
2577// up socket.
2578TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2579 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2580 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2581
2582 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102583 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132584 EXPECT_EQ(ERR_IO_PENDING,
2585 handle1.Init("a",
2586 params_,
2587 kDefaultPriority,
2588 &callback,
2589 pool_.get(),
2590 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262591 EXPECT_EQ(OK, callback.WaitForResult());
2592
2593 // No idle sockets, no pending jobs.
2594 EXPECT_EQ(0, pool_->IdleSocketCount());
2595 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2596
2597 // Create a second socket to the same host, but this one will wait.
2598 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2599 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132600 EXPECT_EQ(ERR_IO_PENDING,
2601 handle2.Init("a",
2602 params_,
2603 kDefaultPriority,
2604 &callback,
2605 pool_.get(),
2606 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262607 // No idle sockets, and one connecting job.
2608 EXPECT_EQ(0, pool_->IdleSocketCount());
2609 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2610
2611 // Return the first handle to the pool. This will initiate the delayed
2612 // binding.
2613 handle1.Reset();
2614
2615 MessageLoop::current()->RunAllPending();
2616
2617 // Still no idle sockets, still one pending connect job.
2618 EXPECT_EQ(0, pool_->IdleSocketCount());
2619 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2620
2621 // The second socket connected, even though it was a Waiting Job.
2622 EXPECT_EQ(OK, callback.WaitForResult());
2623
2624 // And we can see there is still one job waiting.
2625 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2626
2627 // Finally, signal the waiting Connect.
2628 client_socket_factory_.SignalJobs();
2629 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2630
2631 MessageLoop::current()->RunAllPending();
2632}
2633
2634// Test delayed socket binding when a group is at capacity and one
2635// of the group's sockets frees up.
2636TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2637 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2638 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2639
2640 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102641 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132642 EXPECT_EQ(ERR_IO_PENDING,
2643 handle1.Init("a",
2644 params_,
2645 kDefaultPriority,
2646 &callback,
2647 pool_.get(),
2648 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262649 EXPECT_EQ(OK, callback.WaitForResult());
2650
2651 // No idle sockets, no pending jobs.
2652 EXPECT_EQ(0, pool_->IdleSocketCount());
2653 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2654
2655 // Create a second socket to the same host, but this one will wait.
2656 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2657 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132658 EXPECT_EQ(ERR_IO_PENDING,
2659 handle2.Init("a",
2660 params_,
2661 kDefaultPriority,
2662 &callback,
2663 pool_.get(),
2664 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262665 // No idle sockets, and one connecting job.
2666 EXPECT_EQ(0, pool_->IdleSocketCount());
2667 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2668
2669 // Return the first handle to the pool. This will initiate the delayed
2670 // binding.
2671 handle1.Reset();
2672
2673 MessageLoop::current()->RunAllPending();
2674
2675 // Still no idle sockets, still one pending connect job.
2676 EXPECT_EQ(0, pool_->IdleSocketCount());
2677 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2678
2679 // The second socket connected, even though it was a Waiting Job.
2680 EXPECT_EQ(OK, callback.WaitForResult());
2681
2682 // And we can see there is still one job waiting.
2683 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2684
2685 // Finally, signal the waiting Connect.
2686 client_socket_factory_.SignalJobs();
2687 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2688
2689 MessageLoop::current()->RunAllPending();
2690}
2691
2692// Test out the case where we have one socket connected, one
2693// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512694// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262695// should complete, by taking the first socket's idle socket.
2696TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2697 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2698 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2699
2700 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102701 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132702 EXPECT_EQ(ERR_IO_PENDING,
2703 handle1.Init("a",
2704 params_,
2705 kDefaultPriority,
2706 &callback,
2707 pool_.get(),
2708 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262709 EXPECT_EQ(OK, callback.WaitForResult());
2710
2711 // No idle sockets, no pending jobs.
2712 EXPECT_EQ(0, pool_->IdleSocketCount());
2713 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2714
2715 // Create a second socket to the same host, but this one will wait.
2716 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2717 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132718 EXPECT_EQ(ERR_IO_PENDING,
2719 handle2.Init("a",
2720 params_,
2721 kDefaultPriority,
2722 &callback,
2723 pool_.get(),
2724 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262725 // No idle sockets, and one connecting job.
2726 EXPECT_EQ(0, pool_->IdleSocketCount());
2727 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2728
2729 // Return the first handle to the pool. This will initiate the delayed
2730 // binding.
2731 handle1.Reset();
2732
2733 MessageLoop::current()->RunAllPending();
2734
2735 // Still no idle sockets, still one pending connect job.
2736 EXPECT_EQ(0, pool_->IdleSocketCount());
2737 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2738
2739 // The second socket connected, even though it was a Waiting Job.
2740 EXPECT_EQ(OK, callback.WaitForResult());
2741
2742 // And we can see there is still one job waiting.
2743 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2744
2745 // Finally, signal the waiting Connect.
2746 client_socket_factory_.SignalJobs();
2747 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2748
2749 MessageLoop::current()->RunAllPending();
2750}
2751
[email protected]2abfe90a2010-08-25 17:49:512752// Cover the case where on an available socket slot, we have one pending
2753// request that completes synchronously, thereby making the Group empty.
2754TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2755 const int kUnlimitedSockets = 100;
2756 const int kOneSocketPerGroup = 1;
2757 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2758
2759 // Make the first request asynchronous fail.
2760 // This will free up a socket slot later.
2761 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2762
2763 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102764 TestOldCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132765 EXPECT_EQ(ERR_IO_PENDING,
2766 handle1.Init("a",
2767 params_,
2768 kDefaultPriority,
2769 &callback1,
2770 pool_.get(),
2771 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512772 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2773
2774 // Make the second request synchronously fail. This should make the Group
2775 // empty.
2776 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2777 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102778 TestOldCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512779 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2780 // when created.
[email protected]2431756e2010-09-29 20:26:132781 EXPECT_EQ(ERR_IO_PENDING,
2782 handle2.Init("a",
2783 params_,
2784 kDefaultPriority,
2785 &callback2,
2786 pool_.get(),
2787 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512788
2789 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2790
2791 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2792 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2793 EXPECT_FALSE(pool_->HasGroup("a"));
2794}
2795
[email protected]e1b54dc2010-10-06 21:27:222796TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2797 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2798
2799 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2800
2801 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102802 TestOldCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222803 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2804 params_,
2805 kDefaultPriority,
2806 &callback1,
2807 pool_.get(),
2808 BoundNetLog()));
2809
2810 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102811 TestOldCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222812 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2813 params_,
2814 kDefaultPriority,
2815 &callback2,
2816 pool_.get(),
2817 BoundNetLog()));
2818 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102819 TestOldCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222820 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2821 params_,
2822 kDefaultPriority,
2823 &callback3,
2824 pool_.get(),
2825 BoundNetLog()));
2826
2827 EXPECT_EQ(OK, callback1.WaitForResult());
2828 EXPECT_EQ(OK, callback2.WaitForResult());
2829 EXPECT_EQ(OK, callback3.WaitForResult());
2830
2831 // Use the socket.
2832 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2833 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2834
2835 handle1.Reset();
2836 handle2.Reset();
2837 handle3.Reset();
2838
2839 EXPECT_EQ(OK, handle1.Init("a",
2840 params_,
2841 kDefaultPriority,
2842 &callback1,
2843 pool_.get(),
2844 BoundNetLog()));
2845 EXPECT_EQ(OK, handle2.Init("a",
2846 params_,
2847 kDefaultPriority,
2848 &callback2,
2849 pool_.get(),
2850 BoundNetLog()));
2851 EXPECT_EQ(OK, handle3.Init("a",
2852 params_,
2853 kDefaultPriority,
2854 &callback3,
2855 pool_.get(),
2856 BoundNetLog()));
2857
2858 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2859 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2860 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2861}
2862
[email protected]2c2bef152010-10-13 00:55:032863TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2864 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2865 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2866
2867 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2868
2869 ASSERT_TRUE(pool_->HasGroup("a"));
2870 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2871 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2872
2873 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102874 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032875 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2876 params_,
2877 kDefaultPriority,
2878 &callback1,
2879 pool_.get(),
2880 BoundNetLog()));
2881
2882 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102883 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032884 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2885 params_,
2886 kDefaultPriority,
2887 &callback2,
2888 pool_.get(),
2889 BoundNetLog()));
2890
2891 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2892 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2893
2894 EXPECT_EQ(OK, callback1.WaitForResult());
2895 EXPECT_EQ(OK, callback2.WaitForResult());
2896 handle1.Reset();
2897 handle2.Reset();
2898
2899 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2900 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2901}
2902
2903TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2904 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2906
2907 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102908 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032909 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2910 params_,
2911 kDefaultPriority,
2912 &callback1,
2913 pool_.get(),
2914 BoundNetLog()));
2915
2916 ASSERT_TRUE(pool_->HasGroup("a"));
2917 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2918 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2919
2920 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2921
2922 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2923 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2924
2925 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102926 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032927 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2928 params_,
2929 kDefaultPriority,
2930 &callback2,
2931 pool_.get(),
2932 BoundNetLog()));
2933
2934 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2935 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2936
2937 EXPECT_EQ(OK, callback1.WaitForResult());
2938 EXPECT_EQ(OK, callback2.WaitForResult());
2939 handle1.Reset();
2940 handle2.Reset();
2941
2942 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2943 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2944}
2945
2946TEST_F(ClientSocketPoolBaseTest,
2947 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2948 CreatePool(4, 4);
2949 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2950
2951 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102952 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032953 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2954 params_,
2955 kDefaultPriority,
2956 &callback1,
2957 pool_.get(),
2958 BoundNetLog()));
2959
2960 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102961 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032962 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2963 params_,
2964 kDefaultPriority,
2965 &callback2,
2966 pool_.get(),
2967 BoundNetLog()));
2968
2969 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102970 TestOldCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:032971 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2972 params_,
2973 kDefaultPriority,
2974 &callback3,
2975 pool_.get(),
2976 BoundNetLog()));
2977
2978 ASSERT_TRUE(pool_->HasGroup("a"));
2979 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2980 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2981
2982 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2983
2984 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2985 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2986
2987 EXPECT_EQ(OK, callback1.WaitForResult());
2988 EXPECT_EQ(OK, callback2.WaitForResult());
2989 EXPECT_EQ(OK, callback3.WaitForResult());
2990 handle1.Reset();
2991 handle2.Reset();
2992 handle3.Reset();
2993
2994 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2995 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2996}
2997
2998TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2999 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3000 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3001
3002 ASSERT_FALSE(pool_->HasGroup("a"));
3003
3004 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
3005 BoundNetLog());
3006
3007 ASSERT_TRUE(pool_->HasGroup("a"));
3008 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
3009
3010 ASSERT_FALSE(pool_->HasGroup("b"));
3011
3012 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3013 BoundNetLog());
3014
3015 ASSERT_FALSE(pool_->HasGroup("b"));
3016}
3017
3018TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
3019 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3020 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3021
3022 ASSERT_FALSE(pool_->HasGroup("a"));
3023
3024 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3025 BoundNetLog());
3026
3027 ASSERT_TRUE(pool_->HasGroup("a"));
3028 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3029
3030 ASSERT_FALSE(pool_->HasGroup("b"));
3031
3032 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3033 BoundNetLog());
3034
3035 ASSERT_TRUE(pool_->HasGroup("b"));
3036 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3037}
3038
3039TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3040 CreatePool(4, 4);
3041 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3042
3043 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103044 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033045 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3046 params_,
3047 kDefaultPriority,
3048 &callback1,
3049 pool_.get(),
3050 BoundNetLog()));
3051 ASSERT_EQ(OK, callback1.WaitForResult());
3052 handle1.Reset();
3053
3054 ASSERT_TRUE(pool_->HasGroup("a"));
3055 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3056 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3057
3058 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3059
3060 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3061 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3062}
3063
3064TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
3065 CreatePool(4, 4);
3066 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3067
3068 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103069 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033070 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3071 params_,
3072 kDefaultPriority,
3073 &callback1,
3074 pool_.get(),
3075 BoundNetLog()));
3076 ASSERT_EQ(OK, callback1.WaitForResult());
3077
3078 ASSERT_TRUE(pool_->HasGroup("a"));
3079 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3080 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3081 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3082
3083 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3084
3085 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3086 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3087 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3088}
3089
3090TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3091 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3092 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3093
3094 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3095 BoundNetLog());
3096
3097 ASSERT_TRUE(pool_->HasGroup("a"));
3098 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3099 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3100
3101 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3102 BoundNetLog());
3103
3104 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3105 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3106}
3107
[email protected]3c819f522010-12-02 02:03:123108TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3109 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3110 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3111
3112 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3113 BoundNetLog());
3114
3115 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523116
3117 connect_job_factory_->set_job_type(
3118 TestConnectJob::kMockAdditionalErrorStateJob);
3119 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3120 BoundNetLog());
3121
3122 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123123}
3124
[email protected]2c2bef152010-10-13 00:55:033125TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3126 CreatePool(4, 4);
3127 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3128
3129 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3130
3131 ASSERT_TRUE(pool_->HasGroup("a"));
3132 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3133 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3134
3135 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3136 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3137 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3138
3139 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103140 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033141 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3142 params_,
3143 kDefaultPriority,
3144 &callback1,
3145 pool_.get(),
3146 BoundNetLog()));
3147 ASSERT_EQ(OK, callback1.WaitForResult());
3148
3149 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103150 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033151 int rv = handle2.Init("a",
3152 params_,
3153 kDefaultPriority,
3154 &callback2,
3155 pool_.get(),
3156 BoundNetLog());
3157 if (rv != OK) {
3158 EXPECT_EQ(ERR_IO_PENDING, rv);
3159 EXPECT_EQ(OK, callback2.WaitForResult());
3160 }
3161
3162 handle1.Reset();
3163 handle2.Reset();
3164
3165 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3166
3167 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3168 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3169 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3170}
3171
3172TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3173 CreatePool(4, 4);
3174 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3175
3176 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3177
3178 ASSERT_TRUE(pool_->HasGroup("a"));
3179 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3180 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3181
3182 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3183 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3184 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3185
3186 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3187 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3188 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3189
3190 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3191 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3192 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3193}
3194
3195TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3196 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3197 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3198
3199 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3200
3201 ASSERT_TRUE(pool_->HasGroup("a"));
3202 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3203 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3204
3205 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103206 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033207 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3208 params_,
3209 kDefaultPriority,
3210 &callback1,
3211 pool_.get(),
3212 BoundNetLog()));
3213
3214 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3215 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3216
3217 ASSERT_EQ(OK, callback1.WaitForResult());
3218
3219 handle1.Reset();
3220
3221 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3222}
3223
[email protected]dcbe168a2010-12-02 03:14:463224// http://crbug.com/64940 regression test.
3225TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3226 const int kMaxTotalSockets = 3;
3227 const int kMaxSocketsPerGroup = 2;
3228 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3229 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3230
3231 // Note that group name ordering matters here. "a" comes before "b", so
3232 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3233
3234 // Set up one idle socket in "a".
3235 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103236 TestOldCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463237 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3238 params_,
3239 kDefaultPriority,
3240 &callback1,
3241 pool_.get(),
3242 BoundNetLog()));
3243
3244 ASSERT_EQ(OK, callback1.WaitForResult());
3245 handle1.Reset();
3246 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3247
3248 // Set up two active sockets in "b".
3249 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103250 TestOldCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463251 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3252 params_,
3253 kDefaultPriority,
3254 &callback1,
3255 pool_.get(),
3256 BoundNetLog()));
3257 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3258 params_,
3259 kDefaultPriority,
3260 &callback2,
3261 pool_.get(),
3262 BoundNetLog()));
3263
3264 ASSERT_EQ(OK, callback1.WaitForResult());
3265 ASSERT_EQ(OK, callback2.WaitForResult());
3266 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3267 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3268
3269 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3270 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3271 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3272 // sockets for "a", and "b" should still have 2 active sockets.
3273
3274 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3275 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3276 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3277 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3278 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3279 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3280 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3281
3282 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3283 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3284 // "a" should result in closing 1 for "b".
3285 handle1.Reset();
3286 handle2.Reset();
3287 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3288 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3289
3290 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3291 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3292 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3293 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3294 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3295 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3296 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3297}
3298
[email protected]b7b8be42011-07-12 12:46:413299TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073300 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3301 pool_->EnableConnectBackupJobs();
3302
3303 // Make the ConnectJob hang until it times out, shorten the timeout.
3304 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3305 connect_job_factory_->set_timeout_duration(
3306 base::TimeDelta::FromMilliseconds(500));
3307 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3308 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3309 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073310
[email protected]b7b8be42011-07-12 12:46:413311 // Verify the backup timer doesn't create a backup job, by making
3312 // the backup job a pending job instead of a waiting job, so it
3313 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073314 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413315 MessageLoop::current()->PostDelayedTask(FROM_HERE,
3316 new MessageLoop::QuitTask(), 1000);
3317 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073318 EXPECT_FALSE(pool_->HasGroup("a"));
3319}
3320
[email protected]b7b8be42011-07-12 12:46:413321TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073322 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3323 pool_->EnableConnectBackupJobs();
3324
3325 // Make the ConnectJob hang forever.
3326 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3327 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3328 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3329 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3330 MessageLoop::current()->RunAllPending();
3331
3332 // Make the backup job be a pending job, so it completes normally.
3333 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3334 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:103335 TestOldCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073336 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3337 params_,
3338 kDefaultPriority,
3339 &callback,
3340 pool_.get(),
3341 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413342 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073343 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3344 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3345 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3346 ASSERT_EQ(OK, callback.WaitForResult());
3347
3348 // The hung connect job should still be there, but everything else should be
3349 // complete.
3350 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3351 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3352 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3353}
3354
[email protected]f6d1d6eb2009-06-24 20:16:093355} // namespace
3356
3357} // namespace net