blob: d145bdf45d4442cd6c8402c272ae6c142866edf6 [file] [log] [blame]
[email protected]7fc5b09a2010-02-27 00:07:381// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]f6d1d6eb2009-06-24 20:16:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]ab838892009-06-30 18:49:055#include "net/socket/client_socket_pool_base.h"
[email protected]f6d1d6eb2009-06-24 20:16:096
[email protected]2041cf342010-02-19 03:15:597#include "base/callback.h"
[email protected]f6d1d6eb2009-06-24 20:16:098#include "base/compiler_specific.h"
9#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:3410#include "base/platform_thread.h"
[email protected]df4b4ef2010-07-12 18:25:2111#include "base/ref_counted.h"
[email protected]c9d6a1d2009-07-14 16:15:2012#include "base/scoped_vector.h"
[email protected]e83326f2010-07-31 17:29:2513#include "base/string_number_conversions.h"
[email protected]43a21b82010-06-10 21:30:5414#include "base/string_util.h"
[email protected]d8eb84242010-09-25 02:25:0615#include "net/base/net_errors.h"
[email protected]9e743cd2010-03-16 07:03:5316#include "net/base/net_log.h"
17#include "net/base/net_log_unittest.h"
[email protected]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "net/base/test_completion_callback.h"
[email protected]277d5942010-08-11 21:02:3520#include "net/http/http_response_headers.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_factory.h"
23#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0024#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1725#include "net/socket/socket_test_util.h"
[email protected]d0672be2010-10-20 16:30:1926#include "net/socket/ssl_host_info.h"
[email protected]f6d1d6eb2009-06-24 20:16:0927#include "testing/gtest/include/gtest/gtest.h"
28
29namespace net {
30
31namespace {
32
[email protected]211d21722009-07-22 15:48:5333const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2034const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5235const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0136
[email protected]df4b4ef2010-07-12 18:25:2137class TestSocketParams : public base::RefCounted<TestSocketParams> {
38 private:
39 friend class base::RefCounted<TestSocketParams>;
40 ~TestSocketParams() {}
41};
[email protected]7fc5b09a2010-02-27 00:07:3842typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4943
[email protected]f6d1d6eb2009-06-24 20:16:0944class MockClientSocket : public ClientSocket {
45 public:
[email protected]0f873e82010-09-02 16:09:0146 MockClientSocket() : connected_(false), was_used_to_convey_data_(false) {}
[email protected]f6d1d6eb2009-06-24 20:16:0947
[email protected]ab838892009-06-30 18:49:0548 // Socket methods:
49 virtual int Read(
50 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
51 return ERR_UNEXPECTED;
52 }
53
54 virtual int Write(
[email protected]0f873e82010-09-02 16:09:0155 IOBuffer* /* buf */, int len, CompletionCallback* /* callback */) {
56 was_used_to_convey_data_ = true;
57 return len;
[email protected]ab838892009-06-30 18:49:0558 }
[email protected]06650c52010-06-03 00:49:1759 virtual bool SetReceiveBufferSize(int32 size) { return true; }
60 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0561
[email protected]f6d1d6eb2009-06-24 20:16:0962 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0563
[email protected]a2006ece2010-04-23 16:44:0264 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0965 connected_ = true;
66 return OK;
67 }
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]ab838892009-06-30 18:49:0569 virtual void Disconnect() { connected_ = false; }
70 virtual bool IsConnected() const { return connected_; }
71 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0172
[email protected]ac9eec62010-02-20 18:50:3873 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1674 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0975 }
[email protected]f6d1d6eb2009-06-24 20:16:0976
[email protected]a2006ece2010-04-23 16:44:0277 virtual const BoundNetLog& NetLog() const {
78 return net_log_;
79 }
80
[email protected]9b5614a2010-08-25 20:29:4581 virtual void SetSubresourceSpeculation() {}
82 virtual void SetOmniboxSpeculation() {}
[email protected]0f873e82010-09-02 16:09:0183 virtual bool WasEverUsed() const { return was_used_to_convey_data_; }
[email protected]7f7e92392010-10-26 18:29:2984 virtual bool UsingTCPFastOpen() const { return false; }
[email protected]9b5614a2010-08-25 20:29:4585
[email protected]f6d1d6eb2009-06-24 20:16:0986 private:
87 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0288 BoundNetLog net_log_;
[email protected]0f873e82010-09-02 16:09:0189 bool was_used_to_convey_data_;
[email protected]f6d1d6eb2009-06-24 20:16:0990
[email protected]ab838892009-06-30 18:49:0591 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0992};
93
[email protected]5fc08e32009-07-15 17:09:5794class TestConnectJob;
95
[email protected]f6d1d6eb2009-06-24 20:16:0996class MockClientSocketFactory : public ClientSocketFactory {
97 public:
[email protected]ab838892009-06-30 18:49:0598 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0999
[email protected]0a0b7682010-08-25 17:08:07100 virtual ClientSocket* CreateTCPClientSocket(
101 const AddressList& addresses,
102 NetLog* /* net_log */,
103 const NetLog::Source& /*source*/) {
[email protected]f6d1d6eb2009-06-24 20:16:09104 allocation_count_++;
[email protected]ab838892009-06-30 18:49:05105 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:09106 }
107
108 virtual SSLClientSocket* CreateSSLClientSocket(
[email protected]e60e47a2010-07-14 03:37:18109 ClientSocketHandle* transport_socket,
[email protected]4f4de7e62010-11-12 19:55:27110 const HostPortPair& host_and_port,
[email protected]7ab5bbd12010-10-19 13:33:21111 const SSLConfig& ssl_config,
[email protected]d8fbf582010-11-04 21:51:12112 SSLHostInfo* ssl_host_info,
[email protected]345c613b2010-11-22 19:33:18113 DnsCertProvenanceChecker* dns_cert_checker) {
[email protected]f6d1d6eb2009-06-24 20:16:09114 NOTIMPLEMENTED();
[email protected]7ab5bbd12010-10-19 13:33:21115 delete ssl_host_info;
[email protected]f6d1d6eb2009-06-24 20:16:09116 return NULL;
117 }
118
[email protected]5fc08e32009-07-15 17:09:57119 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
120 void SignalJobs();
121
[email protected]f6d1d6eb2009-06-24 20:16:09122 int allocation_count() const { return allocation_count_; }
123
[email protected]f6d1d6eb2009-06-24 20:16:09124 private:
125 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57126 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09127};
128
[email protected]ab838892009-06-30 18:49:05129class TestConnectJob : public ConnectJob {
130 public:
131 enum JobType {
132 kMockJob,
133 kMockFailingJob,
134 kMockPendingJob,
135 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57136 kMockWaitingJob,
137 kMockAdvancingLoadStateJob,
[email protected]e772db3f2010-07-12 18:11:13138 kMockRecoverableJob,
139 kMockPendingRecoverableJob,
[email protected]e60e47a2010-07-14 03:37:18140 kMockAdditionalErrorStateJob,
141 kMockPendingAdditionalErrorStateJob,
[email protected]ab838892009-06-30 18:49:05142 };
143
[email protected]994d4932010-07-12 17:55:13144 // The kMockPendingJob uses a slight delay before allowing the connect
145 // to complete.
146 static const int kPendingConnectDelay = 2;
147
[email protected]ab838892009-06-30 18:49:05148 TestConnectJob(JobType job_type,
149 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49150 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34151 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05152 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30153 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17154 NetLog* net_log)
155 : ConnectJob(group_name, timeout_duration, delegate,
156 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58157 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05158 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21159 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
[email protected]e60e47a2010-07-14 03:37:18160 load_state_(LOAD_STATE_IDLE),
161 store_additional_error_state_(false) {}
[email protected]ab838892009-06-30 18:49:05162
[email protected]974ebd62009-08-03 23:14:34163 void Signal() {
[email protected]e772db3f2010-07-12 18:11:13164 DoConnect(waiting_success_, true /* async */, false /* recoverable */);
[email protected]974ebd62009-08-03 23:14:34165 }
166
[email protected]46451352009-09-01 14:54:21167 virtual LoadState GetLoadState() const { return load_state_; }
168
[email protected]e60e47a2010-07-14 03:37:18169 virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {
170 if (store_additional_error_state_) {
171 // Set all of the additional error state fields in some way.
172 handle->set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43173 HttpResponseInfo info;
174 info.headers = new HttpResponseHeaders("");
175 handle->set_ssl_error_response_info(info);
[email protected]e60e47a2010-07-14 03:37:18176 }
177 }
178
[email protected]974ebd62009-08-03 23:14:34179 private:
[email protected]ab838892009-06-30 18:49:05180 // ConnectJob methods:
181
[email protected]974ebd62009-08-03 23:14:34182 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05183 AddressList ignored;
[email protected]0a0b7682010-08-25 17:08:07184 client_socket_factory_->CreateTCPClientSocket(
185 ignored, NULL, net::NetLog::Source());
[email protected]6e713f02009-08-06 02:56:40186 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05187 switch (job_type_) {
188 case kMockJob:
[email protected]e772db3f2010-07-12 18:11:13189 return DoConnect(true /* successful */, false /* sync */,
190 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05191 case kMockFailingJob:
[email protected]e772db3f2010-07-12 18:11:13192 return DoConnect(false /* error */, false /* sync */,
193 false /* recoverable */);
[email protected]ab838892009-06-30 18:49:05194 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57195 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47196
197 // Depending on execution timings, posting a delayed task can result
198 // in the task getting executed the at the earliest possible
199 // opportunity or only after returning once from the message loop and
200 // then a second call into the message loop. In order to make behavior
201 // more deterministic, we change the default delay to 2ms. This should
202 // always require us to wait for the second call into the message loop.
203 //
204 // N.B. The correct fix for this and similar timing problems is to
205 // abstract time for the purpose of unittests. Unfortunately, we have
206 // a lot of third-party components that directly call the various
207 // time functions, so this change would be rather invasive.
208 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05209 FROM_HERE,
210 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47211 &TestConnectJob::DoConnect,
212 true /* successful */,
[email protected]e772db3f2010-07-12 18:11:13213 true /* async */,
214 false /* recoverable */),
[email protected]994d4932010-07-12 17:55:13215 kPendingConnectDelay);
[email protected]ab838892009-06-30 18:49:05216 return ERR_IO_PENDING;
217 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57218 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47219 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05220 FROM_HERE,
221 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47222 &TestConnectJob::DoConnect,
223 false /* error */,
[email protected]e772db3f2010-07-12 18:11:13224 true /* async */,
225 false /* recoverable */),
[email protected]6b175382009-10-13 06:47:47226 2);
[email protected]ab838892009-06-30 18:49:05227 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57228 case kMockWaitingJob:
229 client_socket_factory_->WaitForSignal(this);
230 waiting_success_ = true;
231 return ERR_IO_PENDING;
232 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46233 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57234 FROM_HERE,
235 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46236 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57237 return ERR_IO_PENDING;
[email protected]e772db3f2010-07-12 18:11:13238 case kMockRecoverableJob:
239 return DoConnect(false /* error */, false /* sync */,
240 true /* recoverable */);
241 case kMockPendingRecoverableJob:
242 set_load_state(LOAD_STATE_CONNECTING);
243 MessageLoop::current()->PostDelayedTask(
244 FROM_HERE,
245 method_factory_.NewRunnableMethod(
246 &TestConnectJob::DoConnect,
247 false /* error */,
248 true /* async */,
249 true /* recoverable */),
250 2);
251 return ERR_IO_PENDING;
[email protected]e60e47a2010-07-14 03:37:18252 case kMockAdditionalErrorStateJob:
253 store_additional_error_state_ = true;
254 return DoConnect(false /* error */, false /* sync */,
255 false /* recoverable */);
256 case kMockPendingAdditionalErrorStateJob:
257 set_load_state(LOAD_STATE_CONNECTING);
258 store_additional_error_state_ = true;
259 MessageLoop::current()->PostDelayedTask(
260 FROM_HERE,
261 method_factory_.NewRunnableMethod(
262 &TestConnectJob::DoConnect,
263 false /* error */,
264 true /* async */,
265 false /* recoverable */),
266 2);
267 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05268 default:
269 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40270 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05271 return ERR_FAILED;
272 }
273 }
274
[email protected]46451352009-09-01 14:54:21275 void set_load_state(LoadState load_state) { load_state_ = load_state; }
276
[email protected]e772db3f2010-07-12 18:11:13277 int DoConnect(bool succeed, bool was_async, bool recoverable) {
278 int result = OK;
[email protected]ab838892009-06-30 18:49:05279 if (succeed) {
[email protected]a2006ece2010-04-23 16:44:02280 socket()->Connect(NULL);
[email protected]e772db3f2010-07-12 18:11:13281 } else if (recoverable) {
282 result = ERR_PROXY_AUTH_REQUESTED;
[email protected]6e713f02009-08-06 02:56:40283 } else {
[email protected]e772db3f2010-07-12 18:11:13284 result = ERR_CONNECTION_FAILED;
[email protected]6e713f02009-08-06 02:56:40285 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05286 }
[email protected]2ab05b52009-07-01 23:57:58287
288 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30289 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05290 return result;
291 }
292
[email protected]cfa8228c2010-06-17 01:07:56293 // This function helps simulate the progress of load states on a ConnectJob.
294 // Each time it is called it advances the load state and posts a task to be
295 // called again. It stops at the last connecting load state (the one
296 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57297 void AdvanceLoadState(LoadState state) {
298 int tmp = state;
299 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56300 if (tmp < LOAD_STATE_SENDING_REQUEST) {
301 state = static_cast<LoadState>(tmp);
302 set_load_state(state);
303 MessageLoop::current()->PostTask(
304 FROM_HERE,
305 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
306 state));
307 }
[email protected]5fc08e32009-07-15 17:09:57308 }
309
310 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05311 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57312 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05313 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21314 LoadState load_state_;
[email protected]e60e47a2010-07-14 03:37:18315 bool store_additional_error_state_;
[email protected]ab838892009-06-30 18:49:05316
317 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
318};
319
[email protected]d80a4322009-08-14 07:07:49320class TestConnectJobFactory
321 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05322 public:
[email protected]5fc08e32009-07-15 17:09:57323 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05324 : job_type_(TestConnectJob::kMockJob),
325 client_socket_factory_(client_socket_factory) {}
326
327 virtual ~TestConnectJobFactory() {}
328
329 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
330
[email protected]974ebd62009-08-03 23:14:34331 void set_timeout_duration(base::TimeDelta timeout_duration) {
332 timeout_duration_ = timeout_duration;
333 }
334
[email protected]ab838892009-06-30 18:49:05335 // ConnectJobFactory methods:
336
337 virtual ConnectJob* NewConnectJob(
338 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49339 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17340 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05341 return new TestConnectJob(job_type_,
342 group_name,
343 request,
[email protected]974ebd62009-08-03 23:14:34344 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05345 delegate,
[email protected]fd7b7c92009-08-20 19:38:30346 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17347 NULL);
[email protected]ab838892009-06-30 18:49:05348 }
349
[email protected]a796bcec2010-03-22 17:17:26350 virtual base::TimeDelta ConnectionTimeout() const {
351 return timeout_duration_;
352 }
353
[email protected]ab838892009-06-30 18:49:05354 private:
355 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34356 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57357 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05358
359 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
360};
361
362class TestClientSocketPool : public ClientSocketPool {
363 public:
364 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53365 int max_sockets,
[email protected]ab838892009-06-30 18:49:05366 int max_sockets_per_group,
[email protected]2431756e2010-09-29 20:26:13367 ClientSocketPoolHistograms* histograms,
[email protected]9bf28db2009-08-29 01:35:16368 base::TimeDelta unused_idle_socket_timeout,
369 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49370 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00371 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16372 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38373 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05374
[email protected]2431756e2010-09-29 20:26:13375 virtual ~TestClientSocketPool() {}
376
[email protected]ab838892009-06-30 18:49:05377 virtual int RequestSocket(
378 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49379 const void* params,
[email protected]ac790b42009-12-02 04:31:31380 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05381 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46382 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53383 const BoundNetLog& net_log) {
[email protected]df4b4ef2010-07-12 18:25:21384 const scoped_refptr<TestSocketParams>* casted_socket_params =
385 static_cast<const scoped_refptr<TestSocketParams>*>(params);
386 return base_.RequestSocket(group_name, *casted_socket_params, priority,
387 handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05388 }
389
[email protected]2c2bef152010-10-13 00:55:03390 virtual void RequestSockets(const std::string& group_name,
391 const void* params,
392 int num_sockets,
393 const BoundNetLog& net_log) {
394 const scoped_refptr<TestSocketParams>* casted_params =
395 static_cast<const scoped_refptr<TestSocketParams>*>(params);
396
397 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
398 }
399
[email protected]ab838892009-06-30 18:49:05400 virtual void CancelRequest(
401 const std::string& group_name,
[email protected]05ea9ff2010-07-15 19:08:21402 ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49403 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05404 }
405
406 virtual void ReleaseSocket(
407 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24408 ClientSocket* socket,
409 int id) {
410 base_.ReleaseSocket(group_name, socket, id);
411 }
412
413 virtual void Flush() {
414 base_.Flush();
[email protected]ab838892009-06-30 18:49:05415 }
416
417 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49418 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05419 }
420
[email protected]d80a4322009-08-14 07:07:49421 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05422
423 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49424 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05425 }
426
427 virtual LoadState GetLoadState(const std::string& group_name,
428 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49429 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05430 }
431
[email protected]ba00b492010-09-08 14:53:38432 virtual DictionaryValue* GetInfoAsValue(const std::string& name,
433 const std::string& type,
434 bool include_nested_pools) const {
[email protected]59d7a5a2010-08-30 16:44:27435 return base_.GetInfoAsValue(name, type);
436 }
437
[email protected]a796bcec2010-03-22 17:17:26438 virtual base::TimeDelta ConnectionTimeout() const {
439 return base_.ConnectionTimeout();
440 }
441
[email protected]2431756e2010-09-29 20:26:13442 virtual ClientSocketPoolHistograms* histograms() const {
[email protected]b89f7e42010-05-20 20:37:00443 return base_.histograms();
444 }
[email protected]a796bcec2010-03-22 17:17:26445
[email protected]d80a4322009-08-14 07:07:49446 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20447
[email protected]974ebd62009-08-03 23:14:34448 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49449 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34450 }
451
[email protected]2c2bef152010-10-13 00:55:03452 int NumActiveSocketsInGroup(const std::string& group_name) const {
453 return base_.NumActiveSocketsInGroup(group_name);
454 }
455
[email protected]2abfe90a2010-08-25 17:49:51456 bool HasGroup(const std::string& group_name) const {
457 return base_.HasGroup(group_name);
458 }
459
[email protected]9bf28db2009-08-29 01:35:16460 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
461
[email protected]06d94042010-08-25 01:45:22462 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
[email protected]43a21b82010-06-10 21:30:54463
[email protected]ab838892009-06-30 18:49:05464 private:
[email protected]d80a4322009-08-14 07:07:49465 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05466
467 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
468};
469
[email protected]a937a06d2009-08-19 21:19:24470} // namespace
471
[email protected]7fc5b09a2010-02-27 00:07:38472REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24473
474namespace {
475
[email protected]5fc08e32009-07-15 17:09:57476void MockClientSocketFactory::SignalJobs() {
477 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
478 it != waiting_jobs_.end(); ++it) {
479 (*it)->Signal();
480 }
481 waiting_jobs_.clear();
482}
483
[email protected]974ebd62009-08-03 23:14:34484class TestConnectJobDelegate : public ConnectJob::Delegate {
485 public:
486 TestConnectJobDelegate()
487 : have_result_(false), waiting_for_result_(false), result_(OK) {}
488 virtual ~TestConnectJobDelegate() {}
489
490 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
491 result_ = result;
[email protected]6e713f02009-08-06 02:56:40492 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07493 // socket.get() should be NULL iff result != OK
494 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34495 delete job;
496 have_result_ = true;
497 if (waiting_for_result_)
498 MessageLoop::current()->Quit();
499 }
500
501 int WaitForResult() {
502 DCHECK(!waiting_for_result_);
503 while (!have_result_) {
504 waiting_for_result_ = true;
505 MessageLoop::current()->Run();
506 waiting_for_result_ = false;
507 }
508 have_result_ = false; // auto-reset for next callback
509 return result_;
510 }
511
512 private:
513 bool have_result_;
514 bool waiting_for_result_;
515 int result_;
516};
517
[email protected]2431756e2010-09-29 20:26:13518class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09519 protected:
[email protected]b89f7e42010-05-20 20:37:00520 ClientSocketPoolBaseTest()
[email protected]df4b4ef2010-07-12 18:25:21521 : params_(new TestSocketParams()),
[email protected]2431756e2010-09-29 20:26:13522 histograms_("ClientSocketPoolTest") {}
523
524 virtual ~ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20525
[email protected]211d21722009-07-22 15:48:53526 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16527 CreatePoolWithIdleTimeouts(
528 max_sockets,
529 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00530 base::TimeDelta::FromSeconds(
531 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16532 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
533 }
534
535 void CreatePoolWithIdleTimeouts(
536 int max_sockets, int max_sockets_per_group,
537 base::TimeDelta unused_idle_socket_timeout,
538 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20539 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04540 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]2431756e2010-09-29 20:26:13541 pool_.reset(new TestClientSocketPool(max_sockets,
542 max_sockets_per_group,
543 &histograms_,
544 unused_idle_socket_timeout,
545 used_idle_socket_timeout,
546 connect_job_factory_));
[email protected]c9d6a1d2009-07-14 16:15:20547 }
[email protected]f6d1d6eb2009-06-24 20:16:09548
[email protected]ac790b42009-12-02 04:31:31549 int StartRequest(const std::string& group_name,
550 net::RequestPriority priority) {
[email protected]2431756e2010-09-29 20:26:13551 return test_base_.StartRequestUsingPool<
552 TestClientSocketPool, TestSocketParams>(
553 pool_.get(), group_name, priority, params_);
[email protected]f6d1d6eb2009-06-24 20:16:09554 }
555
[email protected]2431756e2010-09-29 20:26:13556 int GetOrderOfRequest(size_t index) const {
557 return test_base_.GetOrderOfRequest(index);
[email protected]f6d1d6eb2009-06-24 20:16:09558 }
559
[email protected]2431756e2010-09-29 20:26:13560 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
561 return test_base_.ReleaseOneConnection(keep_alive);
562 }
563
564 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
565 test_base_.ReleaseAllConnections(keep_alive);
566 }
567
568 TestSocketRequest* request(int i) { return test_base_.request(i); }
569 size_t requests_size() const { return test_base_.requests_size(); }
570 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
571 size_t completion_count() const { return test_base_.completion_count(); }
572
[email protected]f6d1d6eb2009-06-24 20:16:09573 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04574 TestConnectJobFactory* connect_job_factory_;
[email protected]df4b4ef2010-07-12 18:25:21575 scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:13576 ClientSocketPoolHistograms histograms_;
577 scoped_ptr<TestClientSocketPool> pool_;
578 ClientSocketPoolTest test_base_;
[email protected]f6d1d6eb2009-06-24 20:16:09579};
580
[email protected]974ebd62009-08-03 23:14:34581// Even though a timeout is specified, it doesn't time out on a synchronous
582// completion.
583TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
584 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06585 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49586 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03587 &ignored, NULL, kDefaultPriority,
588 internal::ClientSocketPoolBaseHelper::NORMAL,
589 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34590 scoped_ptr<TestConnectJob> job(
591 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12592 "a",
[email protected]974ebd62009-08-03 23:14:34593 request,
594 base::TimeDelta::FromMicroseconds(1),
595 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30596 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17597 NULL));
[email protected]974ebd62009-08-03 23:14:34598 EXPECT_EQ(OK, job->Connect());
599}
600
601TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
602 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06603 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17604 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53605
[email protected]d80a4322009-08-14 07:07:49606 TestClientSocketPoolBase::Request request(
[email protected]2c2bef152010-10-13 00:55:03607 &ignored, NULL, kDefaultPriority,
608 internal::ClientSocketPoolBaseHelper::NORMAL,
609 params_, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34610 // Deleted by TestConnectJobDelegate.
611 TestConnectJob* job =
612 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12613 "a",
[email protected]974ebd62009-08-03 23:14:34614 request,
615 base::TimeDelta::FromMicroseconds(1),
616 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30617 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17618 &log);
[email protected]974ebd62009-08-03 23:14:34619 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
620 PlatformThread::Sleep(1);
621 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30622
[email protected]06650c52010-06-03 00:49:17623 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46624 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53625 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17626 EXPECT_TRUE(LogContainsBeginEvent(
627 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46628 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17629 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
630 NetLog::PHASE_NONE));
631 EXPECT_TRUE(LogContainsEvent(
632 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53633 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46634 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17635 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
636 EXPECT_TRUE(LogContainsEndEvent(
637 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34638}
639
[email protected]5fc08e32009-07-15 17:09:57640TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53641 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20642
[email protected]f6d1d6eb2009-06-24 20:16:09643 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06644 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53645 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
646
[email protected]2431756e2010-09-29 20:26:13647 EXPECT_EQ(OK,
648 handle.Init("a",
649 params_,
650 kDefaultPriority,
651 &callback,
652 pool_.get(),
653 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09654 EXPECT_TRUE(handle.is_initialized());
655 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09656 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30657
[email protected]06650c52010-06-03 00:49:17658 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46659 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53660 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53661 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17662 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
663 NetLog::PHASE_NONE));
664 EXPECT_TRUE(LogContainsEvent(
665 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53666 NetLog::PHASE_NONE));
667 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17668 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09669}
670
[email protected]ab838892009-06-30 18:49:05671TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53672 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20673
[email protected]ab838892009-06-30 18:49:05674 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53675 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
676
[email protected]2431756e2010-09-29 20:26:13677 ClientSocketHandle handle;
678 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18679 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13680 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43681 HttpResponseInfo info;
682 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13683 handle.set_ssl_error_response_info(info);
684 EXPECT_EQ(ERR_CONNECTION_FAILED,
685 handle.Init("a",
686 params_,
687 kDefaultPriority,
688 &callback,
689 pool_.get(),
690 log.bound()));
691 EXPECT_FALSE(handle.socket());
692 EXPECT_FALSE(handle.is_ssl_error());
693 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30694
[email protected]06650c52010-06-03 00:49:17695 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27696 EXPECT_TRUE(LogContainsBeginEvent(
697 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17698 EXPECT_TRUE(LogContainsEvent(
699 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
700 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02701 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17702 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09703}
704
[email protected]211d21722009-07-22 15:48:53705TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
706 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
707
[email protected]9e743cd2010-03-16 07:03:53708 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30709
[email protected]211d21722009-07-22 15:48:53710 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
711 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
712 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
713 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
714
[email protected]2431756e2010-09-29 20:26:13715 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53716 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13717 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53718
719 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
720 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
721 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
722
[email protected]2431756e2010-09-29 20:26:13723 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53724
[email protected]2431756e2010-09-29 20:26:13725 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53726 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13727 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53728
729 EXPECT_EQ(1, GetOrderOfRequest(1));
730 EXPECT_EQ(2, GetOrderOfRequest(2));
731 EXPECT_EQ(3, GetOrderOfRequest(3));
732 EXPECT_EQ(4, GetOrderOfRequest(4));
733 EXPECT_EQ(5, GetOrderOfRequest(5));
734 EXPECT_EQ(6, GetOrderOfRequest(6));
735 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17736
737 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13738 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53739}
740
741TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
742 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
743
[email protected]9e743cd2010-03-16 07:03:53744 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30745
[email protected]211d21722009-07-22 15:48:53746 // Reach all limits: max total sockets, and max sockets per group.
747 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
748 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
749 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
750 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
751
[email protected]2431756e2010-09-29 20:26:13752 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53753 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13754 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53755
756 // Now create a new group and verify that we don't starve it.
757 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
758
[email protected]2431756e2010-09-29 20:26:13759 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53760
[email protected]2431756e2010-09-29 20:26:13761 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53762 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13763 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53764
765 EXPECT_EQ(1, GetOrderOfRequest(1));
766 EXPECT_EQ(2, GetOrderOfRequest(2));
767 EXPECT_EQ(3, GetOrderOfRequest(3));
768 EXPECT_EQ(4, GetOrderOfRequest(4));
769 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17770
771 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13772 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53773}
774
775TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
776 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
777
[email protected]ac790b42009-12-02 04:31:31778 EXPECT_EQ(OK, StartRequest("b", LOWEST));
779 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
780 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
781 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53782
[email protected]2431756e2010-09-29 20:26:13783 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53784 client_socket_factory_.allocation_count());
785
[email protected]ac790b42009-12-02 04:31:31786 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
787 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53789
[email protected]2431756e2010-09-29 20:26:13790 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53791
[email protected]2431756e2010-09-29 20:26:13792 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53793
794 // First 4 requests don't have to wait, and finish in order.
795 EXPECT_EQ(1, GetOrderOfRequest(1));
796 EXPECT_EQ(2, GetOrderOfRequest(2));
797 EXPECT_EQ(3, GetOrderOfRequest(3));
798 EXPECT_EQ(4, GetOrderOfRequest(4));
799
[email protected]ac790b42009-12-02 04:31:31800 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
801 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53802 EXPECT_EQ(7, GetOrderOfRequest(5));
803 EXPECT_EQ(6, GetOrderOfRequest(6));
804 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17805
806 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13807 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53808}
809
810TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
811 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
812
[email protected]ac790b42009-12-02 04:31:31813 EXPECT_EQ(OK, StartRequest("a", LOWEST));
814 EXPECT_EQ(OK, StartRequest("a", LOW));
815 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
816 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53817
[email protected]2431756e2010-09-29 20:26:13818 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53819 client_socket_factory_.allocation_count());
820
[email protected]ac790b42009-12-02 04:31:31821 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
822 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
823 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53824
[email protected]2431756e2010-09-29 20:26:13825 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53826
[email protected]2431756e2010-09-29 20:26:13827 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53828 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13829 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53830
831 // First 4 requests don't have to wait, and finish in order.
832 EXPECT_EQ(1, GetOrderOfRequest(1));
833 EXPECT_EQ(2, GetOrderOfRequest(2));
834 EXPECT_EQ(3, GetOrderOfRequest(3));
835 EXPECT_EQ(4, GetOrderOfRequest(4));
836
837 // Request ("b", 7) has the highest priority, but we can't make new socket for
838 // group "b", because it has reached the per-group limit. Then we make
839 // socket for ("c", 6), because it has higher priority than ("a", 4),
840 // and we still can't make a socket for group "b".
841 EXPECT_EQ(5, GetOrderOfRequest(5));
842 EXPECT_EQ(6, GetOrderOfRequest(6));
843 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17844
845 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13846 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53847}
848
849// Make sure that we count connecting sockets against the total limit.
850TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
851 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
852
853 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
854 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
855 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
856
857 // Create one asynchronous request.
858 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
859 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
860
[email protected]6b175382009-10-13 06:47:47861 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
862 // actually become pending until 2ms after they have been created. In order
863 // to flush all tasks, we need to wait so that we know there are no
864 // soon-to-be-pending tasks waiting.
865 PlatformThread::Sleep(10);
866 MessageLoop::current()->RunAllPending();
867
[email protected]211d21722009-07-22 15:48:53868 // The next synchronous request should wait for its turn.
869 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", 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());
876
877 EXPECT_EQ(1, GetOrderOfRequest(1));
878 EXPECT_EQ(2, GetOrderOfRequest(2));
879 EXPECT_EQ(3, GetOrderOfRequest(3));
880 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17881 EXPECT_EQ(5, GetOrderOfRequest(5));
882
883 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13884 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53885}
886
[email protected]6427fe22010-04-16 22:27:41887TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
888 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
889 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
890
891 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
892 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
893 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
894 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
895
896 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
897
898 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
899
900 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
901 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
902
903 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
904
[email protected]2431756e2010-09-29 20:26:13905 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41906 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13907 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41908 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13909 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
910 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41911 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
912}
913
[email protected]d7027bb2010-05-10 18:58:54914TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
915 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
916 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
917
918 ClientSocketHandle handle;
919 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13920 EXPECT_EQ(ERR_IO_PENDING,
921 handle.Init("a",
922 params_,
923 kDefaultPriority,
924 &callback,
925 pool_.get(),
926 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54927
928 ClientSocketHandle handles[4];
929 for (size_t i = 0; i < arraysize(handles); ++i) {
930 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13931 EXPECT_EQ(ERR_IO_PENDING,
932 handles[i].Init("b",
933 params_,
934 kDefaultPriority,
935 &callback,
936 pool_.get(),
937 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54938 }
939
940 // One will be stalled, cancel all the handles now.
941 // This should hit the OnAvailableSocketSlot() code where we previously had
942 // stalled groups, but no longer have any.
943 for (size_t i = 0; i < arraysize(handles); ++i)
944 handles[i].Reset();
945}
946
[email protected]eb5a99382010-07-11 03:18:26947TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54948 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
949 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
950
[email protected]eb5a99382010-07-11 03:18:26951 {
952 ClientSocketHandle handles[kDefaultMaxSockets];
953 TestCompletionCallback callbacks[kDefaultMaxSockets];
954 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13955 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
956 params_,
[email protected]e83326f2010-07-31 17:29:25957 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13958 &callbacks[i],
959 pool_.get(),
960 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26961 }
962
963 // Force a stalled group.
964 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54965 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13966 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
967 params_,
968 kDefaultPriority,
969 &callback,
970 pool_.get(),
971 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26972
973 // Cancel the stalled request.
974 stalled_handle.Reset();
975
976 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
977 EXPECT_EQ(0, pool_->IdleSocketCount());
978
979 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54980 }
981
[email protected]43a21b82010-06-10 21:30:54982 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
983 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26984}
[email protected]43a21b82010-06-10 21:30:54985
[email protected]eb5a99382010-07-11 03:18:26986TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
987 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
988 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
989
990 {
991 ClientSocketHandle handles[kDefaultMaxSockets];
992 for (int i = 0; i < kDefaultMaxSockets; ++i) {
993 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13994 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
995 params_,
996 kDefaultPriority,
997 &callback,
998 pool_.get(),
999 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261000 }
1001
1002 // Force a stalled group.
1003 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1004 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541005 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131006 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1007 params_,
1008 kDefaultPriority,
1009 &callback,
1010 pool_.get(),
1011 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261012
1013 // Since it is stalled, it should have no connect jobs.
1014 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1015
1016 // Cancel the stalled request.
1017 handles[0].Reset();
1018
[email protected]eb5a99382010-07-11 03:18:261019 // Now we should have a connect job.
1020 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1021
1022 // The stalled socket should connect.
1023 EXPECT_EQ(OK, callback.WaitForResult());
1024
1025 EXPECT_EQ(kDefaultMaxSockets + 1,
1026 client_socket_factory_.allocation_count());
1027 EXPECT_EQ(0, pool_->IdleSocketCount());
1028 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1029
1030 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541031 }
1032
[email protected]eb5a99382010-07-11 03:18:261033 EXPECT_EQ(1, pool_->IdleSocketCount());
1034}
[email protected]43a21b82010-06-10 21:30:541035
[email protected]eb5a99382010-07-11 03:18:261036TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1037 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1038 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541039
[email protected]eb5a99382010-07-11 03:18:261040 ClientSocketHandle stalled_handle;
1041 TestCompletionCallback callback;
1042 {
1043 ClientSocketHandle handles[kDefaultMaxSockets];
1044 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1045 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061046 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131047 params_,
1048 kDefaultPriority,
1049 &callback,
1050 pool_.get(),
1051 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261052 }
1053
1054 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1055 EXPECT_EQ(0, pool_->IdleSocketCount());
1056
1057 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131058 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1059 params_,
1060 kDefaultPriority,
1061 &callback,
1062 pool_.get(),
1063 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261064
1065 // Dropping out of scope will close all handles and return them to idle.
1066 }
[email protected]43a21b82010-06-10 21:30:541067
1068 // But if we wait for it, the released idle sockets will be closed in
1069 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101070 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261071
1072 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1073 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541074}
1075
1076// Regression test for http://crbug.com/40952.
1077TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1078 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221079 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541080 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1081
1082 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1083 ClientSocketHandle handle;
1084 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131085 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1086 params_,
1087 kDefaultPriority,
1088 &callback,
1089 pool_.get(),
1090 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541091 }
1092
1093 // Flush all the DoReleaseSocket tasks.
1094 MessageLoop::current()->RunAllPending();
1095
1096 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1097 // reuse a socket.
1098 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1099 ClientSocketHandle handle;
1100 TestCompletionCallback callback;
1101
1102 // "0" is special here, since it should be the first entry in the sorted map,
1103 // which is the one which we would close an idle socket for. We shouldn't
1104 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131105 EXPECT_EQ(OK, handle.Init("0",
1106 params_,
1107 kDefaultPriority,
1108 &callback,
1109 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211110 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541111
1112 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1113 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1114}
1115
[email protected]ab838892009-06-30 18:49:051116TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531117 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091118
[email protected]c9d6a1d2009-07-14 16:15:201119 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1120 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031121 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311122 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1123 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1124 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1125 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1126 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]2431756e2010-09-29 20:26:131128 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091129
[email protected]c9d6a1d2009-07-14 16:15:201130 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1131 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131132 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1133 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091134
[email protected]c9d6a1d2009-07-14 16:15:201135 EXPECT_EQ(1, GetOrderOfRequest(1));
1136 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031137 EXPECT_EQ(8, GetOrderOfRequest(3));
1138 EXPECT_EQ(6, GetOrderOfRequest(4));
1139 EXPECT_EQ(4, GetOrderOfRequest(5));
1140 EXPECT_EQ(3, GetOrderOfRequest(6));
1141 EXPECT_EQ(5, GetOrderOfRequest(7));
1142 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171143
1144 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131145 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091146}
1147
[email protected]ab838892009-06-30 18:49:051148TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531149 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091150
[email protected]c9d6a1d2009-07-14 16:15:201151 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1152 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311153 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1154 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1155 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1156 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1157 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091158
[email protected]2431756e2010-09-29 20:26:131159 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091160
[email protected]2431756e2010-09-29 20:26:131161 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1162 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201163
[email protected]2431756e2010-09-29 20:26:131164 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201165 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131166 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1167 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091168}
1169
1170// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051171// The pending connect job will be cancelled and should not call back into
1172// ClientSocketPoolBase.
1173TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531174 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201175
[email protected]ab838892009-06-30 18:49:051176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131177 ClientSocketHandle handle;
1178 TestCompletionCallback callback;
1179 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1180 params_,
1181 kDefaultPriority,
1182 &callback,
1183 pool_.get(),
1184 BoundNetLog()));
1185 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091186}
1187
[email protected]ab838892009-06-30 18:49:051188TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531189 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201190
[email protected]ab838892009-06-30 18:49:051191 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061192 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091193 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091194
[email protected]2431756e2010-09-29 20:26:131195 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1196 params_,
1197 kDefaultPriority,
1198 &callback,
1199 pool_.get(),
1200 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091201
1202 handle.Reset();
1203
1204 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131205 EXPECT_EQ(ERR_IO_PENDING,
1206 handle.Init("a",
1207 params_,
1208 kDefaultPriority,
1209 &callback2,
1210 pool_.get(),
1211 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091212
1213 EXPECT_EQ(OK, callback2.WaitForResult());
1214 EXPECT_FALSE(callback.have_result());
1215
1216 handle.Reset();
1217}
1218
[email protected]ab838892009-06-30 18:49:051219TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531220 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091221
[email protected]c9d6a1d2009-07-14 16:15:201222 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1223 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1227 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1228 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091229
1230 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201231 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131232 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1233 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091234
[email protected]2431756e2010-09-29 20:26:131235 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091236
[email protected]c9d6a1d2009-07-14 16:15:201237 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1238 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131239 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1240 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091241
[email protected]c9d6a1d2009-07-14 16:15:201242 EXPECT_EQ(1, GetOrderOfRequest(1));
1243 EXPECT_EQ(2, GetOrderOfRequest(2));
1244 EXPECT_EQ(5, GetOrderOfRequest(3));
1245 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131246 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1247 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201248 EXPECT_EQ(4, GetOrderOfRequest(6));
1249 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171250
1251 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131252 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091253}
1254
1255class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1256 public:
[email protected]2ab05b52009-07-01 23:57:581257 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241258 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581259 TestConnectJobFactory* test_connect_job_factory,
1260 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091261 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061262 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581263 within_callback_(false),
1264 test_connect_job_factory_(test_connect_job_factory),
1265 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091266
1267 virtual void RunWithParams(const Tuple1<int>& params) {
1268 callback_.RunWithParams(params);
1269 ASSERT_EQ(OK, params.a);
1270
1271 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581272 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111273
1274 // Don't allow reuse of the socket. Disconnect it and then release it and
1275 // run through the MessageLoop once to get it completely released.
1276 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091277 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111278 {
1279 MessageLoop::ScopedNestableTaskAllower nestable(
1280 MessageLoop::current());
1281 MessageLoop::current()->RunAllPending();
1282 }
[email protected]f6d1d6eb2009-06-24 20:16:091283 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471284 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271285 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131286 int rv = handle_->Init("a",
1287 params,
1288 kDefaultPriority,
1289 &next_job_callback,
1290 pool_,
1291 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581292 switch (next_job_type_) {
1293 case TestConnectJob::kMockJob:
1294 EXPECT_EQ(OK, rv);
1295 break;
1296 case TestConnectJob::kMockPendingJob:
1297 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471298
1299 // For pending jobs, wait for new socket to be created. This makes
1300 // sure there are no more pending operations nor any unclosed sockets
1301 // when the test finishes.
1302 // We need to give it a little bit of time to run, so that all the
1303 // operations that happen on timers (e.g. cleanup of idle
1304 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111305 {
1306 MessageLoop::ScopedNestableTaskAllower nestable(
1307 MessageLoop::current());
1308 PlatformThread::Sleep(10);
1309 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1310 }
[email protected]2ab05b52009-07-01 23:57:581311 break;
1312 default:
1313 FAIL() << "Unexpected job type: " << next_job_type_;
1314 break;
1315 }
[email protected]f6d1d6eb2009-06-24 20:16:091316 }
1317 }
1318
1319 int WaitForResult() {
1320 return callback_.WaitForResult();
1321 }
1322
1323 private:
1324 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131325 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091326 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581327 TestConnectJobFactory* const test_connect_job_factory_;
1328 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091329 TestCompletionCallback callback_;
1330};
1331
[email protected]2ab05b52009-07-01 23:57:581332TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531333 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201334
[email protected]0b7648c2009-07-06 20:14:011335 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061336 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581337 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061338 &handle, pool_.get(), connect_job_factory_,
1339 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131340 int rv = handle.Init("a",
1341 params_,
1342 kDefaultPriority,
1343 &callback,
1344 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211345 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091346 ASSERT_EQ(ERR_IO_PENDING, rv);
1347
1348 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581349}
[email protected]f6d1d6eb2009-06-24 20:16:091350
[email protected]2ab05b52009-07-01 23:57:581351TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531352 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201353
[email protected]0b7648c2009-07-06 20:14:011354 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061355 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581356 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061357 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131358 int rv = handle.Init("a",
1359 params_,
1360 kDefaultPriority,
1361 &callback,
1362 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211363 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581364 ASSERT_EQ(ERR_IO_PENDING, rv);
1365
1366 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091367}
1368
1369// Make sure that pending requests get serviced after active requests get
1370// cancelled.
[email protected]ab838892009-06-30 18:49:051371TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201373
[email protected]0b7648c2009-07-06 20:14:011374 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091375
[email protected]c9d6a1d2009-07-14 16:15:201376 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1377 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1378 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1379 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1380 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1381 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1382 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091383
[email protected]c9d6a1d2009-07-14 16:15:201384 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1385 // Let's cancel them.
1386 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131387 ASSERT_FALSE(request(i)->handle()->is_initialized());
1388 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091389 }
1390
[email protected]f6d1d6eb2009-06-24 20:16:091391 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131392 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1393 EXPECT_EQ(OK, request(i)->WaitForResult());
1394 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091395 }
1396
[email protected]2431756e2010-09-29 20:26:131397 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1398 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091399}
1400
1401// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051402TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531403 const size_t kMaxSockets = 5;
1404 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201405
[email protected]0b7648c2009-07-06 20:14:011406 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091407
[email protected]211d21722009-07-22 15:48:531408 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1409 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091410
1411 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531412 for (size_t i = 0; i < kNumberOfRequests; ++i)
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091414
[email protected]211d21722009-07-22 15:48:531415 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131416 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091417}
1418
[email protected]5fc08e32009-07-15 17:09:571419TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571421
1422 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1423
[email protected]2431756e2010-09-29 20:26:131424 ClientSocketHandle handle;
1425 TestCompletionCallback callback;
1426 int rv = handle.Init("a",
1427 params_,
1428 kDefaultPriority,
1429 &callback,
1430 pool_.get(),
1431 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571432 EXPECT_EQ(ERR_IO_PENDING, rv);
1433
1434 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131435 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571436
[email protected]2431756e2010-09-29 20:26:131437 rv = handle.Init("a",
1438 params_,
1439 kDefaultPriority,
1440 &callback,
1441 pool_.get(),
1442 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571443 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131444 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571445
[email protected]2431756e2010-09-29 20:26:131446 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571447 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1448}
1449
[email protected]2b7523d2009-07-29 20:29:231450// Regression test for http://crbug.com/17985.
1451TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1452 const int kMaxSockets = 3;
1453 const int kMaxSocketsPerGroup = 2;
1454 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1455
[email protected]ac790b42009-12-02 04:31:311456 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231457
1458 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1459 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1460
1461 // This is going to be a pending request in an otherwise empty group.
1462 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1463
1464 // Reach the maximum socket limit.
1465 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1466
1467 // Create a stalled group with high priorities.
1468 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1469 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231470
[email protected]eb5a99382010-07-11 03:18:261471 // Release the first two sockets from "a". Because this is a keepalive,
1472 // the first release will unblock the pending request for "a". The
1473 // second release will unblock a request for "c", becaue it is the next
1474 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131475 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1476 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231477
1478 // Closing idle sockets should not get us into trouble, but in the bug
1479 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411480 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541481 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261482
1483 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231484}
1485
[email protected]4d3b05d2010-01-27 21:27:291486TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531487 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571488
1489 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131490 ClientSocketHandle handle;
1491 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531492 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131493 int rv = handle.Init("a",
1494 params_,
1495 LOWEST,
1496 &callback,
1497 pool_.get(),
1498 log.bound());
[email protected]5fc08e32009-07-15 17:09:571499 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131500 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1501 EXPECT_EQ(OK, callback.WaitForResult());
1502 EXPECT_TRUE(handle.is_initialized());
1503 EXPECT_TRUE(handle.socket());
1504 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301505
[email protected]06650c52010-06-03 00:49:171506 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461507 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531508 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171509 EXPECT_TRUE(LogContainsEvent(
1510 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1511 NetLog::PHASE_NONE));
1512 EXPECT_TRUE(LogContainsEvent(
1513 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1514 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461515 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171516 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571517}
1518
[email protected]4d3b05d2010-01-27 21:27:291519TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571520 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531521 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571522
1523 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131524 ClientSocketHandle handle;
1525 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531526 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181527 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131528 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431529 HttpResponseInfo info;
1530 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131531 handle.set_ssl_error_response_info(info);
1532 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1533 params_,
1534 kDefaultPriority,
1535 &callback,
1536 pool_.get(),
1537 log.bound()));
1538 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1539 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1540 EXPECT_FALSE(handle.is_ssl_error());
1541 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301542
[email protected]06650c52010-06-03 00:49:171543 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461544 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531545 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171546 EXPECT_TRUE(LogContainsEvent(
1547 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1548 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321549 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171550 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571551}
1552
[email protected]4d3b05d2010-01-27 21:27:291553TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101554 // TODO(eroman): Add back the log expectations! Removed them because the
1555 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531556 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571557
1558 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131559 ClientSocketHandle handle;
1560 TestCompletionCallback callback;
1561 ClientSocketHandle handle2;
1562 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571563
[email protected]2431756e2010-09-29 20:26:131564 EXPECT_EQ(ERR_IO_PENDING,
1565 handle.Init("a",
1566 params_,
1567 kDefaultPriority,
1568 &callback,
1569 pool_.get(),
1570 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531571 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131572 EXPECT_EQ(ERR_IO_PENDING,
1573 handle2.Init("a",
1574 params_,
1575 kDefaultPriority,
1576 &callback2,
1577 pool_.get(),
1578 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571579
[email protected]2431756e2010-09-29 20:26:131580 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571581
[email protected]fd7b7c92009-08-20 19:38:301582
1583 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301584
[email protected]2431756e2010-09-29 20:26:131585 EXPECT_EQ(OK, callback2.WaitForResult());
1586 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301587
1588 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531589 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571590}
1591
[email protected]4d3b05d2010-01-27 21:27:291592TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341593 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1594
[email protected]17a0c6c2009-08-04 00:07:041595 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1596
[email protected]ac790b42009-12-02 04:31:311597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1599 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341601
1602 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131603 (*requests())[2]->handle()->Reset();
1604 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341605 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1606
[email protected]2431756e2010-09-29 20:26:131607 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341608 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1609
[email protected]2431756e2010-09-29 20:26:131610 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261611 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341612}
1613
[email protected]5fc08e32009-07-15 17:09:571614// When requests and ConnectJobs are not coupled, the request will get serviced
1615// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291616TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531617 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571618
1619 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321620 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571621
[email protected]2431756e2010-09-29 20:26:131622 std::vector<TestSocketRequest*> request_order;
1623 size_t completion_count; // unused
1624 TestSocketRequest req1(&request_order, &completion_count);
1625 int rv = req1.handle()->Init("a",
1626 params_,
1627 kDefaultPriority,
1628 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211629 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571630 EXPECT_EQ(ERR_IO_PENDING, rv);
1631 EXPECT_EQ(OK, req1.WaitForResult());
1632
1633 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1634 // without a job.
1635 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1636
[email protected]2431756e2010-09-29 20:26:131637 TestSocketRequest req2(&request_order, &completion_count);
1638 rv = req2.handle()->Init("a",
1639 params_,
1640 kDefaultPriority,
1641 &req2,
1642 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211643 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571644 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131645 TestSocketRequest req3(&request_order, &completion_count);
1646 rv = req3.handle()->Init("a",
1647 params_,
1648 kDefaultPriority,
1649 &req3,
1650 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211651 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571652 EXPECT_EQ(ERR_IO_PENDING, rv);
1653
1654 // Both Requests 2 and 3 are pending. We release socket 1 which should
1655 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331656 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261657 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331658 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571659 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331660 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571661
1662 // Signal job 2, which should service request 3.
1663
1664 client_socket_factory_.SignalJobs();
1665 EXPECT_EQ(OK, req3.WaitForResult());
1666
[email protected]2431756e2010-09-29 20:26:131667 ASSERT_EQ(3U, request_order.size());
1668 EXPECT_EQ(&req1, request_order[0]);
1669 EXPECT_EQ(&req2, request_order[1]);
1670 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571671 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1672}
1673
1674// The requests are not coupled to the jobs. So, the requests should finish in
1675// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291676TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531677 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571678 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321679 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571680
[email protected]2431756e2010-09-29 20:26:131681 std::vector<TestSocketRequest*> request_order;
1682 size_t completion_count; // unused
1683 TestSocketRequest req1(&request_order, &completion_count);
1684 int rv = req1.handle()->Init("a",
1685 params_,
1686 kDefaultPriority,
1687 &req1,
1688 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211689 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571690 EXPECT_EQ(ERR_IO_PENDING, rv);
1691
[email protected]2431756e2010-09-29 20:26:131692 TestSocketRequest req2(&request_order, &completion_count);
1693 rv = req2.handle()->Init("a",
1694 params_,
1695 kDefaultPriority,
1696 &req2,
1697 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211698 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571699 EXPECT_EQ(ERR_IO_PENDING, rv);
1700
1701 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321702 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571703
[email protected]2431756e2010-09-29 20:26:131704 TestSocketRequest req3(&request_order, &completion_count);
1705 rv = req3.handle()->Init("a",
1706 params_,
1707 kDefaultPriority,
1708 &req3,
1709 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211710 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571711 EXPECT_EQ(ERR_IO_PENDING, rv);
1712
1713 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1714 EXPECT_EQ(OK, req2.WaitForResult());
1715 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1716
[email protected]2431756e2010-09-29 20:26:131717 ASSERT_EQ(3U, request_order.size());
1718 EXPECT_EQ(&req1, request_order[0]);
1719 EXPECT_EQ(&req2, request_order[1]);
1720 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571721}
1722
[email protected]e6ec67b2010-06-16 00:12:461723TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531724 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571725 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321726 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571727
[email protected]2431756e2010-09-29 20:26:131728 ClientSocketHandle handle;
1729 TestCompletionCallback callback;
1730 int rv = handle.Init("a",
1731 params_,
1732 kDefaultPriority,
1733 &callback,
1734 pool_.get(),
1735 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571736 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131737 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571738
1739 MessageLoop::current()->RunAllPending();
1740
[email protected]2431756e2010-09-29 20:26:131741 ClientSocketHandle handle2;
1742 TestCompletionCallback callback2;
1743 rv = handle2.Init("a",
1744 params_,
1745 kDefaultPriority,
1746 &callback2, pool_.get(),
1747 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571748 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131749 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1750 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571751}
1752
[email protected]e772db3f2010-07-12 18:11:131753TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1754 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1755 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1756
[email protected]2431756e2010-09-29 20:26:131757 ClientSocketHandle handle;
1758 TestCompletionCallback callback;
1759 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1760 params_,
1761 kDefaultPriority,
1762 &callback, pool_.get(),
1763 BoundNetLog()));
1764 EXPECT_TRUE(handle.is_initialized());
1765 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131766}
1767
1768TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1769 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1770
1771 connect_job_factory_->set_job_type(
1772 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131773 ClientSocketHandle handle;
1774 TestCompletionCallback callback;
1775 EXPECT_EQ(ERR_IO_PENDING,
1776 handle.Init("a",
1777 params_,
1778 kDefaultPriority,
1779 &callback,
1780 pool_.get(),
1781 BoundNetLog()));
1782 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1783 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1784 EXPECT_TRUE(handle.is_initialized());
1785 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131786}
1787
[email protected]e60e47a2010-07-14 03:37:181788TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1789 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1790 connect_job_factory_->set_job_type(
1791 TestConnectJob::kMockAdditionalErrorStateJob);
1792
[email protected]2431756e2010-09-29 20:26:131793 ClientSocketHandle handle;
1794 TestCompletionCallback callback;
1795 EXPECT_EQ(ERR_CONNECTION_FAILED,
1796 handle.Init("a",
1797 params_,
1798 kDefaultPriority,
1799 &callback,
1800 pool_.get(),
1801 BoundNetLog()));
1802 EXPECT_FALSE(handle.is_initialized());
1803 EXPECT_FALSE(handle.socket());
1804 EXPECT_TRUE(handle.is_ssl_error());
1805 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181806}
1807
1808TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1809 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1810
1811 connect_job_factory_->set_job_type(
1812 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131813 ClientSocketHandle handle;
1814 TestCompletionCallback callback;
1815 EXPECT_EQ(ERR_IO_PENDING,
1816 handle.Init("a",
1817 params_,
1818 kDefaultPriority,
1819 &callback,
1820 pool_.get(),
1821 BoundNetLog()));
1822 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1823 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1824 EXPECT_FALSE(handle.is_initialized());
1825 EXPECT_FALSE(handle.socket());
1826 EXPECT_TRUE(handle.is_ssl_error());
1827 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181828}
1829
[email protected]4d3b05d2010-01-27 21:27:291830TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161831 CreatePoolWithIdleTimeouts(
1832 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1833 base::TimeDelta(), // Time out unused sockets immediately.
1834 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1835
1836 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1837
1838 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1839
[email protected]2431756e2010-09-29 20:26:131840 ClientSocketHandle handle;
1841 TestCompletionCallback callback;
1842 int rv = handle.Init("a",
1843 params_,
1844 LOWEST,
1845 &callback,
1846 pool_.get(),
1847 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161848 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131849 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161850
[email protected]2431756e2010-09-29 20:26:131851 ClientSocketHandle handle2;
1852 TestCompletionCallback callback2;
1853 rv = handle2.Init("a",
1854 params_,
1855 LOWEST,
1856 &callback2,
1857 pool_.get(),
1858 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161859 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131860 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161861
1862 // Cancel one of the requests. Wait for the other, which will get the first
1863 // job. Release the socket. Run the loop again to make sure the second
1864 // socket is sitting idle and the first one is released (since ReleaseSocket()
1865 // just posts a DoReleaseSocket() task).
1866
[email protected]2431756e2010-09-29 20:26:131867 handle.Reset();
1868 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011869 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131870 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1871 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471872
1873 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1874 // actually become pending until 2ms after they have been created. In order
1875 // to flush all tasks, we need to wait so that we know there are no
1876 // soon-to-be-pending tasks waiting.
1877 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161878 MessageLoop::current()->RunAllPending();
1879
1880 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041881
[email protected]9bf28db2009-08-29 01:35:161882 // Invoke the idle socket cleanup check. Only one socket should be left, the
1883 // used socket. Request it to make sure that it's used.
1884
1885 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531886 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131887 rv = handle.Init("a",
1888 params_,
1889 LOWEST,
1890 &callback,
1891 pool_.get(),
1892 log.bound());
[email protected]9bf28db2009-08-29 01:35:161893 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131894 EXPECT_TRUE(handle.is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151895 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451896 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161897}
1898
[email protected]2041cf342010-02-19 03:15:591899// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161900// because of multiple releasing disconnected sockets.
1901TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1902 CreatePoolWithIdleTimeouts(
1903 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1904 base::TimeDelta(), // Time out unused sockets immediately.
1905 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1906
1907 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1908
1909 // Startup 4 connect jobs. Two of them will be pending.
1910
[email protected]2431756e2010-09-29 20:26:131911 ClientSocketHandle handle;
1912 TestCompletionCallback callback;
1913 int rv = handle.Init("a",
1914 params_,
1915 LOWEST,
1916 &callback,
1917 pool_.get(),
1918 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161919 EXPECT_EQ(OK, rv);
1920
[email protected]2431756e2010-09-29 20:26:131921 ClientSocketHandle handle2;
1922 TestCompletionCallback callback2;
1923 rv = handle2.Init("a",
1924 params_,
1925 LOWEST,
1926 &callback2,
1927 pool_.get(),
1928 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161929 EXPECT_EQ(OK, rv);
1930
[email protected]2431756e2010-09-29 20:26:131931 ClientSocketHandle handle3;
1932 TestCompletionCallback callback3;
1933 rv = handle3.Init("a",
1934 params_,
1935 LOWEST,
1936 &callback3,
1937 pool_.get(),
1938 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161939 EXPECT_EQ(ERR_IO_PENDING, rv);
1940
[email protected]2431756e2010-09-29 20:26:131941 ClientSocketHandle handle4;
1942 TestCompletionCallback callback4;
1943 rv = handle4.Init("a",
1944 params_,
1945 LOWEST,
1946 &callback4,
1947 pool_.get(),
1948 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161949 EXPECT_EQ(ERR_IO_PENDING, rv);
1950
1951 // Release two disconnected sockets.
1952
[email protected]2431756e2010-09-29 20:26:131953 handle.socket()->Disconnect();
1954 handle.Reset();
1955 handle2.socket()->Disconnect();
1956 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161957
[email protected]2431756e2010-09-29 20:26:131958 EXPECT_EQ(OK, callback3.WaitForResult());
1959 EXPECT_FALSE(handle3.is_reused());
1960 EXPECT_EQ(OK, callback4.WaitForResult());
1961 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161962}
1963
[email protected]d7027bb2010-05-10 18:58:541964// Regression test for http://crbug.com/42267.
1965// When DoReleaseSocket() is processed for one socket, it is blocked because the
1966// other stalled groups all have releasing sockets, so no progress can be made.
1967TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1968 CreatePoolWithIdleTimeouts(
1969 4 /* socket limit */, 4 /* socket limit per group */,
1970 base::TimeDelta(), // Time out unused sockets immediately.
1971 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1972
1973 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1974
1975 // Max out the socket limit with 2 per group.
1976
[email protected]2431756e2010-09-29 20:26:131977 ClientSocketHandle handle_a[4];
1978 TestCompletionCallback callback_a[4];
1979 ClientSocketHandle handle_b[4];
1980 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541981
1982 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:131983 EXPECT_EQ(OK, handle_a[i].Init("a",
1984 params_,
1985 LOWEST,
1986 &callback_a[i],
1987 pool_.get(),
1988 BoundNetLog()));
1989 EXPECT_EQ(OK, handle_b[i].Init("b",
1990 params_,
1991 LOWEST,
1992 &callback_b[i],
1993 pool_.get(),
1994 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:541995 }
[email protected]b89f7e42010-05-20 20:37:001996
[email protected]d7027bb2010-05-10 18:58:541997 // Make 4 pending requests, 2 per group.
1998
1999 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132000 EXPECT_EQ(ERR_IO_PENDING,
2001 handle_a[i].Init("a",
2002 params_,
2003 LOWEST,
2004 &callback_a[i],
2005 pool_.get(),
2006 BoundNetLog()));
2007 EXPECT_EQ(ERR_IO_PENDING,
2008 handle_b[i].Init("b",
2009 params_,
2010 LOWEST,
2011 &callback_b[i],
2012 pool_.get(),
2013 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542014 }
2015
2016 // Release b's socket first. The order is important, because in
2017 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2018 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2019 // first, which has a releasing socket, so it refuses to start up another
2020 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132021 handle_b[0].socket()->Disconnect();
2022 handle_b[0].Reset();
2023 handle_a[0].socket()->Disconnect();
2024 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542025
2026 // Used to get stuck here.
2027 MessageLoop::current()->RunAllPending();
2028
[email protected]2431756e2010-09-29 20:26:132029 handle_b[1].socket()->Disconnect();
2030 handle_b[1].Reset();
2031 handle_a[1].socket()->Disconnect();
2032 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542033
2034 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132035 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2036 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542037 }
2038}
2039
[email protected]fd4fe0b2010-02-08 23:02:152040TEST_F(ClientSocketPoolBaseTest,
2041 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2042 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2043
2044 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2045
2046 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2047 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2048 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2049 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2050
[email protected]2431756e2010-09-29 20:26:132051 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2052 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2053 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152054
2055 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132056 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2057 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152058
[email protected]2431756e2010-09-29 20:26:132059 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2060 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2061 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152062
2063 EXPECT_EQ(1, GetOrderOfRequest(1));
2064 EXPECT_EQ(2, GetOrderOfRequest(2));
2065 EXPECT_EQ(3, GetOrderOfRequest(3));
2066 EXPECT_EQ(4, GetOrderOfRequest(4));
2067
2068 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132069 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152070}
2071
[email protected]4f1e4982010-03-02 18:31:042072class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2073 public:
[email protected]2431756e2010-09-29 20:26:132074 TestReleasingSocketRequest(TestClientSocketPool* pool,
2075 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182076 bool reset_releasing_handle)
2077 : pool_(pool),
2078 expected_result_(expected_result),
2079 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042080
2081 ClientSocketHandle* handle() { return &handle_; }
2082
2083 int WaitForResult() {
2084 return callback_.WaitForResult();
2085 }
2086
2087 virtual void RunWithParams(const Tuple1<int>& params) {
2088 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182089 if (reset_releasing_handle_)
2090 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272091 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132092 EXPECT_EQ(expected_result_, handle2_.Init("a",
2093 con_params,
2094 kDefaultPriority,
2095 &callback2_,
2096 pool_,
[email protected]e60e47a2010-07-14 03:37:182097 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042098 }
2099
2100 private:
[email protected]2431756e2010-09-29 20:26:132101 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182102 int expected_result_;
2103 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042104 ClientSocketHandle handle_;
2105 ClientSocketHandle handle2_;
2106 TestCompletionCallback callback_;
2107 TestCompletionCallback callback2_;
2108};
2109
[email protected]e60e47a2010-07-14 03:37:182110
2111TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2112 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2113
2114 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2115 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2116 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2117
[email protected]2431756e2010-09-29 20:26:132118 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182119 client_socket_factory_.allocation_count());
2120
2121 connect_job_factory_->set_job_type(
2122 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2123 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132124 EXPECT_EQ(ERR_IO_PENDING,
2125 req.handle()->Init("a",
2126 params_,
2127 kDefaultPriority,
2128 &req,
2129 pool_.get(),
2130 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182131 // The next job should complete synchronously
2132 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2133
2134 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2135 EXPECT_FALSE(req.handle()->is_initialized());
2136 EXPECT_FALSE(req.handle()->socket());
2137 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432138 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182139}
2140
[email protected]b6501d3d2010-06-03 23:53:342141// http://crbug.com/44724 regression test.
2142// We start releasing the pool when we flush on network change. When that
2143// happens, the only active references are in the ClientSocketHandles. When a
2144// ConnectJob completes and calls back into the last ClientSocketHandle, that
2145// callback can release the last reference and delete the pool. After the
2146// callback finishes, we go back to the stack frame within the now-deleted pool.
2147// Executing any code that refers to members of the now-deleted pool can cause
2148// crashes.
2149TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2150 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2151 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2152
2153 ClientSocketHandle handle;
2154 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132155 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2156 params_,
2157 kDefaultPriority,
2158 &callback,
2159 pool_.get(),
2160 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342161
[email protected]2431756e2010-09-29 20:26:132162 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342163
2164 // We'll call back into this now.
2165 callback.WaitForResult();
2166}
2167
[email protected]a7e38572010-06-07 18:22:242168TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2169 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2170 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2171
2172 ClientSocketHandle handle;
2173 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132174 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2175 params_,
2176 kDefaultPriority,
2177 &callback,
2178 pool_.get(),
2179 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242180 EXPECT_EQ(OK, callback.WaitForResult());
2181 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2182
2183 pool_->Flush();
2184
2185 handle.Reset();
2186 MessageLoop::current()->RunAllPending();
2187
[email protected]2431756e2010-09-29 20:26:132188 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2189 params_,
2190 kDefaultPriority,
2191 &callback,
2192 pool_.get(),
2193 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242194 EXPECT_EQ(OK, callback.WaitForResult());
2195 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2196}
2197
[email protected]06f92462010-08-31 19:24:142198class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2199 public:
2200 ConnectWithinCallback(
2201 const std::string& group_name,
2202 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132203 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142204 : group_name_(group_name), params_(params), pool_(pool) {}
2205
2206 ~ConnectWithinCallback() {}
2207
2208 virtual void RunWithParams(const Tuple1<int>& params) {
2209 callback_.RunWithParams(params);
2210 EXPECT_EQ(ERR_IO_PENDING,
2211 handle_.Init(group_name_,
2212 params_,
2213 kDefaultPriority,
2214 &nested_callback_,
2215 pool_,
2216 BoundNetLog()));
2217 }
2218
2219 int WaitForResult() {
2220 return callback_.WaitForResult();
2221 }
2222
2223 int WaitForNestedResult() {
2224 return nested_callback_.WaitForResult();
2225 }
2226
2227 private:
2228 const std::string group_name_;
2229 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132230 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142231 ClientSocketHandle handle_;
2232 TestCompletionCallback callback_;
2233 TestCompletionCallback nested_callback_;
2234};
2235
2236TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2237 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2238
2239 // First job will be waiting until it gets aborted.
2240 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2241
2242 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132243 ConnectWithinCallback callback("a", params_, pool_.get());
2244 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2245 params_,
2246 kDefaultPriority,
2247 &callback,
2248 pool_.get(),
2249 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142250
2251 // Second job will be started during the first callback, and will
2252 // asynchronously complete with OK.
2253 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2254 pool_->Flush();
2255 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2256 EXPECT_EQ(OK, callback.WaitForNestedResult());
2257}
2258
[email protected]25eea382010-07-10 23:55:262259// Cancel a pending socket request while we're at max sockets,
2260// and verify that the backup socket firing doesn't cause a crash.
2261TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2262 // Max 4 sockets globally, max 4 sockets per group.
2263 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222264 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262265
[email protected]4baaf9d2010-08-31 15:15:442266 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2267 // timer.
[email protected]25eea382010-07-10 23:55:262268 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2269 ClientSocketHandle handle;
2270 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132271 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2272 params_,
2273 kDefaultPriority,
2274 &callback,
2275 pool_.get(),
2276 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262277
2278 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2279 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2280 ClientSocketHandle handles[kDefaultMaxSockets];
2281 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2282 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132283 EXPECT_EQ(OK, handles[i].Init("bar",
2284 params_,
2285 kDefaultPriority,
2286 &callback,
2287 pool_.get(),
2288 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262289 }
2290
2291 MessageLoop::current()->RunAllPending();
2292
2293 // Cancel the pending request.
2294 handle.Reset();
2295
2296 // Wait for the backup timer to fire (add some slop to ensure it fires)
2297 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2298
2299 MessageLoop::current()->RunAllPending();
2300 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2301}
2302
[email protected]3f00be82010-09-27 19:50:022303TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442304 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2305 pool_->EnableConnectBackupJobs();
2306
2307 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2308 // timer.
2309 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2310 ClientSocketHandle handle;
2311 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132312 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2313 params_,
2314 kDefaultPriority,
2315 &callback,
2316 pool_.get(),
2317 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442318 ASSERT_TRUE(pool_->HasGroup("bar"));
2319 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2320
2321 // Cancel the socket request. This should cancel the backup timer. Wait for
2322 // the backup time to see if it indeed got canceled.
2323 handle.Reset();
2324 // Wait for the backup timer to fire (add some slop to ensure it fires)
2325 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2326 MessageLoop::current()->RunAllPending();
2327 ASSERT_TRUE(pool_->HasGroup("bar"));
2328 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2329}
2330
[email protected]3f00be82010-09-27 19:50:022331TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2332 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2333 pool_->EnableConnectBackupJobs();
2334
2335 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2336 // timer.
2337 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2338 ClientSocketHandle handle;
2339 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132340 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2341 params_,
2342 kDefaultPriority,
2343 &callback,
2344 pool_.get(),
2345 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022346 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2347 ClientSocketHandle handle2;
2348 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132349 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2350 params_,
2351 kDefaultPriority,
2352 &callback2,
2353 pool_.get(),
2354 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022355 ASSERT_TRUE(pool_->HasGroup("bar"));
2356 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2357
2358 // Cancel request 1 and then complete request 2. With the requests finished,
2359 // the backup timer should be cancelled.
2360 handle.Reset();
2361 EXPECT_EQ(OK, callback2.WaitForResult());
2362 // Wait for the backup timer to fire (add some slop to ensure it fires)
2363 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2364 MessageLoop::current()->RunAllPending();
2365}
2366
[email protected]eb5a99382010-07-11 03:18:262367// Test delayed socket binding for the case where we have two connects,
2368// and while one is waiting on a connect, the other frees up.
2369// The socket waiting on a connect should switch immediately to the freed
2370// up socket.
2371TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2372 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2373 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2374
2375 ClientSocketHandle handle1;
2376 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132377 EXPECT_EQ(ERR_IO_PENDING,
2378 handle1.Init("a",
2379 params_,
2380 kDefaultPriority,
2381 &callback,
2382 pool_.get(),
2383 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262384 EXPECT_EQ(OK, callback.WaitForResult());
2385
2386 // No idle sockets, no pending jobs.
2387 EXPECT_EQ(0, pool_->IdleSocketCount());
2388 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2389
2390 // Create a second socket to the same host, but this one will wait.
2391 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2392 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132393 EXPECT_EQ(ERR_IO_PENDING,
2394 handle2.Init("a",
2395 params_,
2396 kDefaultPriority,
2397 &callback,
2398 pool_.get(),
2399 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262400 // No idle sockets, and one connecting job.
2401 EXPECT_EQ(0, pool_->IdleSocketCount());
2402 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2403
2404 // Return the first handle to the pool. This will initiate the delayed
2405 // binding.
2406 handle1.Reset();
2407
2408 MessageLoop::current()->RunAllPending();
2409
2410 // Still no idle sockets, still one pending connect job.
2411 EXPECT_EQ(0, pool_->IdleSocketCount());
2412 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2413
2414 // The second socket connected, even though it was a Waiting Job.
2415 EXPECT_EQ(OK, callback.WaitForResult());
2416
2417 // And we can see there is still one job waiting.
2418 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2419
2420 // Finally, signal the waiting Connect.
2421 client_socket_factory_.SignalJobs();
2422 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2423
2424 MessageLoop::current()->RunAllPending();
2425}
2426
2427// Test delayed socket binding when a group is at capacity and one
2428// of the group's sockets frees up.
2429TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2430 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2431 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2432
2433 ClientSocketHandle handle1;
2434 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132435 EXPECT_EQ(ERR_IO_PENDING,
2436 handle1.Init("a",
2437 params_,
2438 kDefaultPriority,
2439 &callback,
2440 pool_.get(),
2441 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262442 EXPECT_EQ(OK, callback.WaitForResult());
2443
2444 // No idle sockets, no pending jobs.
2445 EXPECT_EQ(0, pool_->IdleSocketCount());
2446 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2447
2448 // Create a second socket to the same host, but this one will wait.
2449 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2450 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132451 EXPECT_EQ(ERR_IO_PENDING,
2452 handle2.Init("a",
2453 params_,
2454 kDefaultPriority,
2455 &callback,
2456 pool_.get(),
2457 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262458 // No idle sockets, and one connecting job.
2459 EXPECT_EQ(0, pool_->IdleSocketCount());
2460 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2461
2462 // Return the first handle to the pool. This will initiate the delayed
2463 // binding.
2464 handle1.Reset();
2465
2466 MessageLoop::current()->RunAllPending();
2467
2468 // Still no idle sockets, still one pending connect job.
2469 EXPECT_EQ(0, pool_->IdleSocketCount());
2470 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2471
2472 // The second socket connected, even though it was a Waiting Job.
2473 EXPECT_EQ(OK, callback.WaitForResult());
2474
2475 // And we can see there is still one job waiting.
2476 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2477
2478 // Finally, signal the waiting Connect.
2479 client_socket_factory_.SignalJobs();
2480 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2481
2482 MessageLoop::current()->RunAllPending();
2483}
2484
2485// Test out the case where we have one socket connected, one
2486// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512487// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262488// should complete, by taking the first socket's idle socket.
2489TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2490 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2491 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2492
2493 ClientSocketHandle handle1;
2494 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132495 EXPECT_EQ(ERR_IO_PENDING,
2496 handle1.Init("a",
2497 params_,
2498 kDefaultPriority,
2499 &callback,
2500 pool_.get(),
2501 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262502 EXPECT_EQ(OK, callback.WaitForResult());
2503
2504 // No idle sockets, no pending jobs.
2505 EXPECT_EQ(0, pool_->IdleSocketCount());
2506 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2507
2508 // Create a second socket to the same host, but this one will wait.
2509 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2510 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132511 EXPECT_EQ(ERR_IO_PENDING,
2512 handle2.Init("a",
2513 params_,
2514 kDefaultPriority,
2515 &callback,
2516 pool_.get(),
2517 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262518 // No idle sockets, and one connecting job.
2519 EXPECT_EQ(0, pool_->IdleSocketCount());
2520 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2521
2522 // Return the first handle to the pool. This will initiate the delayed
2523 // binding.
2524 handle1.Reset();
2525
2526 MessageLoop::current()->RunAllPending();
2527
2528 // Still no idle sockets, still one pending connect job.
2529 EXPECT_EQ(0, pool_->IdleSocketCount());
2530 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2531
2532 // The second socket connected, even though it was a Waiting Job.
2533 EXPECT_EQ(OK, callback.WaitForResult());
2534
2535 // And we can see there is still one job waiting.
2536 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2537
2538 // Finally, signal the waiting Connect.
2539 client_socket_factory_.SignalJobs();
2540 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2541
2542 MessageLoop::current()->RunAllPending();
2543}
2544
[email protected]2abfe90a2010-08-25 17:49:512545// Cover the case where on an available socket slot, we have one pending
2546// request that completes synchronously, thereby making the Group empty.
2547TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2548 const int kUnlimitedSockets = 100;
2549 const int kOneSocketPerGroup = 1;
2550 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2551
2552 // Make the first request asynchronous fail.
2553 // This will free up a socket slot later.
2554 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2555
2556 ClientSocketHandle handle1;
2557 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132558 EXPECT_EQ(ERR_IO_PENDING,
2559 handle1.Init("a",
2560 params_,
2561 kDefaultPriority,
2562 &callback1,
2563 pool_.get(),
2564 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512565 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2566
2567 // Make the second request synchronously fail. This should make the Group
2568 // empty.
2569 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2570 ClientSocketHandle handle2;
2571 TestCompletionCallback callback2;
2572 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2573 // when created.
[email protected]2431756e2010-09-29 20:26:132574 EXPECT_EQ(ERR_IO_PENDING,
2575 handle2.Init("a",
2576 params_,
2577 kDefaultPriority,
2578 &callback2,
2579 pool_.get(),
2580 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512581
2582 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2583
2584 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2585 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2586 EXPECT_FALSE(pool_->HasGroup("a"));
2587}
2588
[email protected]e1b54dc2010-10-06 21:27:222589TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2590 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2591
2592 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2593
2594 ClientSocketHandle handle1;
2595 TestCompletionCallback callback1;
2596 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2597 params_,
2598 kDefaultPriority,
2599 &callback1,
2600 pool_.get(),
2601 BoundNetLog()));
2602
2603 ClientSocketHandle handle2;
2604 TestCompletionCallback callback2;
2605 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2606 params_,
2607 kDefaultPriority,
2608 &callback2,
2609 pool_.get(),
2610 BoundNetLog()));
2611 ClientSocketHandle handle3;
2612 TestCompletionCallback callback3;
2613 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2614 params_,
2615 kDefaultPriority,
2616 &callback3,
2617 pool_.get(),
2618 BoundNetLog()));
2619
2620 EXPECT_EQ(OK, callback1.WaitForResult());
2621 EXPECT_EQ(OK, callback2.WaitForResult());
2622 EXPECT_EQ(OK, callback3.WaitForResult());
2623
2624 // Use the socket.
2625 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2626 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2627
2628 handle1.Reset();
2629 handle2.Reset();
2630 handle3.Reset();
2631
2632 EXPECT_EQ(OK, handle1.Init("a",
2633 params_,
2634 kDefaultPriority,
2635 &callback1,
2636 pool_.get(),
2637 BoundNetLog()));
2638 EXPECT_EQ(OK, handle2.Init("a",
2639 params_,
2640 kDefaultPriority,
2641 &callback2,
2642 pool_.get(),
2643 BoundNetLog()));
2644 EXPECT_EQ(OK, handle3.Init("a",
2645 params_,
2646 kDefaultPriority,
2647 &callback3,
2648 pool_.get(),
2649 BoundNetLog()));
2650
2651 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2652 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2653 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2654}
2655
[email protected]2c2bef152010-10-13 00:55:032656TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2657 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2658 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2659
2660 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2661
2662 ASSERT_TRUE(pool_->HasGroup("a"));
2663 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2664 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2665
2666 ClientSocketHandle handle1;
2667 TestCompletionCallback callback1;
2668 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2669 params_,
2670 kDefaultPriority,
2671 &callback1,
2672 pool_.get(),
2673 BoundNetLog()));
2674
2675 ClientSocketHandle handle2;
2676 TestCompletionCallback callback2;
2677 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2678 params_,
2679 kDefaultPriority,
2680 &callback2,
2681 pool_.get(),
2682 BoundNetLog()));
2683
2684 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2685 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2686
2687 EXPECT_EQ(OK, callback1.WaitForResult());
2688 EXPECT_EQ(OK, callback2.WaitForResult());
2689 handle1.Reset();
2690 handle2.Reset();
2691
2692 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2693 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2694}
2695
2696TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2697 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2698 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2699
2700 ClientSocketHandle handle1;
2701 TestCompletionCallback callback1;
2702 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2703 params_,
2704 kDefaultPriority,
2705 &callback1,
2706 pool_.get(),
2707 BoundNetLog()));
2708
2709 ASSERT_TRUE(pool_->HasGroup("a"));
2710 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2711 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2712
2713 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2714
2715 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2716 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2717
2718 ClientSocketHandle handle2;
2719 TestCompletionCallback callback2;
2720 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2721 params_,
2722 kDefaultPriority,
2723 &callback2,
2724 pool_.get(),
2725 BoundNetLog()));
2726
2727 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2728 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2729
2730 EXPECT_EQ(OK, callback1.WaitForResult());
2731 EXPECT_EQ(OK, callback2.WaitForResult());
2732 handle1.Reset();
2733 handle2.Reset();
2734
2735 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2736 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2737}
2738
2739TEST_F(ClientSocketPoolBaseTest,
2740 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2741 CreatePool(4, 4);
2742 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2743
2744 ClientSocketHandle handle1;
2745 TestCompletionCallback callback1;
2746 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2747 params_,
2748 kDefaultPriority,
2749 &callback1,
2750 pool_.get(),
2751 BoundNetLog()));
2752
2753 ClientSocketHandle handle2;
2754 TestCompletionCallback callback2;
2755 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2756 params_,
2757 kDefaultPriority,
2758 &callback2,
2759 pool_.get(),
2760 BoundNetLog()));
2761
2762 ClientSocketHandle handle3;
2763 TestCompletionCallback callback3;
2764 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2765 params_,
2766 kDefaultPriority,
2767 &callback3,
2768 pool_.get(),
2769 BoundNetLog()));
2770
2771 ASSERT_TRUE(pool_->HasGroup("a"));
2772 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2773 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2774
2775 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2776
2777 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2778 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2779
2780 EXPECT_EQ(OK, callback1.WaitForResult());
2781 EXPECT_EQ(OK, callback2.WaitForResult());
2782 EXPECT_EQ(OK, callback3.WaitForResult());
2783 handle1.Reset();
2784 handle2.Reset();
2785 handle3.Reset();
2786
2787 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2788 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2789}
2790
2791TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2792 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2793 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2794
2795 ASSERT_FALSE(pool_->HasGroup("a"));
2796
2797 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2798 BoundNetLog());
2799
2800 ASSERT_TRUE(pool_->HasGroup("a"));
2801 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2802
2803 ASSERT_FALSE(pool_->HasGroup("b"));
2804
2805 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2806 BoundNetLog());
2807
2808 ASSERT_FALSE(pool_->HasGroup("b"));
2809}
2810
2811TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2812 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2813 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2814
2815 ASSERT_FALSE(pool_->HasGroup("a"));
2816
2817 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2818 BoundNetLog());
2819
2820 ASSERT_TRUE(pool_->HasGroup("a"));
2821 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2822
2823 ASSERT_FALSE(pool_->HasGroup("b"));
2824
2825 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2826 BoundNetLog());
2827
2828 ASSERT_TRUE(pool_->HasGroup("b"));
2829 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2830}
2831
2832TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2833 CreatePool(4, 4);
2834 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2835
2836 ClientSocketHandle handle1;
2837 TestCompletionCallback callback1;
2838 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2839 params_,
2840 kDefaultPriority,
2841 &callback1,
2842 pool_.get(),
2843 BoundNetLog()));
2844 ASSERT_EQ(OK, callback1.WaitForResult());
2845 handle1.Reset();
2846
2847 ASSERT_TRUE(pool_->HasGroup("a"));
2848 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2849 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2850
2851 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2852
2853 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2854 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2855}
2856
2857TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2858 CreatePool(4, 4);
2859 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2860
2861 ClientSocketHandle handle1;
2862 TestCompletionCallback callback1;
2863 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2864 params_,
2865 kDefaultPriority,
2866 &callback1,
2867 pool_.get(),
2868 BoundNetLog()));
2869 ASSERT_EQ(OK, callback1.WaitForResult());
2870
2871 ASSERT_TRUE(pool_->HasGroup("a"));
2872 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2873 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2874 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2875
2876 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2877
2878 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2879 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2880 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2881}
2882
2883TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2884 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2885 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2886
2887 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2888 BoundNetLog());
2889
2890 ASSERT_TRUE(pool_->HasGroup("a"));
2891 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2892 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2893
2894 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2895 BoundNetLog());
2896
2897 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2898 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2899}
2900
2901TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2902 CreatePool(4, 4);
2903 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2904
2905 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2906
2907 ASSERT_TRUE(pool_->HasGroup("a"));
2908 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2909 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2910
2911 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2912 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2913 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2914
2915 ClientSocketHandle handle1;
2916 TestCompletionCallback callback1;
2917 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2918 params_,
2919 kDefaultPriority,
2920 &callback1,
2921 pool_.get(),
2922 BoundNetLog()));
2923 ASSERT_EQ(OK, callback1.WaitForResult());
2924
2925 ClientSocketHandle handle2;
2926 TestCompletionCallback callback2;
2927 int rv = handle2.Init("a",
2928 params_,
2929 kDefaultPriority,
2930 &callback2,
2931 pool_.get(),
2932 BoundNetLog());
2933 if (rv != OK) {
2934 EXPECT_EQ(ERR_IO_PENDING, rv);
2935 EXPECT_EQ(OK, callback2.WaitForResult());
2936 }
2937
2938 handle1.Reset();
2939 handle2.Reset();
2940
2941 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2942
2943 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2944 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2945 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2946}
2947
2948TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2949 CreatePool(4, 4);
2950 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2951
2952 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2953
2954 ASSERT_TRUE(pool_->HasGroup("a"));
2955 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2956 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2957
2958 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2959 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2960 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2961
2962 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2963 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2964 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2965
2966 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2967 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2968 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2969}
2970
2971TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
2972 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2973 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2974
2975 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2976
2977 ASSERT_TRUE(pool_->HasGroup("a"));
2978 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2979 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2980
2981 ClientSocketHandle handle1;
2982 TestCompletionCallback callback1;
2983 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2984 params_,
2985 kDefaultPriority,
2986 &callback1,
2987 pool_.get(),
2988 BoundNetLog()));
2989
2990 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2991 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2992
2993 ASSERT_EQ(OK, callback1.WaitForResult());
2994
2995 handle1.Reset();
2996
2997 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2998}
2999
[email protected]f6d1d6eb2009-06-24 20:16:093000} // namespace
3001
3002} // namespace net