blob: 2be05b1bd5d3ee3a0f7cd25070c381b7ed2eb7c1 [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);
557 }
[email protected]2431756e2010-09-29 20:26:13558
[email protected]636b8252011-04-08 19:56:54559 virtual ~ClientSocketPoolBaseTest() {
560 internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
561 connect_backup_jobs_enabled_);
562 }
[email protected]c9d6a1d2009-07-14 16:15:20563
[email protected]211d21722009-07-22 15:48:53564 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16565 CreatePoolWithIdleTimeouts(
566 max_sockets,
567 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00568 base::TimeDelta::FromSeconds(
569 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16570 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
571 }
572
573 void CreatePoolWithIdleTimeouts(
574 int max_sockets, int max_sockets_per_group,
575 base::TimeDelta unused_idle_socket_timeout,
576 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20577 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04578 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13579 pool_.reset(new TestClientSocketPool(max_sockets,
580 max_sockets_per_group,
581 &histograms_,
582 unused_idle_socket_timeout,
583 used_idle_socket_timeout,
584 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20585 }
[email protected]f6d1d6eb2009-06-24 20:16:09586
[email protected]ac790b42009-12-02 04:31:31587 int StartRequest(const std::string& group_name,
588 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13589 return test_base_.StartRequestUsingPool<
590 TestClientSocketPool, TestSocketParams>(
591 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09592 }
593
[email protected]2431756e2010-09-29 20:26:13594 int GetOrderOfRequest(size_t index) const {
595 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09596 }
597
[email protected]2431756e2010-09-29 20:26:13598 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
599 return test_base_.ReleaseOneConnection(keep_alive);
600 }
601
602 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
603 test_base_.ReleaseAllConnections(keep_alive);
604 }
605
606 TestSocketRequest* request(int i) { return test_base_.request(i); }
607 size_t requests_size() const { return test_base_.requests_size(); }
608 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
609 size_t completion_count() const { return test_base_.completion_count(); }
610
[email protected]636b8252011-04-08 19:56:54611 bool connect_backup_jobs_enabled_;
[email protected]f6d1d6eb2009-06-24 20:16:09612 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04613 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21614 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13615 ClientSocketPoolHistograms histograms_;
616 scoped_ptr<TestClientSocketPool> pool_;
617 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09618};
619
[email protected]5e6efa52011-06-27 17:26:41620TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_WarmestSocket) {
621 CreatePool(4, 4);
622 net::SetSocketReusePolicy(0);
623
624 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
625 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
626 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
627 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
628
629 std::map<int, StreamSocket*> sockets_;
630 for (size_t i = 0; i < test_base_.requests_size(); i++) {
631 TestSocketRequest* req = test_base_.request(i);
632 StreamSocket* s = req->handle()->socket();
633 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
634 CHECK(sock);
635 sockets_[i] = sock;
636 sock->Read(NULL, 1024 - i, NULL);
637 }
638
639 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
640
641 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
642 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
643
644 // First socket is warmest.
645 EXPECT_EQ(sockets_[0], req->handle()->socket());
646
647 // Test that NumBytes are as expected.
648 EXPECT_EQ(1024, sockets_[0]->NumBytesRead());
649 EXPECT_EQ(1023, sockets_[1]->NumBytesRead());
650 EXPECT_EQ(1022, sockets_[2]->NumBytesRead());
651 EXPECT_EQ(1021, sockets_[3]->NumBytesRead());
652
653 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
654}
655
656TEST_F(ClientSocketPoolBaseTest, AssignIdleSocketToGroup_LastAccessedSocket) {
657 CreatePool(4, 4);
658 net::SetSocketReusePolicy(2);
659
660 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
661 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
662 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
663 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
664
665 std::map<int, StreamSocket*> sockets_;
666 for (size_t i = 0; i < test_base_.requests_size(); i++) {
667 TestSocketRequest* req = test_base_.request(i);
668 StreamSocket* s = req->handle()->socket();
669 MockClientSocket* sock = static_cast<MockClientSocket*>(s);
670 CHECK(sock);
671 sockets_[i] = sock;
672 sock->Read(NULL, 1024 - i, NULL);
673 }
674
675 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
676
677 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
678 TestSocketRequest* req = test_base_.request(test_base_.requests_size() - 1);
679
680 // Last socket is most recently accessed.
681 EXPECT_EQ(sockets_[3], req->handle()->socket());
682 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
683}
684
[email protected]974ebd62009-08-03 23:14:34685// Even though a timeout is specified, it doesn't time out on a synchronous
686// completion.
687TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
688 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06689 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49690 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03691 &ignored, NULL, kDefaultPriority,
692 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20693 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34694 scoped_ptr<TestConnectJob> job(
695 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12696 "a",
[email protected]974ebd62009-08-03 23:14:34697 request,
698 base::TimeDelta::FromMicroseconds(1),
699 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30700 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17701 NULL));
[email protected]974ebd62009-08-03 23:14:34702 EXPECT_EQ(OK, job->Connect());
703}
704
705TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
706 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06707 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17708 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53709
[email protected]d80a4322009-08-14 07:07:49710 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03711 &ignored, NULL, kDefaultPriority,
712 internal::ClientSocketPoolBaseHelper::NORMAL,
[email protected]5acdce12011-03-30 13:00:20713 false, params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34714 // Deleted by TestConnectJobDelegate.
715 TestConnectJob* job =
716 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12717 "a",
[email protected]974ebd62009-08-03 23:14:34718 request,
719 base::TimeDelta::FromMicroseconds(1),
720 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30721 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17722 &log);
[email protected]974ebd62009-08-03 23:14:34723 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
[email protected]f214f8792011-01-01 02:17:08724 base::PlatformThread::Sleep(1);
[email protected]974ebd62009-08-03 23:14:34725 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30726
[email protected]b2fcd0e2010-12-01 15:19:40727 net::CapturingNetLog::EntryList entries;
728 log.GetEntries(&entries);
729
730 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46731 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40732 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17733 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40734 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46735 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40736 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17737 NetLog::PHASE_NONE));
738 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40739 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53740 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46741 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40742 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17743 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40744 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34745}
746
[email protected]5fc08e32009-07-15 17:09:57747TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53748 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20749
[email protected]f1f3f0f82011-10-01 20:38:10750 TestOldCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06751 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53752 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
753
[email protected]2431756e2010-09-29 20:26:13754 EXPECT_EQ(OK,
755 handle.Init("a",
756 params_,
757 kDefaultPriority,
758 &callback,
759 pool_.get(),
760 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09761 EXPECT_TRUE(handle.is_initialized());
762 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09763 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30764
[email protected]b2fcd0e2010-12-01 15:19:40765 net::CapturingNetLog::EntryList entries;
766 log.GetEntries(&entries);
767
768 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46769 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40770 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53771 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40772 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17773 NetLog::PHASE_NONE));
774 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40775 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53776 NetLog::PHASE_NONE));
777 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40778 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09779}
780
[email protected]ab838892009-06-30 18:49:05781TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53782 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20783
[email protected]ab838892009-06-30 18:49:05784 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53785 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
786
[email protected]2431756e2010-09-29 20:26:13787 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:10788 TestOldCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18789 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13790 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43791 HttpResponseInfo info;
792 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13793 handle.set_ssl_error_response_info(info);
794 EXPECT_EQ(ERR_CONNECTION_FAILED,
795 handle.Init("a",
796 params_,
797 kDefaultPriority,
798 &callback,
799 pool_.get(),
800 log.bound()));
801 EXPECT_FALSE(handle.socket());
802 EXPECT_FALSE(handle.is_ssl_error());
803 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30804
[email protected]b2fcd0e2010-12-01 15:19:40805 net::CapturingNetLog::EntryList entries;
806 log.GetEntries(&entries);
807
808 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27809 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40810 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17811 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40812 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17813 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02814 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40815 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09816}
817
[email protected]211d21722009-07-22 15:48:53818TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
820
[email protected]9e743cd2010-03-16 07:03:53821 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30822
[email protected]211d21722009-07-22 15:48:53823 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
824 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
825 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
826 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
827
[email protected]2431756e2010-09-29 20:26:13828 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53829 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13830 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53831
832 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
833 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
834 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
835
[email protected]2431756e2010-09-29 20:26:13836 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53837
[email protected]2431756e2010-09-29 20:26:13838 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53839 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13840 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53841
842 EXPECT_EQ(1, GetOrderOfRequest(1));
843 EXPECT_EQ(2, GetOrderOfRequest(2));
844 EXPECT_EQ(3, GetOrderOfRequest(3));
845 EXPECT_EQ(4, GetOrderOfRequest(4));
846 EXPECT_EQ(5, GetOrderOfRequest(5));
847 EXPECT_EQ(6, GetOrderOfRequest(6));
848 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17849
850 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13851 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53852}
853
854TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
855 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
856
[email protected]9e743cd2010-03-16 07:03:53857 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30858
[email protected]211d21722009-07-22 15:48:53859 // Reach all limits: max total sockets, and max sockets per group.
860 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
861 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
862 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
863 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
864
[email protected]2431756e2010-09-29 20:26:13865 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53866 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13867 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53868
869 // Now create a new group and verify that we don't starve it.
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
871
[email protected]2431756e2010-09-29 20:26:13872 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53873
[email protected]2431756e2010-09-29 20:26:13874 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53875 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13876 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53877
878 EXPECT_EQ(1, GetOrderOfRequest(1));
879 EXPECT_EQ(2, GetOrderOfRequest(2));
880 EXPECT_EQ(3, GetOrderOfRequest(3));
881 EXPECT_EQ(4, GetOrderOfRequest(4));
882 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17883
884 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13885 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53886}
887
888TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
890
[email protected]ac790b42009-12-02 04:31:31891 EXPECT_EQ(OK, StartRequest("b", LOWEST));
892 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
893 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
894 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53895
[email protected]2431756e2010-09-29 20:26:13896 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53897 client_socket_factory_.allocation_count());
898
[email protected]ac790b42009-12-02 04:31:31899 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
900 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
901 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53902
[email protected]2431756e2010-09-29 20:26:13903 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53904
[email protected]2431756e2010-09-29 20:26:13905 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53906
907 // First 4 requests don't have to wait, and finish in order.
908 EXPECT_EQ(1, GetOrderOfRequest(1));
909 EXPECT_EQ(2, GetOrderOfRequest(2));
910 EXPECT_EQ(3, GetOrderOfRequest(3));
911 EXPECT_EQ(4, GetOrderOfRequest(4));
912
[email protected]ac790b42009-12-02 04:31:31913 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
914 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53915 EXPECT_EQ(7, GetOrderOfRequest(5));
916 EXPECT_EQ(6, GetOrderOfRequest(6));
917 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17918
919 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13920 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53921}
922
923TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
924 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
925
[email protected]ac790b42009-12-02 04:31:31926 EXPECT_EQ(OK, StartRequest("a", LOWEST));
927 EXPECT_EQ(OK, StartRequest("a", LOW));
928 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
929 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53930
[email protected]2431756e2010-09-29 20:26:13931 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53932 client_socket_factory_.allocation_count());
933
[email protected]ac790b42009-12-02 04:31:31934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53937
[email protected]2431756e2010-09-29 20:26:13938 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53939
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53941 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13942 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53943
944 // First 4 requests don't have to wait, and finish in order.
945 EXPECT_EQ(1, GetOrderOfRequest(1));
946 EXPECT_EQ(2, GetOrderOfRequest(2));
947 EXPECT_EQ(3, GetOrderOfRequest(3));
948 EXPECT_EQ(4, GetOrderOfRequest(4));
949
950 // Request ("b", 7) has the highest priority, but we can't make new socket for
951 // group "b", because it has reached the per-group limit. Then we make
952 // socket for ("c", 6), because it has higher priority than ("a", 4),
953 // and we still can't make a socket for group "b".
954 EXPECT_EQ(5, GetOrderOfRequest(5));
955 EXPECT_EQ(6, GetOrderOfRequest(6));
956 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17957
958 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13959 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53960}
961
962// Make sure that we count connecting sockets against the total limit.
963TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
964 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
965
966 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
967 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
968 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
969
970 // Create one asynchronous request.
971 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
972 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
973
[email protected]6b175382009-10-13 06:47:47974 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
975 // actually become pending until 2ms after they have been created. In order
976 // to flush all tasks, we need to wait so that we know there are no
977 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:08978 base::PlatformThread::Sleep(10);
[email protected]6b175382009-10-13 06:47:47979 MessageLoop::current()->RunAllPending();
980
[email protected]211d21722009-07-22 15:48:53981 // The next synchronous request should wait for its turn.
982 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
983 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
984
[email protected]2431756e2010-09-29 20:26:13985 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53986
[email protected]2431756e2010-09-29 20:26:13987 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53988 client_socket_factory_.allocation_count());
989
990 EXPECT_EQ(1, GetOrderOfRequest(1));
991 EXPECT_EQ(2, GetOrderOfRequest(2));
992 EXPECT_EQ(3, GetOrderOfRequest(3));
993 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17994 EXPECT_EQ(5, GetOrderOfRequest(5));
995
996 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13997 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53998}
999
[email protected]6427fe22010-04-16 22:27:411000TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
1001 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1002 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1003
1004 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1005 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1006 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1007 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1008
1009 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1010
1011 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1012
1013 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
1014 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
1015
1016 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1017
[email protected]2431756e2010-09-29 20:26:131018 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411019 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131020 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411021 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131022 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1023 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:411024 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
1025}
1026
[email protected]d7027bb2010-05-10 18:58:541027TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
1028 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1029 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1030
1031 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101032 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131033 EXPECT_EQ(ERR_IO_PENDING,
1034 handle.Init("a",
1035 params_,
1036 kDefaultPriority,
1037 &callback,
1038 pool_.get(),
1039 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541040
1041 ClientSocketHandle handles[4];
1042 for (size_t i = 0; i < arraysize(handles); ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101043 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131044 EXPECT_EQ(ERR_IO_PENDING,
1045 handles[i].Init("b",
1046 params_,
1047 kDefaultPriority,
1048 &callback,
1049 pool_.get(),
1050 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541051 }
1052
1053 // One will be stalled, cancel all the handles now.
1054 // This should hit the OnAvailableSocketSlot() code where we previously had
1055 // stalled groups, but no longer have any.
1056 for (size_t i = 0; i < arraysize(handles); ++i)
1057 handles[i].Reset();
1058}
1059
[email protected]eb5a99382010-07-11 03:18:261060TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:541061 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1062 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1063
[email protected]eb5a99382010-07-11 03:18:261064 {
1065 ClientSocketHandle handles[kDefaultMaxSockets];
[email protected]f1f3f0f82011-10-01 20:38:101066 TestOldCompletionCallback callbacks[kDefaultMaxSockets];
[email protected]eb5a99382010-07-11 03:18:261067 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:131068 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
1069 params_,
[email protected]e83326f2010-07-31 17:29:251070 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:131071 &callbacks[i],
1072 pool_.get(),
1073 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261074 }
1075
1076 // Force a stalled group.
1077 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101078 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131079 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1080 params_,
1081 kDefaultPriority,
1082 &callback,
1083 pool_.get(),
1084 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261085
1086 // Cancel the stalled request.
1087 stalled_handle.Reset();
1088
1089 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1090 EXPECT_EQ(0, pool_->IdleSocketCount());
1091
1092 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541093 }
1094
[email protected]43a21b82010-06-10 21:30:541095 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1096 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:261097}
[email protected]43a21b82010-06-10 21:30:541098
[email protected]eb5a99382010-07-11 03:18:261099TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
1100 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1101 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1102
1103 {
1104 ClientSocketHandle handles[kDefaultMaxSockets];
1105 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101106 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131107 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1108 params_,
1109 kDefaultPriority,
1110 &callback,
1111 pool_.get(),
1112 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261113 }
1114
1115 // Force a stalled group.
1116 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1117 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101118 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131119 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1120 params_,
1121 kDefaultPriority,
1122 &callback,
1123 pool_.get(),
1124 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261125
1126 // Since it is stalled, it should have no connect jobs.
1127 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1128
1129 // Cancel the stalled request.
1130 handles[0].Reset();
1131
[email protected]eb5a99382010-07-11 03:18:261132 // Now we should have a connect job.
1133 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1134
1135 // The stalled socket should connect.
1136 EXPECT_EQ(OK, callback.WaitForResult());
1137
1138 EXPECT_EQ(kDefaultMaxSockets + 1,
1139 client_socket_factory_.allocation_count());
1140 EXPECT_EQ(0, pool_->IdleSocketCount());
1141 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1142
1143 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541144 }
1145
[email protected]eb5a99382010-07-11 03:18:261146 EXPECT_EQ(1, pool_->IdleSocketCount());
1147}
[email protected]43a21b82010-06-10 21:30:541148
[email protected]eb5a99382010-07-11 03:18:261149TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1150 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1151 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541152
[email protected]eb5a99382010-07-11 03:18:261153 ClientSocketHandle stalled_handle;
[email protected]f1f3f0f82011-10-01 20:38:101154 TestOldCompletionCallback callback;
[email protected]eb5a99382010-07-11 03:18:261155 {
1156 ClientSocketHandle handles[kDefaultMaxSockets];
1157 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:101158 TestOldCompletionCallback callback;
[email protected]1870d5cf2011-05-12 01:55:401159 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1160 "Take 2: %d", i),
1161 params_,
1162 kDefaultPriority,
1163 &callback,
1164 pool_.get(),
1165 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261166 }
1167
1168 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1169 EXPECT_EQ(0, pool_->IdleSocketCount());
1170
1171 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131172 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1173 params_,
1174 kDefaultPriority,
1175 &callback,
1176 pool_.get(),
1177 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261178
1179 // Dropping out of scope will close all handles and return them to idle.
1180 }
[email protected]43a21b82010-06-10 21:30:541181
1182 // But if we wait for it, the released idle sockets will be closed in
1183 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101184 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261185
1186 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1187 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541188}
1189
1190// Regression test for http://crbug.com/40952.
1191TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1192 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221193 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541194 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1195
1196 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1197 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101198 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131199 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1200 params_,
1201 kDefaultPriority,
1202 &callback,
1203 pool_.get(),
1204 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541205 }
1206
1207 // Flush all the DoReleaseSocket tasks.
1208 MessageLoop::current()->RunAllPending();
1209
1210 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1211 // reuse a socket.
1212 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1213 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101214 TestOldCompletionCallback callback;
[email protected]43a21b82010-06-10 21:30:541215
1216 // "0" is special here, since it should be the first entry in the sorted map,
1217 // which is the one which we would close an idle socket for. We shouldn't
1218 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131219 EXPECT_EQ(OK, handle.Init("0",
1220 params_,
1221 kDefaultPriority,
1222 &callback,
1223 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211224 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541225
1226 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1227 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1228}
1229
[email protected]ab838892009-06-30 18:49:051230TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531231 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091232
[email protected]c9d6a1d2009-07-14 16:15:201233 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1234 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1238 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1239 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1240 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091241
[email protected]2431756e2010-09-29 20:26:131242 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091243
[email protected]c9d6a1d2009-07-14 16:15:201244 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1245 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131246 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1247 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091248
[email protected]c9d6a1d2009-07-14 16:15:201249 EXPECT_EQ(1, GetOrderOfRequest(1));
1250 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031251 EXPECT_EQ(8, GetOrderOfRequest(3));
1252 EXPECT_EQ(6, GetOrderOfRequest(4));
1253 EXPECT_EQ(4, GetOrderOfRequest(5));
1254 EXPECT_EQ(3, GetOrderOfRequest(6));
1255 EXPECT_EQ(5, GetOrderOfRequest(7));
1256 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171257
1258 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131259 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091260}
1261
[email protected]ab838892009-06-30 18:49:051262TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531263 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091264
[email protected]c9d6a1d2009-07-14 16:15:201265 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1266 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311267 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1268 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1269 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1270 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1271 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091272
[email protected]2431756e2010-09-29 20:26:131273 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091274
[email protected]2431756e2010-09-29 20:26:131275 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1276 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201277
[email protected]2431756e2010-09-29 20:26:131278 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201279 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131280 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1281 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091282}
1283
1284// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051285// The pending connect job will be cancelled and should not call back into
1286// ClientSocketPoolBase.
1287TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531288 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201289
[email protected]ab838892009-06-30 18:49:051290 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131291 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101292 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131293 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1294 params_,
1295 kDefaultPriority,
1296 &callback,
1297 pool_.get(),
1298 BoundNetLog()));
1299 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091300}
1301
[email protected]ab838892009-06-30 18:49:051302TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531303 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201304
[email protected]ab838892009-06-30 18:49:051305 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061306 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101307 TestOldCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091308
[email protected]2431756e2010-09-29 20:26:131309 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1310 params_,
1311 kDefaultPriority,
1312 &callback,
1313 pool_.get(),
1314 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091315
1316 handle.Reset();
1317
[email protected]f1f3f0f82011-10-01 20:38:101318 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131319 EXPECT_EQ(ERR_IO_PENDING,
1320 handle.Init("a",
1321 params_,
1322 kDefaultPriority,
1323 &callback2,
1324 pool_.get(),
1325 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091326
1327 EXPECT_EQ(OK, callback2.WaitForResult());
1328 EXPECT_FALSE(callback.have_result());
1329
1330 handle.Reset();
1331}
1332
[email protected]ab838892009-06-30 18:49:051333TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531334 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091335
[email protected]c9d6a1d2009-07-14 16:15:201336 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1337 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311338 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1339 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1340 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1341 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1342 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091343
1344 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201345 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131346 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1347 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091348
[email protected]2431756e2010-09-29 20:26:131349 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091350
[email protected]c9d6a1d2009-07-14 16:15:201351 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1352 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131353 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1354 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091355
[email protected]c9d6a1d2009-07-14 16:15:201356 EXPECT_EQ(1, GetOrderOfRequest(1));
1357 EXPECT_EQ(2, GetOrderOfRequest(2));
1358 EXPECT_EQ(5, GetOrderOfRequest(3));
1359 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131360 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1361 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201362 EXPECT_EQ(4, GetOrderOfRequest(6));
1363 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171364
1365 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131366 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091367}
1368
1369class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1370 public:
[email protected]2ab05b52009-07-01 23:57:581371 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241372 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581373 TestConnectJobFactory* test_connect_job_factory,
1374 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091375 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061376 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581377 within_callback_(false),
1378 test_connect_job_factory_(test_connect_job_factory),
1379 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091380
1381 virtual void RunWithParams(const Tuple1<int>& params) {
1382 callback_.RunWithParams(params);
1383 ASSERT_EQ(OK, params.a);
1384
1385 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581386 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111387
1388 // Don't allow reuse of the socket. Disconnect it and then release it and
1389 // run through the MessageLoop once to get it completely released.
1390 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091391 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111392 {
1393 MessageLoop::ScopedNestableTaskAllower nestable(
1394 MessageLoop::current());
1395 MessageLoop::current()->RunAllPending();
1396 }
[email protected]f6d1d6eb2009-06-24 20:16:091397 within_callback_ = true;
[email protected]f1f3f0f82011-10-01 20:38:101398 TestOldCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271399 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131400 int rv = handle_->Init("a",
1401 params,
1402 kDefaultPriority,
1403 &next_job_callback,
1404 pool_,
1405 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581406 switch (next_job_type_) {
1407 case TestConnectJob::kMockJob:
1408 EXPECT_EQ(OK, rv);
1409 break;
1410 case TestConnectJob::kMockPendingJob:
1411 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471412
1413 // For pending jobs, wait for new socket to be created. This makes
1414 // sure there are no more pending operations nor any unclosed sockets
1415 // when the test finishes.
1416 // We need to give it a little bit of time to run, so that all the
1417 // operations that happen on timers (e.g. cleanup of idle
1418 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111419 {
1420 MessageLoop::ScopedNestableTaskAllower nestable(
1421 MessageLoop::current());
[email protected]f214f8792011-01-01 02:17:081422 base::PlatformThread::Sleep(10);
[email protected]5edbf8d2010-01-13 18:44:111423 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1424 }
[email protected]2ab05b52009-07-01 23:57:581425 break;
1426 default:
1427 FAIL() << "Unexpected job type: " << next_job_type_;
1428 break;
1429 }
[email protected]f6d1d6eb2009-06-24 20:16:091430 }
1431 }
1432
1433 int WaitForResult() {
1434 return callback_.WaitForResult();
1435 }
1436
1437 private:
1438 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131439 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091440 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581441 TestConnectJobFactory* const test_connect_job_factory_;
1442 TestConnectJob::JobType next_job_type_;
[email protected]f1f3f0f82011-10-01 20:38:101443 TestOldCompletionCallback callback_;
[email protected]f6d1d6eb2009-06-24 20:16:091444};
1445
[email protected]2ab05b52009-07-01 23:57:581446TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531447 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201448
[email protected]0b7648c2009-07-06 20:14:011449 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061450 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581451 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061452 &handle, pool_.get(), connect_job_factory_,
1453 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131454 int rv = handle.Init("a",
1455 params_,
1456 kDefaultPriority,
1457 &callback,
1458 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211459 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091460 ASSERT_EQ(ERR_IO_PENDING, rv);
1461
1462 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581463}
[email protected]f6d1d6eb2009-06-24 20:16:091464
[email protected]2ab05b52009-07-01 23:57:581465TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531466 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201467
[email protected]0b7648c2009-07-06 20:14:011468 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061469 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581470 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061471 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131472 int rv = handle.Init("a",
1473 params_,
1474 kDefaultPriority,
1475 &callback,
1476 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211477 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581478 ASSERT_EQ(ERR_IO_PENDING, rv);
1479
1480 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091481}
1482
1483// Make sure that pending requests get serviced after active requests get
1484// cancelled.
[email protected]ab838892009-06-30 18:49:051485TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531486 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201487
[email protected]0b7648c2009-07-06 20:14:011488 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091489
[email protected]c9d6a1d2009-07-14 16:15:201490 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1491 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1492 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1493 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1494 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));
[email protected]f6d1d6eb2009-06-24 20:16:091497
[email protected]c9d6a1d2009-07-14 16:15:201498 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1499 // Let's cancel them.
1500 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131501 ASSERT_FALSE(request(i)->handle()->is_initialized());
1502 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091503 }
1504
[email protected]f6d1d6eb2009-06-24 20:16:091505 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131506 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1507 EXPECT_EQ(OK, request(i)->WaitForResult());
1508 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091509 }
1510
[email protected]2431756e2010-09-29 20:26:131511 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1512 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091513}
1514
1515// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051516TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531517 const size_t kMaxSockets = 5;
1518 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201519
[email protected]0b7648c2009-07-06 20:14:011520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091521
[email protected]211d21722009-07-22 15:48:531522 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1523 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091524
1525 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531526 for (size_t i = 0; i < kNumberOfRequests; ++i)
1527 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091528
[email protected]211d21722009-07-22 15:48:531529 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131530 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091531}
1532
[email protected]5fc08e32009-07-15 17:09:571533TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571535
1536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1537
[email protected]2431756e2010-09-29 20:26:131538 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101539 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131540 int rv = handle.Init("a",
1541 params_,
1542 kDefaultPriority,
1543 &callback,
1544 pool_.get(),
1545 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571546 EXPECT_EQ(ERR_IO_PENDING, rv);
1547
1548 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131549 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571550
[email protected]2431756e2010-09-29 20:26:131551 rv = handle.Init("a",
1552 params_,
1553 kDefaultPriority,
1554 &callback,
1555 pool_.get(),
1556 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571557 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131558 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571559
[email protected]2431756e2010-09-29 20:26:131560 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571561 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1562}
1563
[email protected]2b7523d2009-07-29 20:29:231564// Regression test for http://crbug.com/17985.
1565TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1566 const int kMaxSockets = 3;
1567 const int kMaxSocketsPerGroup = 2;
1568 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1569
[email protected]ac790b42009-12-02 04:31:311570 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231571
1572 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1573 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1574
1575 // This is going to be a pending request in an otherwise empty group.
1576 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1577
1578 // Reach the maximum socket limit.
1579 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1580
1581 // Create a stalled group with high priorities.
1582 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1583 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231584
[email protected]eb5a99382010-07-11 03:18:261585 // Release the first two sockets from "a". Because this is a keepalive,
1586 // the first release will unblock the pending request for "a". The
1587 // second release will unblock a request for "c", becaue it is the next
1588 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131589 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1590 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231591
1592 // Closing idle sockets should not get us into trouble, but in the bug
1593 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411594 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541595 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261596
1597 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231598}
1599
[email protected]4d3b05d2010-01-27 21:27:291600TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531601 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571602
1603 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131604 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101605 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531606 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131607 int rv = handle.Init("a",
1608 params_,
1609 LOWEST,
1610 &callback,
1611 pool_.get(),
1612 log.bound());
[email protected]5fc08e32009-07-15 17:09:571613 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131614 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1615 EXPECT_EQ(OK, callback.WaitForResult());
1616 EXPECT_TRUE(handle.is_initialized());
1617 EXPECT_TRUE(handle.socket());
1618 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301619
[email protected]b2fcd0e2010-12-01 15:19:401620 net::CapturingNetLog::EntryList entries;
1621 log.GetEntries(&entries);
1622
1623 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461624 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401625 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171626 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401627 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171628 NetLog::PHASE_NONE));
1629 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401630 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171631 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461632 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401633 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571634}
1635
[email protected]4d3b05d2010-01-27 21:27:291636TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571637 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531638 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571639
1640 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131641 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101642 TestOldCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531643 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181644 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131645 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431646 HttpResponseInfo info;
1647 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131648 handle.set_ssl_error_response_info(info);
1649 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1650 params_,
1651 kDefaultPriority,
1652 &callback,
1653 pool_.get(),
1654 log.bound()));
1655 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1656 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1657 EXPECT_FALSE(handle.is_ssl_error());
1658 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301659
[email protected]b2fcd0e2010-12-01 15:19:401660 net::CapturingNetLog::EntryList entries;
1661 log.GetEntries(&entries);
1662
1663 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461664 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401665 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171666 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401667 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171668 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321669 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401670 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571671}
1672
[email protected]4d3b05d2010-01-27 21:27:291673TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101674 // TODO(eroman): Add back the log expectations! Removed them because the
1675 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571677
1678 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131679 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101680 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131681 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101682 TestOldCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571683
[email protected]2431756e2010-09-29 20:26:131684 EXPECT_EQ(ERR_IO_PENDING,
1685 handle.Init("a",
1686 params_,
1687 kDefaultPriority,
1688 &callback,
1689 pool_.get(),
1690 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531691 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131692 EXPECT_EQ(ERR_IO_PENDING,
1693 handle2.Init("a",
1694 params_,
1695 kDefaultPriority,
1696 &callback2,
1697 pool_.get(),
1698 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571699
[email protected]2431756e2010-09-29 20:26:131700 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571701
[email protected]fd7b7c92009-08-20 19:38:301702
1703 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301704
[email protected]2431756e2010-09-29 20:26:131705 EXPECT_EQ(OK, callback2.WaitForResult());
1706 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301707
1708 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531709 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571710}
1711
[email protected]4d3b05d2010-01-27 21:27:291712TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341713 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1714
[email protected]17a0c6c2009-08-04 00:07:041715 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1716
[email protected]ac790b42009-12-02 04:31:311717 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1719 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1720 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341721
1722 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131723 (*requests())[2]->handle()->Reset();
1724 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341725 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1726
[email protected]2431756e2010-09-29 20:26:131727 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341728 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1729
[email protected]2431756e2010-09-29 20:26:131730 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261731 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341732}
1733
[email protected]5fc08e32009-07-15 17:09:571734// When requests and ConnectJobs are not coupled, the request will get serviced
1735// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291736TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531737 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571738
1739 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321740 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571741
[email protected]2431756e2010-09-29 20:26:131742 std::vector<TestSocketRequest*> request_order;
1743 size_t completion_count; // unused
1744 TestSocketRequest req1(&request_order, &completion_count);
1745 int rv = req1.handle()->Init("a",
1746 params_,
1747 kDefaultPriority,
1748 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211749 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571750 EXPECT_EQ(ERR_IO_PENDING, rv);
1751 EXPECT_EQ(OK, req1.WaitForResult());
1752
1753 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1754 // without a job.
1755 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1756
[email protected]2431756e2010-09-29 20:26:131757 TestSocketRequest req2(&request_order, &completion_count);
1758 rv = req2.handle()->Init("a",
1759 params_,
1760 kDefaultPriority,
1761 &req2,
1762 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211763 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571764 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131765 TestSocketRequest req3(&request_order, &completion_count);
1766 rv = req3.handle()->Init("a",
1767 params_,
1768 kDefaultPriority,
1769 &req3,
1770 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211771 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571772 EXPECT_EQ(ERR_IO_PENDING, rv);
1773
1774 // Both Requests 2 and 3 are pending. We release socket 1 which should
1775 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331776 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261777 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331778 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571779 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331780 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571781
1782 // Signal job 2, which should service request 3.
1783
1784 client_socket_factory_.SignalJobs();
1785 EXPECT_EQ(OK, req3.WaitForResult());
1786
[email protected]2431756e2010-09-29 20:26:131787 ASSERT_EQ(3U, request_order.size());
1788 EXPECT_EQ(&req1, request_order[0]);
1789 EXPECT_EQ(&req2, request_order[1]);
1790 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571791 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1792}
1793
1794// The requests are not coupled to the jobs. So, the requests should finish in
1795// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291796TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531797 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571798 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321799 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571800
[email protected]2431756e2010-09-29 20:26:131801 std::vector<TestSocketRequest*> request_order;
1802 size_t completion_count; // unused
1803 TestSocketRequest req1(&request_order, &completion_count);
1804 int rv = req1.handle()->Init("a",
1805 params_,
1806 kDefaultPriority,
1807 &req1,
1808 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211809 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571810 EXPECT_EQ(ERR_IO_PENDING, rv);
1811
[email protected]2431756e2010-09-29 20:26:131812 TestSocketRequest req2(&request_order, &completion_count);
1813 rv = req2.handle()->Init("a",
1814 params_,
1815 kDefaultPriority,
1816 &req2,
1817 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211818 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571819 EXPECT_EQ(ERR_IO_PENDING, rv);
1820
1821 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321822 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571823
[email protected]2431756e2010-09-29 20:26:131824 TestSocketRequest req3(&request_order, &completion_count);
1825 rv = req3.handle()->Init("a",
1826 params_,
1827 kDefaultPriority,
1828 &req3,
1829 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211830 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571831 EXPECT_EQ(ERR_IO_PENDING, rv);
1832
1833 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1834 EXPECT_EQ(OK, req2.WaitForResult());
1835 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1836
[email protected]2431756e2010-09-29 20:26:131837 ASSERT_EQ(3U, request_order.size());
1838 EXPECT_EQ(&req1, request_order[0]);
1839 EXPECT_EQ(&req2, request_order[1]);
1840 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571841}
1842
[email protected]e6ec67b2010-06-16 00:12:461843TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531844 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571845 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321846 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571847
[email protected]2431756e2010-09-29 20:26:131848 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101849 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131850 int rv = handle.Init("a",
1851 params_,
1852 kDefaultPriority,
1853 &callback,
1854 pool_.get(),
1855 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571856 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131857 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571858
1859 MessageLoop::current()->RunAllPending();
1860
[email protected]2431756e2010-09-29 20:26:131861 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101862 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131863 rv = handle2.Init("a",
1864 params_,
1865 kDefaultPriority,
1866 &callback2, pool_.get(),
1867 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571868 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131869 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1870 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571871}
1872
[email protected]e772db3f2010-07-12 18:11:131873TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1874 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1875 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1876
[email protected]2431756e2010-09-29 20:26:131877 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101878 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131879 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1880 params_,
1881 kDefaultPriority,
1882 &callback, pool_.get(),
1883 BoundNetLog()));
1884 EXPECT_TRUE(handle.is_initialized());
1885 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131886}
1887
1888TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1889 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1890
1891 connect_job_factory_->set_job_type(
1892 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131893 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101894 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131895 EXPECT_EQ(ERR_IO_PENDING,
1896 handle.Init("a",
1897 params_,
1898 kDefaultPriority,
1899 &callback,
1900 pool_.get(),
1901 BoundNetLog()));
1902 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1903 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1904 EXPECT_TRUE(handle.is_initialized());
1905 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131906}
1907
[email protected]e60e47a2010-07-14 03:37:181908TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1909 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1910 connect_job_factory_->set_job_type(
1911 TestConnectJob::kMockAdditionalErrorStateJob);
1912
[email protected]2431756e2010-09-29 20:26:131913 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101914 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131915 EXPECT_EQ(ERR_CONNECTION_FAILED,
1916 handle.Init("a",
1917 params_,
1918 kDefaultPriority,
1919 &callback,
1920 pool_.get(),
1921 BoundNetLog()));
1922 EXPECT_FALSE(handle.is_initialized());
1923 EXPECT_FALSE(handle.socket());
1924 EXPECT_TRUE(handle.is_ssl_error());
1925 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181926}
1927
1928TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1929 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1930
1931 connect_job_factory_->set_job_type(
1932 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131933 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101934 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131935 EXPECT_EQ(ERR_IO_PENDING,
1936 handle.Init("a",
1937 params_,
1938 kDefaultPriority,
1939 &callback,
1940 pool_.get(),
1941 BoundNetLog()));
1942 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1943 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1944 EXPECT_FALSE(handle.is_initialized());
1945 EXPECT_FALSE(handle.socket());
1946 EXPECT_TRUE(handle.is_ssl_error());
1947 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181948}
1949
[email protected]4d3b05d2010-01-27 21:27:291950TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161951 CreatePoolWithIdleTimeouts(
1952 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1953 base::TimeDelta(), // Time out unused sockets immediately.
1954 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1955
1956 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1957
1958 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1959
[email protected]2431756e2010-09-29 20:26:131960 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:101961 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131962 int rv = handle.Init("a",
1963 params_,
1964 LOWEST,
1965 &callback,
1966 pool_.get(),
1967 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161968 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131969 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161970
[email protected]2431756e2010-09-29 20:26:131971 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:101972 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131973 rv = handle2.Init("a",
1974 params_,
1975 LOWEST,
1976 &callback2,
1977 pool_.get(),
1978 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161979 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131980 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161981
1982 // Cancel one of the requests. Wait for the other, which will get the first
1983 // job. Release the socket. Run the loop again to make sure the second
1984 // socket is sitting idle and the first one is released (since ReleaseSocket()
1985 // just posts a DoReleaseSocket() task).
1986
[email protected]2431756e2010-09-29 20:26:131987 handle.Reset();
1988 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011989 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131990 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1991 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471992
1993 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1994 // actually become pending until 2ms after they have been created. In order
1995 // to flush all tasks, we need to wait so that we know there are no
1996 // soon-to-be-pending tasks waiting.
[email protected]f214f8792011-01-01 02:17:081997 base::PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161998 MessageLoop::current()->RunAllPending();
1999
2000 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:042001
[email protected]9bf28db2009-08-29 01:35:162002 // Invoke the idle socket cleanup check. Only one socket should be left, the
2003 // used socket. Request it to make sure that it's used.
2004
2005 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:532006 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:132007 rv = handle.Init("a",
2008 params_,
2009 LOWEST,
2010 &callback,
2011 pool_.get(),
2012 log.bound());
[email protected]9bf28db2009-08-29 01:35:162013 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:132014 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:402015
2016 net::CapturingNetLog::EntryList entries;
2017 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:152018 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:402019 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:162020}
2021
[email protected]2041cf342010-02-19 03:15:592022// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:162023// because of multiple releasing disconnected sockets.
2024TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
2025 CreatePoolWithIdleTimeouts(
2026 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
2027 base::TimeDelta(), // Time out unused sockets immediately.
2028 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2029
2030 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2031
2032 // Startup 4 connect jobs. Two of them will be pending.
2033
[email protected]2431756e2010-09-29 20:26:132034 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102035 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132036 int rv = handle.Init("a",
2037 params_,
2038 LOWEST,
2039 &callback,
2040 pool_.get(),
2041 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162042 EXPECT_EQ(OK, rv);
2043
[email protected]2431756e2010-09-29 20:26:132044 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102045 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132046 rv = handle2.Init("a",
2047 params_,
2048 LOWEST,
2049 &callback2,
2050 pool_.get(),
2051 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162052 EXPECT_EQ(OK, rv);
2053
[email protected]2431756e2010-09-29 20:26:132054 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102055 TestOldCompletionCallback callback3;
[email protected]2431756e2010-09-29 20:26:132056 rv = handle3.Init("a",
2057 params_,
2058 LOWEST,
2059 &callback3,
2060 pool_.get(),
2061 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162062 EXPECT_EQ(ERR_IO_PENDING, rv);
2063
[email protected]2431756e2010-09-29 20:26:132064 ClientSocketHandle handle4;
[email protected]f1f3f0f82011-10-01 20:38:102065 TestOldCompletionCallback callback4;
[email protected]2431756e2010-09-29 20:26:132066 rv = handle4.Init("a",
2067 params_,
2068 LOWEST,
2069 &callback4,
2070 pool_.get(),
2071 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:162072 EXPECT_EQ(ERR_IO_PENDING, rv);
2073
2074 // Release two disconnected sockets.
2075
[email protected]2431756e2010-09-29 20:26:132076 handle.socket()->Disconnect();
2077 handle.Reset();
2078 handle2.socket()->Disconnect();
2079 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:162080
[email protected]2431756e2010-09-29 20:26:132081 EXPECT_EQ(OK, callback3.WaitForResult());
2082 EXPECT_FALSE(handle3.is_reused());
2083 EXPECT_EQ(OK, callback4.WaitForResult());
2084 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:162085}
2086
[email protected]d7027bb2010-05-10 18:58:542087// Regression test for http://crbug.com/42267.
2088// When DoReleaseSocket() is processed for one socket, it is blocked because the
2089// other stalled groups all have releasing sockets, so no progress can be made.
2090TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
2091 CreatePoolWithIdleTimeouts(
2092 4 /* socket limit */, 4 /* socket limit per group */,
2093 base::TimeDelta(), // Time out unused sockets immediately.
2094 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
2095
2096 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2097
2098 // Max out the socket limit with 2 per group.
2099
[email protected]2431756e2010-09-29 20:26:132100 ClientSocketHandle handle_a[4];
[email protected]f1f3f0f82011-10-01 20:38:102101 TestOldCompletionCallback callback_a[4];
[email protected]2431756e2010-09-29 20:26:132102 ClientSocketHandle handle_b[4];
[email protected]f1f3f0f82011-10-01 20:38:102103 TestOldCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:542104
2105 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132106 EXPECT_EQ(OK, handle_a[i].Init("a",
2107 params_,
2108 LOWEST,
2109 &callback_a[i],
2110 pool_.get(),
2111 BoundNetLog()));
2112 EXPECT_EQ(OK, handle_b[i].Init("b",
2113 params_,
2114 LOWEST,
2115 &callback_b[i],
2116 pool_.get(),
2117 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542118 }
[email protected]b89f7e42010-05-20 20:37:002119
[email protected]d7027bb2010-05-10 18:58:542120 // Make 4 pending requests, 2 per group.
2121
2122 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132123 EXPECT_EQ(ERR_IO_PENDING,
2124 handle_a[i].Init("a",
2125 params_,
2126 LOWEST,
2127 &callback_a[i],
2128 pool_.get(),
2129 BoundNetLog()));
2130 EXPECT_EQ(ERR_IO_PENDING,
2131 handle_b[i].Init("b",
2132 params_,
2133 LOWEST,
2134 &callback_b[i],
2135 pool_.get(),
2136 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542137 }
2138
2139 // Release b's socket first. The order is important, because in
2140 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2141 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2142 // first, which has a releasing socket, so it refuses to start up another
2143 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132144 handle_b[0].socket()->Disconnect();
2145 handle_b[0].Reset();
2146 handle_a[0].socket()->Disconnect();
2147 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542148
2149 // Used to get stuck here.
2150 MessageLoop::current()->RunAllPending();
2151
[email protected]2431756e2010-09-29 20:26:132152 handle_b[1].socket()->Disconnect();
2153 handle_b[1].Reset();
2154 handle_a[1].socket()->Disconnect();
2155 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542156
2157 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132158 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2159 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542160 }
2161}
2162
[email protected]fd4fe0b2010-02-08 23:02:152163TEST_F(ClientSocketPoolBaseTest,
2164 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2165 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2166
2167 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2168
2169 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2170 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2171 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2172 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2173
[email protected]2431756e2010-09-29 20:26:132174 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2175 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2176 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152177
2178 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132179 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2180 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152181
[email protected]2431756e2010-09-29 20:26:132182 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2183 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2184 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152185
2186 EXPECT_EQ(1, GetOrderOfRequest(1));
2187 EXPECT_EQ(2, GetOrderOfRequest(2));
2188 EXPECT_EQ(3, GetOrderOfRequest(3));
2189 EXPECT_EQ(4, GetOrderOfRequest(4));
2190
2191 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132192 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152193}
2194
[email protected]4f1e4982010-03-02 18:31:042195class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2196 public:
[email protected]2431756e2010-09-29 20:26:132197 TestReleasingSocketRequest(TestClientSocketPool* pool,
2198 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182199 bool reset_releasing_handle)
2200 : pool_(pool),
2201 expected_result_(expected_result),
2202 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042203
2204 ClientSocketHandle* handle() { return &handle_; }
2205
2206 int WaitForResult() {
2207 return callback_.WaitForResult();
2208 }
2209
2210 virtual void RunWithParams(const Tuple1<int>& params) {
2211 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182212 if (reset_releasing_handle_)
2213 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272214 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132215 EXPECT_EQ(expected_result_, handle2_.Init("a",
2216 con_params,
2217 kDefaultPriority,
2218 &callback2_,
2219 pool_,
[email protected]e60e47a2010-07-14 03:37:182220 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042221 }
2222
2223 private:
[email protected]2431756e2010-09-29 20:26:132224 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182225 int expected_result_;
2226 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042227 ClientSocketHandle handle_;
2228 ClientSocketHandle handle2_;
[email protected]f1f3f0f82011-10-01 20:38:102229 TestOldCompletionCallback callback_;
2230 TestOldCompletionCallback callback2_;
[email protected]4f1e4982010-03-02 18:31:042231};
2232
[email protected]e60e47a2010-07-14 03:37:182233
2234TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2235 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2236
2237 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2238 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2239 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2240
[email protected]2431756e2010-09-29 20:26:132241 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182242 client_socket_factory_.allocation_count());
2243
2244 connect_job_factory_->set_job_type(
2245 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2246 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132247 EXPECT_EQ(ERR_IO_PENDING,
2248 req.handle()->Init("a",
2249 params_,
2250 kDefaultPriority,
2251 &req,
2252 pool_.get(),
2253 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182254 // The next job should complete synchronously
2255 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2256
2257 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2258 EXPECT_FALSE(req.handle()->is_initialized());
2259 EXPECT_FALSE(req.handle()->socket());
2260 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432261 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182262}
2263
[email protected]b6501d3d2010-06-03 23:53:342264// http://crbug.com/44724 regression test.
2265// We start releasing the pool when we flush on network change. When that
2266// happens, the only active references are in the ClientSocketHandles. When a
2267// ConnectJob completes and calls back into the last ClientSocketHandle, that
2268// callback can release the last reference and delete the pool. After the
2269// callback finishes, we go back to the stack frame within the now-deleted pool.
2270// Executing any code that refers to members of the now-deleted pool can cause
2271// crashes.
2272TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2273 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2274 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2275
2276 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102277 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132278 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2279 params_,
2280 kDefaultPriority,
2281 &callback,
2282 pool_.get(),
2283 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342284
[email protected]2431756e2010-09-29 20:26:132285 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342286
2287 // We'll call back into this now.
2288 callback.WaitForResult();
2289}
2290
[email protected]a7e38572010-06-07 18:22:242291TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2292 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2293 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2294
2295 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102296 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132297 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2298 params_,
2299 kDefaultPriority,
2300 &callback,
2301 pool_.get(),
2302 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242303 EXPECT_EQ(OK, callback.WaitForResult());
2304 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2305
2306 pool_->Flush();
2307
2308 handle.Reset();
2309 MessageLoop::current()->RunAllPending();
2310
[email protected]2431756e2010-09-29 20:26:132311 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2312 params_,
2313 kDefaultPriority,
2314 &callback,
2315 pool_.get(),
2316 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242317 EXPECT_EQ(OK, callback.WaitForResult());
2318 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2319}
2320
[email protected]06f92462010-08-31 19:24:142321class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2322 public:
2323 ConnectWithinCallback(
2324 const std::string& group_name,
2325 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132326 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142327 : group_name_(group_name), params_(params), pool_(pool) {}
2328
2329 ~ConnectWithinCallback() {}
2330
2331 virtual void RunWithParams(const Tuple1<int>& params) {
2332 callback_.RunWithParams(params);
2333 EXPECT_EQ(ERR_IO_PENDING,
2334 handle_.Init(group_name_,
2335 params_,
2336 kDefaultPriority,
2337 &nested_callback_,
2338 pool_,
2339 BoundNetLog()));
2340 }
2341
2342 int WaitForResult() {
2343 return callback_.WaitForResult();
2344 }
2345
2346 int WaitForNestedResult() {
2347 return nested_callback_.WaitForResult();
2348 }
2349
2350 private:
2351 const std::string group_name_;
2352 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132353 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142354 ClientSocketHandle handle_;
[email protected]f1f3f0f82011-10-01 20:38:102355 TestOldCompletionCallback callback_;
2356 TestOldCompletionCallback nested_callback_;
[email protected]06f92462010-08-31 19:24:142357};
2358
2359TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2360 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2361
2362 // First job will be waiting until it gets aborted.
2363 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2364
2365 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132366 ConnectWithinCallback callback("a", params_, pool_.get());
2367 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2368 params_,
2369 kDefaultPriority,
2370 &callback,
2371 pool_.get(),
2372 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142373
2374 // Second job will be started during the first callback, and will
2375 // asynchronously complete with OK.
2376 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2377 pool_->Flush();
2378 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2379 EXPECT_EQ(OK, callback.WaitForNestedResult());
2380}
2381
[email protected]25eea382010-07-10 23:55:262382// Cancel a pending socket request while we're at max sockets,
2383// and verify that the backup socket firing doesn't cause a crash.
2384TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2385 // Max 4 sockets globally, max 4 sockets per group.
2386 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222387 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262388
[email protected]4baaf9d2010-08-31 15:15:442389 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2390 // timer.
[email protected]25eea382010-07-10 23:55:262391 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2392 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102393 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132394 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2395 params_,
2396 kDefaultPriority,
2397 &callback,
2398 pool_.get(),
2399 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262400
2401 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2402 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2403 ClientSocketHandle handles[kDefaultMaxSockets];
2404 for (int i = 1; i < kDefaultMaxSockets; ++i) {
[email protected]f1f3f0f82011-10-01 20:38:102405 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132406 EXPECT_EQ(OK, handles[i].Init("bar",
2407 params_,
2408 kDefaultPriority,
2409 &callback,
2410 pool_.get(),
2411 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262412 }
2413
2414 MessageLoop::current()->RunAllPending();
2415
2416 // Cancel the pending request.
2417 handle.Reset();
2418
2419 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082420 base::PlatformThread::Sleep(
2421 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]25eea382010-07-10 23:55:262422
2423 MessageLoop::current()->RunAllPending();
2424 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2425}
2426
[email protected]3f00be82010-09-27 19:50:022427TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442428 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2429 pool_->EnableConnectBackupJobs();
2430
2431 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2432 // timer.
2433 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2434 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102435 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132436 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2437 params_,
2438 kDefaultPriority,
2439 &callback,
2440 pool_.get(),
2441 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442442 ASSERT_TRUE(pool_->HasGroup("bar"));
2443 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2444
2445 // Cancel the socket request. This should cancel the backup timer. Wait for
2446 // the backup time to see if it indeed got canceled.
2447 handle.Reset();
2448 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082449 base::PlatformThread::Sleep(
2450 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]4baaf9d2010-08-31 15:15:442451 MessageLoop::current()->RunAllPending();
2452 ASSERT_TRUE(pool_->HasGroup("bar"));
2453 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2454}
2455
[email protected]3f00be82010-09-27 19:50:022456TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2457 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2458 pool_->EnableConnectBackupJobs();
2459
2460 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2461 // timer.
2462 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2463 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:102464 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132465 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2466 params_,
2467 kDefaultPriority,
2468 &callback,
2469 pool_.get(),
2470 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022471 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2472 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102473 TestOldCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132474 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2475 params_,
2476 kDefaultPriority,
2477 &callback2,
2478 pool_.get(),
2479 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022480 ASSERT_TRUE(pool_->HasGroup("bar"));
2481 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2482
2483 // Cancel request 1 and then complete request 2. With the requests finished,
2484 // the backup timer should be cancelled.
2485 handle.Reset();
2486 EXPECT_EQ(OK, callback2.WaitForResult());
2487 // Wait for the backup timer to fire (add some slop to ensure it fires)
[email protected]f214f8792011-01-01 02:17:082488 base::PlatformThread::Sleep(
2489 ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
[email protected]3f00be82010-09-27 19:50:022490 MessageLoop::current()->RunAllPending();
2491}
2492
[email protected]eb5a99382010-07-11 03:18:262493// Test delayed socket binding for the case where we have two connects,
2494// and while one is waiting on a connect, the other frees up.
2495// The socket waiting on a connect should switch immediately to the freed
2496// up socket.
2497TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2499 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2500
2501 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102502 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132503 EXPECT_EQ(ERR_IO_PENDING,
2504 handle1.Init("a",
2505 params_,
2506 kDefaultPriority,
2507 &callback,
2508 pool_.get(),
2509 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262510 EXPECT_EQ(OK, callback.WaitForResult());
2511
2512 // No idle sockets, no pending jobs.
2513 EXPECT_EQ(0, pool_->IdleSocketCount());
2514 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2515
2516 // Create a second socket to the same host, but this one will wait.
2517 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2518 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132519 EXPECT_EQ(ERR_IO_PENDING,
2520 handle2.Init("a",
2521 params_,
2522 kDefaultPriority,
2523 &callback,
2524 pool_.get(),
2525 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262526 // No idle sockets, and one connecting job.
2527 EXPECT_EQ(0, pool_->IdleSocketCount());
2528 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2529
2530 // Return the first handle to the pool. This will initiate the delayed
2531 // binding.
2532 handle1.Reset();
2533
2534 MessageLoop::current()->RunAllPending();
2535
2536 // Still no idle sockets, still one pending connect job.
2537 EXPECT_EQ(0, pool_->IdleSocketCount());
2538 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2539
2540 // The second socket connected, even though it was a Waiting Job.
2541 EXPECT_EQ(OK, callback.WaitForResult());
2542
2543 // And we can see there is still one job waiting.
2544 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2545
2546 // Finally, signal the waiting Connect.
2547 client_socket_factory_.SignalJobs();
2548 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2549
2550 MessageLoop::current()->RunAllPending();
2551}
2552
2553// Test delayed socket binding when a group is at capacity and one
2554// of the group's sockets frees up.
2555TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2556 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2557 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2558
2559 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102560 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132561 EXPECT_EQ(ERR_IO_PENDING,
2562 handle1.Init("a",
2563 params_,
2564 kDefaultPriority,
2565 &callback,
2566 pool_.get(),
2567 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262568 EXPECT_EQ(OK, callback.WaitForResult());
2569
2570 // No idle sockets, no pending jobs.
2571 EXPECT_EQ(0, pool_->IdleSocketCount());
2572 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2573
2574 // Create a second socket to the same host, but this one will wait.
2575 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2576 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132577 EXPECT_EQ(ERR_IO_PENDING,
2578 handle2.Init("a",
2579 params_,
2580 kDefaultPriority,
2581 &callback,
2582 pool_.get(),
2583 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262584 // No idle sockets, and one connecting job.
2585 EXPECT_EQ(0, pool_->IdleSocketCount());
2586 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2587
2588 // Return the first handle to the pool. This will initiate the delayed
2589 // binding.
2590 handle1.Reset();
2591
2592 MessageLoop::current()->RunAllPending();
2593
2594 // Still no idle sockets, still one pending connect job.
2595 EXPECT_EQ(0, pool_->IdleSocketCount());
2596 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2597
2598 // The second socket connected, even though it was a Waiting Job.
2599 EXPECT_EQ(OK, callback.WaitForResult());
2600
2601 // And we can see there is still one job waiting.
2602 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2603
2604 // Finally, signal the waiting Connect.
2605 client_socket_factory_.SignalJobs();
2606 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2607
2608 MessageLoop::current()->RunAllPending();
2609}
2610
2611// Test out the case where we have one socket connected, one
2612// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512613// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262614// should complete, by taking the first socket's idle socket.
2615TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2616 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2617 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2618
2619 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102620 TestOldCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132621 EXPECT_EQ(ERR_IO_PENDING,
2622 handle1.Init("a",
2623 params_,
2624 kDefaultPriority,
2625 &callback,
2626 pool_.get(),
2627 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262628 EXPECT_EQ(OK, callback.WaitForResult());
2629
2630 // No idle sockets, no pending jobs.
2631 EXPECT_EQ(0, pool_->IdleSocketCount());
2632 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2633
2634 // Create a second socket to the same host, but this one will wait.
2635 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2636 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132637 EXPECT_EQ(ERR_IO_PENDING,
2638 handle2.Init("a",
2639 params_,
2640 kDefaultPriority,
2641 &callback,
2642 pool_.get(),
2643 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262644 // No idle sockets, and one connecting job.
2645 EXPECT_EQ(0, pool_->IdleSocketCount());
2646 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2647
2648 // Return the first handle to the pool. This will initiate the delayed
2649 // binding.
2650 handle1.Reset();
2651
2652 MessageLoop::current()->RunAllPending();
2653
2654 // Still no idle sockets, still one pending connect job.
2655 EXPECT_EQ(0, pool_->IdleSocketCount());
2656 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2657
2658 // The second socket connected, even though it was a Waiting Job.
2659 EXPECT_EQ(OK, callback.WaitForResult());
2660
2661 // And we can see there is still one job waiting.
2662 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2663
2664 // Finally, signal the waiting Connect.
2665 client_socket_factory_.SignalJobs();
2666 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2667
2668 MessageLoop::current()->RunAllPending();
2669}
2670
[email protected]2abfe90a2010-08-25 17:49:512671// Cover the case where on an available socket slot, we have one pending
2672// request that completes synchronously, thereby making the Group empty.
2673TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2674 const int kUnlimitedSockets = 100;
2675 const int kOneSocketPerGroup = 1;
2676 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2677
2678 // Make the first request asynchronous fail.
2679 // This will free up a socket slot later.
2680 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2681
2682 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102683 TestOldCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132684 EXPECT_EQ(ERR_IO_PENDING,
2685 handle1.Init("a",
2686 params_,
2687 kDefaultPriority,
2688 &callback1,
2689 pool_.get(),
2690 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512691 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2692
2693 // Make the second request synchronously fail. This should make the Group
2694 // empty.
2695 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2696 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102697 TestOldCompletionCallback callback2;
[email protected]2abfe90a2010-08-25 17:49:512698 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2699 // when created.
[email protected]2431756e2010-09-29 20:26:132700 EXPECT_EQ(ERR_IO_PENDING,
2701 handle2.Init("a",
2702 params_,
2703 kDefaultPriority,
2704 &callback2,
2705 pool_.get(),
2706 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512707
2708 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2709
2710 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2711 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2712 EXPECT_FALSE(pool_->HasGroup("a"));
2713}
2714
[email protected]e1b54dc2010-10-06 21:27:222715TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2716 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2717
2718 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2719
2720 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102721 TestOldCompletionCallback callback1;
[email protected]e1b54dc2010-10-06 21:27:222722 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2723 params_,
2724 kDefaultPriority,
2725 &callback1,
2726 pool_.get(),
2727 BoundNetLog()));
2728
2729 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102730 TestOldCompletionCallback callback2;
[email protected]e1b54dc2010-10-06 21:27:222731 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2732 params_,
2733 kDefaultPriority,
2734 &callback2,
2735 pool_.get(),
2736 BoundNetLog()));
2737 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102738 TestOldCompletionCallback callback3;
[email protected]e1b54dc2010-10-06 21:27:222739 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2740 params_,
2741 kDefaultPriority,
2742 &callback3,
2743 pool_.get(),
2744 BoundNetLog()));
2745
2746 EXPECT_EQ(OK, callback1.WaitForResult());
2747 EXPECT_EQ(OK, callback2.WaitForResult());
2748 EXPECT_EQ(OK, callback3.WaitForResult());
2749
2750 // Use the socket.
2751 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2752 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2753
2754 handle1.Reset();
2755 handle2.Reset();
2756 handle3.Reset();
2757
2758 EXPECT_EQ(OK, handle1.Init("a",
2759 params_,
2760 kDefaultPriority,
2761 &callback1,
2762 pool_.get(),
2763 BoundNetLog()));
2764 EXPECT_EQ(OK, handle2.Init("a",
2765 params_,
2766 kDefaultPriority,
2767 &callback2,
2768 pool_.get(),
2769 BoundNetLog()));
2770 EXPECT_EQ(OK, handle3.Init("a",
2771 params_,
2772 kDefaultPriority,
2773 &callback3,
2774 pool_.get(),
2775 BoundNetLog()));
2776
2777 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2778 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2779 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2780}
2781
[email protected]2c2bef152010-10-13 00:55:032782TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2783 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2784 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2785
2786 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2787
2788 ASSERT_TRUE(pool_->HasGroup("a"));
2789 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2790 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2791
2792 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102793 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032794 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2795 params_,
2796 kDefaultPriority,
2797 &callback1,
2798 pool_.get(),
2799 BoundNetLog()));
2800
2801 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102802 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032803 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2804 params_,
2805 kDefaultPriority,
2806 &callback2,
2807 pool_.get(),
2808 BoundNetLog()));
2809
2810 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2811 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2812
2813 EXPECT_EQ(OK, callback1.WaitForResult());
2814 EXPECT_EQ(OK, callback2.WaitForResult());
2815 handle1.Reset();
2816 handle2.Reset();
2817
2818 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2819 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2820}
2821
2822TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2823 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2824 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2825
2826 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102827 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032828 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2829 params_,
2830 kDefaultPriority,
2831 &callback1,
2832 pool_.get(),
2833 BoundNetLog()));
2834
2835 ASSERT_TRUE(pool_->HasGroup("a"));
2836 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2837 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2838
2839 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2840
2841 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2842 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2843
2844 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102845 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032846 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2847 params_,
2848 kDefaultPriority,
2849 &callback2,
2850 pool_.get(),
2851 BoundNetLog()));
2852
2853 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2854 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2855
2856 EXPECT_EQ(OK, callback1.WaitForResult());
2857 EXPECT_EQ(OK, callback2.WaitForResult());
2858 handle1.Reset();
2859 handle2.Reset();
2860
2861 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2862 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2863}
2864
2865TEST_F(ClientSocketPoolBaseTest,
2866 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2867 CreatePool(4, 4);
2868 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2869
2870 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102871 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032872 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2873 params_,
2874 kDefaultPriority,
2875 &callback1,
2876 pool_.get(),
2877 BoundNetLog()));
2878
2879 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:102880 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:032881 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2882 params_,
2883 kDefaultPriority,
2884 &callback2,
2885 pool_.get(),
2886 BoundNetLog()));
2887
2888 ClientSocketHandle handle3;
[email protected]f1f3f0f82011-10-01 20:38:102889 TestOldCompletionCallback callback3;
[email protected]2c2bef152010-10-13 00:55:032890 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2891 params_,
2892 kDefaultPriority,
2893 &callback3,
2894 pool_.get(),
2895 BoundNetLog()));
2896
2897 ASSERT_TRUE(pool_->HasGroup("a"));
2898 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2899 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2900
2901 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2902
2903 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2904 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2905
2906 EXPECT_EQ(OK, callback1.WaitForResult());
2907 EXPECT_EQ(OK, callback2.WaitForResult());
2908 EXPECT_EQ(OK, callback3.WaitForResult());
2909 handle1.Reset();
2910 handle2.Reset();
2911 handle3.Reset();
2912
2913 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2914 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2915}
2916
2917TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2918 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2919 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2920
2921 ASSERT_FALSE(pool_->HasGroup("a"));
2922
2923 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2924 BoundNetLog());
2925
2926 ASSERT_TRUE(pool_->HasGroup("a"));
2927 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2928
2929 ASSERT_FALSE(pool_->HasGroup("b"));
2930
2931 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2932 BoundNetLog());
2933
2934 ASSERT_FALSE(pool_->HasGroup("b"));
2935}
2936
2937TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2938 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2939 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2940
2941 ASSERT_FALSE(pool_->HasGroup("a"));
2942
2943 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2944 BoundNetLog());
2945
2946 ASSERT_TRUE(pool_->HasGroup("a"));
2947 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2948
2949 ASSERT_FALSE(pool_->HasGroup("b"));
2950
2951 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2952 BoundNetLog());
2953
2954 ASSERT_TRUE(pool_->HasGroup("b"));
2955 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2956}
2957
2958TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2959 CreatePool(4, 4);
2960 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2961
2962 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102963 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032964 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2965 params_,
2966 kDefaultPriority,
2967 &callback1,
2968 pool_.get(),
2969 BoundNetLog()));
2970 ASSERT_EQ(OK, callback1.WaitForResult());
2971 handle1.Reset();
2972
2973 ASSERT_TRUE(pool_->HasGroup("a"));
2974 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2975 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2976
2977 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2978
2979 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2980 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2981}
2982
2983TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2984 CreatePool(4, 4);
2985 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2986
2987 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:102988 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:032989 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2990 params_,
2991 kDefaultPriority,
2992 &callback1,
2993 pool_.get(),
2994 BoundNetLog()));
2995 ASSERT_EQ(OK, callback1.WaitForResult());
2996
2997 ASSERT_TRUE(pool_->HasGroup("a"));
2998 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2999 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3000 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3001
3002 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3003
3004 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3005 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3006 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3007}
3008
3009TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
3010 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3011 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3012
3013 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3014 BoundNetLog());
3015
3016 ASSERT_TRUE(pool_->HasGroup("a"));
3017 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3018 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
3019
3020 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
3021 BoundNetLog());
3022
3023 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3024 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
3025}
3026
[email protected]3c819f522010-12-02 02:03:123027TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
3028 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3029 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
3030
3031 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3032 BoundNetLog());
3033
3034 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]fd2e53e2011-01-14 20:40:523035
3036 connect_job_factory_->set_job_type(
3037 TestConnectJob::kMockAdditionalErrorStateJob);
3038 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
3039 BoundNetLog());
3040
3041 ASSERT_FALSE(pool_->HasGroup("a"));
[email protected]3c819f522010-12-02 02:03:123042}
3043
[email protected]2c2bef152010-10-13 00:55:033044TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
3045 CreatePool(4, 4);
3046 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3047
3048 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3049
3050 ASSERT_TRUE(pool_->HasGroup("a"));
3051 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3052 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3053
3054 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3055 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3056 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3057
3058 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103059 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033060 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3061 params_,
3062 kDefaultPriority,
3063 &callback1,
3064 pool_.get(),
3065 BoundNetLog()));
3066 ASSERT_EQ(OK, callback1.WaitForResult());
3067
3068 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103069 TestOldCompletionCallback callback2;
[email protected]2c2bef152010-10-13 00:55:033070 int rv = handle2.Init("a",
3071 params_,
3072 kDefaultPriority,
3073 &callback2,
3074 pool_.get(),
3075 BoundNetLog());
3076 if (rv != OK) {
3077 EXPECT_EQ(ERR_IO_PENDING, rv);
3078 EXPECT_EQ(OK, callback2.WaitForResult());
3079 }
3080
3081 handle1.Reset();
3082 handle2.Reset();
3083
3084 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3085
3086 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3087 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3088 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
3089}
3090
3091TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
3092 CreatePool(4, 4);
3093 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3094
3095 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3096
3097 ASSERT_TRUE(pool_->HasGroup("a"));
3098 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3099 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3100
3101 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3102 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
3103 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3104
3105 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
3106 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3107 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3108
3109 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3110 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
3111 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3112}
3113
3114TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3115 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3116 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3117
3118 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3119
3120 ASSERT_TRUE(pool_->HasGroup("a"));
3121 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3122 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3123
3124 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103125 TestOldCompletionCallback callback1;
[email protected]2c2bef152010-10-13 00:55:033126 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3127 params_,
3128 kDefaultPriority,
3129 &callback1,
3130 pool_.get(),
3131 BoundNetLog()));
3132
3133 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3134 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3135
3136 ASSERT_EQ(OK, callback1.WaitForResult());
3137
3138 handle1.Reset();
3139
3140 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3141}
3142
[email protected]dcbe168a2010-12-02 03:14:463143// http://crbug.com/64940 regression test.
3144TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3145 const int kMaxTotalSockets = 3;
3146 const int kMaxSocketsPerGroup = 2;
3147 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3148 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3149
3150 // Note that group name ordering matters here. "a" comes before "b", so
3151 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3152
3153 // Set up one idle socket in "a".
3154 ClientSocketHandle handle1;
[email protected]f1f3f0f82011-10-01 20:38:103155 TestOldCompletionCallback callback1;
[email protected]dcbe168a2010-12-02 03:14:463156 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3157 params_,
3158 kDefaultPriority,
3159 &callback1,
3160 pool_.get(),
3161 BoundNetLog()));
3162
3163 ASSERT_EQ(OK, callback1.WaitForResult());
3164 handle1.Reset();
3165 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3166
3167 // Set up two active sockets in "b".
3168 ClientSocketHandle handle2;
[email protected]f1f3f0f82011-10-01 20:38:103169 TestOldCompletionCallback callback2;
[email protected]dcbe168a2010-12-02 03:14:463170 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3171 params_,
3172 kDefaultPriority,
3173 &callback1,
3174 pool_.get(),
3175 BoundNetLog()));
3176 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3177 params_,
3178 kDefaultPriority,
3179 &callback2,
3180 pool_.get(),
3181 BoundNetLog()));
3182
3183 ASSERT_EQ(OK, callback1.WaitForResult());
3184 ASSERT_EQ(OK, callback2.WaitForResult());
3185 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3186 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3187
3188 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3189 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3190 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3191 // sockets for "a", and "b" should still have 2 active sockets.
3192
3193 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3194 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3195 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3196 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3197 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3198 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3199 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3200
3201 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3202 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3203 // "a" should result in closing 1 for "b".
3204 handle1.Reset();
3205 handle2.Reset();
3206 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3207 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3208
3209 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3210 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3211 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3212 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3213 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3214 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3215 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3216}
3217
[email protected]b7b8be42011-07-12 12:46:413218TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3220 pool_->EnableConnectBackupJobs();
3221
3222 // Make the ConnectJob hang until it times out, shorten the timeout.
3223 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3224 connect_job_factory_->set_timeout_duration(
3225 base::TimeDelta::FromMilliseconds(500));
3226 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3227 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3228 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]a9fc8fc2011-05-10 02:41:073229
[email protected]b7b8be42011-07-12 12:46:413230 // Verify the backup timer doesn't create a backup job, by making
3231 // the backup job a pending job instead of a waiting job, so it
3232 // *would* complete if it were created.
[email protected]a9fc8fc2011-05-10 02:41:073233 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]b7b8be42011-07-12 12:46:413234 MessageLoop::current()->PostDelayedTask(FROM_HERE,
3235 new MessageLoop::QuitTask(), 1000);
3236 MessageLoop::current()->Run();
[email protected]a9fc8fc2011-05-10 02:41:073237 EXPECT_FALSE(pool_->HasGroup("a"));
3238}
3239
[email protected]b7b8be42011-07-12 12:46:413240TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) {
[email protected]a9fc8fc2011-05-10 02:41:073241 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3242 pool_->EnableConnectBackupJobs();
3243
3244 // Make the ConnectJob hang forever.
3245 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
3246 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3247 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3248 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3249 MessageLoop::current()->RunAllPending();
3250
3251 // Make the backup job be a pending job, so it completes normally.
3252 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3253 ClientSocketHandle handle;
[email protected]f1f3f0f82011-10-01 20:38:103254 TestOldCompletionCallback callback;
[email protected]a9fc8fc2011-05-10 02:41:073255 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
3256 params_,
3257 kDefaultPriority,
3258 &callback,
3259 pool_.get(),
3260 BoundNetLog()));
[email protected]b7b8be42011-07-12 12:46:413261 // Timer has started, but the backup connect job shouldn't be created yet.
[email protected]a9fc8fc2011-05-10 02:41:073262 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3263 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3264 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3265 ASSERT_EQ(OK, callback.WaitForResult());
3266
3267 // The hung connect job should still be there, but everything else should be
3268 // complete.
3269 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3270 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3271 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3272}
3273
[email protected]f6d1d6eb2009-06-24 20:16:093274} // namespace
3275
3276} // namespace net