blob: 843b6beeba068aa10b11f97ab0fe1f8ec7575def [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]b2fcd0e2010-12-01 15:19:40623 net::CapturingNetLog::EntryList entries;
624 log.GetEntries(&entries);
625
626 EXPECT_EQ(6u, entries.size());
[email protected]e9002a92010-01-29 07:10:46627 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40628 entries, 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17629 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40630 entries, 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46631 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40632 entries, 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
[email protected]06650c52010-06-03 00:49:17633 NetLog::PHASE_NONE));
634 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40635 entries, 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53636 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46637 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40638 entries, 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]06650c52010-06-03 00:49:17639 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40640 entries, 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34641}
642
[email protected]5fc08e32009-07-15 17:09:57643TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53644 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20645
[email protected]f6d1d6eb2009-06-24 20:16:09646 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06647 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53648 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
649
[email protected]2431756e2010-09-29 20:26:13650 EXPECT_EQ(OK,
651 handle.Init("a",
652 params_,
653 kDefaultPriority,
654 &callback,
655 pool_.get(),
656 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09657 EXPECT_TRUE(handle.is_initialized());
658 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09659 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30660
[email protected]b2fcd0e2010-12-01 15:19:40661 net::CapturingNetLog::EntryList entries;
662 log.GetEntries(&entries);
663
664 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:46665 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40666 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53667 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40668 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17669 NetLog::PHASE_NONE));
670 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40671 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53672 NetLog::PHASE_NONE));
673 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40674 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09675}
676
[email protected]ab838892009-06-30 18:49:05677TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53678 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20679
[email protected]ab838892009-06-30 18:49:05680 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53681 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
682
[email protected]2431756e2010-09-29 20:26:13683 ClientSocketHandle handle;
684 TestCompletionCallback callback;
[email protected]e60e47a2010-07-14 03:37:18685 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:13686 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:43687 HttpResponseInfo info;
688 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:13689 handle.set_ssl_error_response_info(info);
690 EXPECT_EQ(ERR_CONNECTION_FAILED,
691 handle.Init("a",
692 params_,
693 kDefaultPriority,
694 &callback,
695 pool_.get(),
696 log.bound()));
697 EXPECT_FALSE(handle.socket());
698 EXPECT_FALSE(handle.is_ssl_error());
699 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:30700
[email protected]b2fcd0e2010-12-01 15:19:40701 net::CapturingNetLog::EntryList entries;
702 log.GetEntries(&entries);
703
704 EXPECT_EQ(3u, entries.size());
[email protected]5a1d7ca2010-04-28 20:12:27705 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:40706 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17707 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:40708 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:17709 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02710 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:40711 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09712}
713
[email protected]211d21722009-07-22 15:48:53714TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
715 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
716
[email protected]9e743cd2010-03-16 07:03:53717 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30718
[email protected]211d21722009-07-22 15:48:53719 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
720 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
721 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
722 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
723
[email protected]2431756e2010-09-29 20:26:13724 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53725 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13726 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53727
728 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
729 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
730 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
731
[email protected]2431756e2010-09-29 20:26:13732 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53733
[email protected]2431756e2010-09-29 20:26:13734 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53735 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13736 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53737
738 EXPECT_EQ(1, GetOrderOfRequest(1));
739 EXPECT_EQ(2, GetOrderOfRequest(2));
740 EXPECT_EQ(3, GetOrderOfRequest(3));
741 EXPECT_EQ(4, GetOrderOfRequest(4));
742 EXPECT_EQ(5, GetOrderOfRequest(5));
743 EXPECT_EQ(6, GetOrderOfRequest(6));
744 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17745
746 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13747 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53748}
749
750TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
751 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
752
[email protected]9e743cd2010-03-16 07:03:53753 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30754
[email protected]211d21722009-07-22 15:48:53755 // Reach all limits: max total sockets, and max sockets per group.
756 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
757 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
758 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
759 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
760
[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 // Now create a new group and verify that we don't starve it.
766 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
767
[email protected]2431756e2010-09-29 20:26:13768 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53769
[email protected]2431756e2010-09-29 20:26:13770 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53771 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13772 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53773
774 EXPECT_EQ(1, GetOrderOfRequest(1));
775 EXPECT_EQ(2, GetOrderOfRequest(2));
776 EXPECT_EQ(3, GetOrderOfRequest(3));
777 EXPECT_EQ(4, GetOrderOfRequest(4));
778 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17779
780 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13781 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53782}
783
784TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
785 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
786
[email protected]ac790b42009-12-02 04:31:31787 EXPECT_EQ(OK, StartRequest("b", LOWEST));
788 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
789 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
790 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53791
[email protected]2431756e2010-09-29 20:26:13792 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53793 client_socket_factory_.allocation_count());
794
[email protected]ac790b42009-12-02 04:31:31795 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
796 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
797 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53798
[email protected]2431756e2010-09-29 20:26:13799 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53800
[email protected]2431756e2010-09-29 20:26:13801 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53802
803 // First 4 requests don't have to wait, and finish in order.
804 EXPECT_EQ(1, GetOrderOfRequest(1));
805 EXPECT_EQ(2, GetOrderOfRequest(2));
806 EXPECT_EQ(3, GetOrderOfRequest(3));
807 EXPECT_EQ(4, GetOrderOfRequest(4));
808
[email protected]ac790b42009-12-02 04:31:31809 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
810 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53811 EXPECT_EQ(7, GetOrderOfRequest(5));
812 EXPECT_EQ(6, GetOrderOfRequest(6));
813 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17814
815 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13816 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]211d21722009-07-22 15:48:53817}
818
819TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
820 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
821
[email protected]ac790b42009-12-02 04:31:31822 EXPECT_EQ(OK, StartRequest("a", LOWEST));
823 EXPECT_EQ(OK, StartRequest("a", LOW));
824 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
825 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[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());
829
[email protected]ac790b42009-12-02 04:31:31830 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
831 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
832 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53833
[email protected]2431756e2010-09-29 20:26:13834 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53835
[email protected]2431756e2010-09-29 20:26:13836 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53837 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13838 EXPECT_EQ(requests_size() - kDefaultMaxSockets, completion_count());
[email protected]211d21722009-07-22 15:48:53839
840 // First 4 requests don't have to wait, and finish in order.
841 EXPECT_EQ(1, GetOrderOfRequest(1));
842 EXPECT_EQ(2, GetOrderOfRequest(2));
843 EXPECT_EQ(3, GetOrderOfRequest(3));
844 EXPECT_EQ(4, GetOrderOfRequest(4));
845
846 // Request ("b", 7) has the highest priority, but we can't make new socket for
847 // group "b", because it has reached the per-group limit. Then we make
848 // socket for ("c", 6), because it has higher priority than ("a", 4),
849 // and we still can't make a socket for group "b".
850 EXPECT_EQ(5, GetOrderOfRequest(5));
851 EXPECT_EQ(6, GetOrderOfRequest(6));
852 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17853
854 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13855 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53856}
857
858// Make sure that we count connecting sockets against the total limit.
859TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
860 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
861
862 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
863 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
864 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
865
866 // Create one asynchronous request.
867 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
869
[email protected]6b175382009-10-13 06:47:47870 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
871 // actually become pending until 2ms after they have been created. In order
872 // to flush all tasks, we need to wait so that we know there are no
873 // soon-to-be-pending tasks waiting.
874 PlatformThread::Sleep(10);
875 MessageLoop::current()->RunAllPending();
876
[email protected]211d21722009-07-22 15:48:53877 // The next synchronous request should wait for its turn.
878 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
879 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
880
[email protected]2431756e2010-09-29 20:26:13881 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53882
[email protected]2431756e2010-09-29 20:26:13883 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]211d21722009-07-22 15:48:53884 client_socket_factory_.allocation_count());
885
886 EXPECT_EQ(1, GetOrderOfRequest(1));
887 EXPECT_EQ(2, GetOrderOfRequest(2));
888 EXPECT_EQ(3, GetOrderOfRequest(3));
889 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17890 EXPECT_EQ(5, GetOrderOfRequest(5));
891
892 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:13893 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53894}
895
[email protected]6427fe22010-04-16 22:27:41896TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
897 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
898 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
899
900 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
901 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
902 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
903 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
904
905 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
906
907 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
908
909 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
910 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
911
912 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
913
[email protected]2431756e2010-09-29 20:26:13914 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41915 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13916 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41917 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:13918 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
919 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]6427fe22010-04-16 22:27:41920 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
921}
922
[email protected]d7027bb2010-05-10 18:58:54923TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
924 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
925 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
926
927 ClientSocketHandle handle;
928 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13929 EXPECT_EQ(ERR_IO_PENDING,
930 handle.Init("a",
931 params_,
932 kDefaultPriority,
933 &callback,
934 pool_.get(),
935 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54936
937 ClientSocketHandle handles[4];
938 for (size_t i = 0; i < arraysize(handles); ++i) {
939 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13940 EXPECT_EQ(ERR_IO_PENDING,
941 handles[i].Init("b",
942 params_,
943 kDefaultPriority,
944 &callback,
945 pool_.get(),
946 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:54947 }
948
949 // One will be stalled, cancel all the handles now.
950 // This should hit the OnAvailableSocketSlot() code where we previously had
951 // stalled groups, but no longer have any.
952 for (size_t i = 0; i < arraysize(handles); ++i)
953 handles[i].Reset();
954}
955
[email protected]eb5a99382010-07-11 03:18:26956TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54957 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
958 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
959
[email protected]eb5a99382010-07-11 03:18:26960 {
961 ClientSocketHandle handles[kDefaultMaxSockets];
962 TestCompletionCallback callbacks[kDefaultMaxSockets];
963 for (int i = 0; i < kDefaultMaxSockets; ++i) {
[email protected]2431756e2010-09-29 20:26:13964 EXPECT_EQ(OK, handles[i].Init(base::IntToString(i),
965 params_,
[email protected]e83326f2010-07-31 17:29:25966 kDefaultPriority,
[email protected]2431756e2010-09-29 20:26:13967 &callbacks[i],
968 pool_.get(),
969 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26970 }
971
972 // Force a stalled group.
973 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:54974 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:13975 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
976 params_,
977 kDefaultPriority,
978 &callback,
979 pool_.get(),
980 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:26981
982 // Cancel the stalled request.
983 stalled_handle.Reset();
984
985 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
986 EXPECT_EQ(0, pool_->IdleSocketCount());
987
988 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:54989 }
990
[email protected]43a21b82010-06-10 21:30:54991 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
992 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
[email protected]eb5a99382010-07-11 03:18:26993}
[email protected]43a21b82010-06-10 21:30:54994
[email protected]eb5a99382010-07-11 03:18:26995TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) {
996 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
997 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
998
999 {
1000 ClientSocketHandle handles[kDefaultMaxSockets];
1001 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1002 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131003 EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(base::IntToString(i),
1004 params_,
1005 kDefaultPriority,
1006 &callback,
1007 pool_.get(),
1008 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261009 }
1010
1011 // Force a stalled group.
1012 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1013 ClientSocketHandle stalled_handle;
[email protected]43a21b82010-06-10 21:30:541014 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131015 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1016 params_,
1017 kDefaultPriority,
1018 &callback,
1019 pool_.get(),
1020 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261021
1022 // Since it is stalled, it should have no connect jobs.
1023 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1024
1025 // Cancel the stalled request.
1026 handles[0].Reset();
1027
[email protected]eb5a99382010-07-11 03:18:261028 // Now we should have a connect job.
1029 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("foo"));
1030
1031 // The stalled socket should connect.
1032 EXPECT_EQ(OK, callback.WaitForResult());
1033
1034 EXPECT_EQ(kDefaultMaxSockets + 1,
1035 client_socket_factory_.allocation_count());
1036 EXPECT_EQ(0, pool_->IdleSocketCount());
1037 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("foo"));
1038
1039 // Dropping out of scope will close all handles and return them to idle.
[email protected]43a21b82010-06-10 21:30:541040 }
1041
[email protected]eb5a99382010-07-11 03:18:261042 EXPECT_EQ(1, pool_->IdleSocketCount());
1043}
[email protected]43a21b82010-06-10 21:30:541044
[email protected]eb5a99382010-07-11 03:18:261045TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1046 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1047 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]43a21b82010-06-10 21:30:541048
[email protected]eb5a99382010-07-11 03:18:261049 ClientSocketHandle stalled_handle;
1050 TestCompletionCallback callback;
1051 {
1052 ClientSocketHandle handles[kDefaultMaxSockets];
1053 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1054 TestCompletionCallback callback;
[email protected]d8eb84242010-09-25 02:25:061055 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf("Take 2: %d", i),
[email protected]2431756e2010-09-29 20:26:131056 params_,
1057 kDefaultPriority,
1058 &callback,
1059 pool_.get(),
1060 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261061 }
1062
1063 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1064 EXPECT_EQ(0, pool_->IdleSocketCount());
1065
1066 // Now we will hit the socket limit.
[email protected]2431756e2010-09-29 20:26:131067 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1068 params_,
1069 kDefaultPriority,
1070 &callback,
1071 pool_.get(),
1072 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:261073
1074 // Dropping out of scope will close all handles and return them to idle.
1075 }
[email protected]43a21b82010-06-10 21:30:541076
1077 // But if we wait for it, the released idle sockets will be closed in
1078 // preference of the waiting request.
[email protected]8ae03f42010-07-07 19:08:101079 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]eb5a99382010-07-11 03:18:261080
1081 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1082 EXPECT_EQ(3, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:541083}
1084
1085// Regression test for http://crbug.com/40952.
1086TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
1087 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]06d94042010-08-25 01:45:221088 pool_->EnableConnectBackupJobs();
[email protected]43a21b82010-06-10 21:30:541089 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1090
1091 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1092 ClientSocketHandle handle;
1093 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:131094 EXPECT_EQ(OK, handle.Init(base::IntToString(i),
1095 params_,
1096 kDefaultPriority,
1097 &callback,
1098 pool_.get(),
1099 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541100 }
1101
1102 // Flush all the DoReleaseSocket tasks.
1103 MessageLoop::current()->RunAllPending();
1104
1105 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
1106 // reuse a socket.
1107 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1108 ClientSocketHandle handle;
1109 TestCompletionCallback callback;
1110
1111 // "0" is special here, since it should be the first entry in the sorted map,
1112 // which is the one which we would close an idle socket for. We shouldn't
1113 // close an idle socket though, since we should reuse the idle socket.
[email protected]2431756e2010-09-29 20:26:131114 EXPECT_EQ(OK, handle.Init("0",
1115 params_,
1116 kDefaultPriority,
1117 &callback,
1118 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211119 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:541120
1121 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1122 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
1123}
1124
[email protected]ab838892009-06-30 18:49:051125TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531126 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091127
[email protected]c9d6a1d2009-07-14 16:15:201128 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1129 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]c9c6f5c2010-07-31 01:30:031130 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", IDLE));
[email protected]ac790b42009-12-02 04:31:311131 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1132 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1133 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1134 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1135 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091136
[email protected]2431756e2010-09-29 20:26:131137 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091138
[email protected]c9d6a1d2009-07-14 16:15:201139 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1140 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131141 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1142 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091143
[email protected]c9d6a1d2009-07-14 16:15:201144 EXPECT_EQ(1, GetOrderOfRequest(1));
1145 EXPECT_EQ(2, GetOrderOfRequest(2));
[email protected]c9c6f5c2010-07-31 01:30:031146 EXPECT_EQ(8, GetOrderOfRequest(3));
1147 EXPECT_EQ(6, GetOrderOfRequest(4));
1148 EXPECT_EQ(4, GetOrderOfRequest(5));
1149 EXPECT_EQ(3, GetOrderOfRequest(6));
1150 EXPECT_EQ(5, GetOrderOfRequest(7));
1151 EXPECT_EQ(7, GetOrderOfRequest(8));
[email protected]75439d3b2009-07-23 22:11:171152
1153 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131154 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(9));
[email protected]f6d1d6eb2009-06-24 20:16:091155}
1156
[email protected]ab838892009-06-30 18:49:051157TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091159
[email protected]c9d6a1d2009-07-14 16:15:201160 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1161 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311162 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1163 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1164 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1165 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1166 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091167
[email protected]2431756e2010-09-29 20:26:131168 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091169
[email protected]2431756e2010-09-29 20:26:131170 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i)
1171 EXPECT_EQ(OK, request(i)->WaitForResult());
[email protected]c9d6a1d2009-07-14 16:15:201172
[email protected]2431756e2010-09-29 20:26:131173 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]c9d6a1d2009-07-14 16:15:201174 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131175 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1176 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091177}
1178
1179// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051180// The pending connect job will be cancelled and should not call back into
1181// ClientSocketPoolBase.
1182TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531183 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201184
[email protected]ab838892009-06-30 18:49:051185 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131186 ClientSocketHandle handle;
1187 TestCompletionCallback callback;
1188 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1189 params_,
1190 kDefaultPriority,
1191 &callback,
1192 pool_.get(),
1193 BoundNetLog()));
1194 handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091195}
1196
[email protected]ab838892009-06-30 18:49:051197TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531198 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201199
[email protected]ab838892009-06-30 18:49:051200 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061201 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091202 TestCompletionCallback callback;
[email protected]f6d1d6eb2009-06-24 20:16:091203
[email protected]2431756e2010-09-29 20:26:131204 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1205 params_,
1206 kDefaultPriority,
1207 &callback,
1208 pool_.get(),
1209 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091210
1211 handle.Reset();
1212
1213 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:131214 EXPECT_EQ(ERR_IO_PENDING,
1215 handle.Init("a",
1216 params_,
1217 kDefaultPriority,
1218 &callback2,
1219 pool_.get(),
1220 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091221
1222 EXPECT_EQ(OK, callback2.WaitForResult());
1223 EXPECT_FALSE(callback.have_result());
1224
1225 handle.Reset();
1226}
1227
[email protected]ab838892009-06-30 18:49:051228TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531229 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091230
[email protected]c9d6a1d2009-07-14 16:15:201231 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1232 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1234 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1235 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1236 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091238
1239 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201240 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]2431756e2010-09-29 20:26:131241 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
1242 (*requests())[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091243
[email protected]2431756e2010-09-29 20:26:131244 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091245
[email protected]c9d6a1d2009-07-14 16:15:201246 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1247 client_socket_factory_.allocation_count());
[email protected]2431756e2010-09-29 20:26:131248 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup - 1,
1249 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091250
[email protected]c9d6a1d2009-07-14 16:15:201251 EXPECT_EQ(1, GetOrderOfRequest(1));
1252 EXPECT_EQ(2, GetOrderOfRequest(2));
1253 EXPECT_EQ(5, GetOrderOfRequest(3));
1254 EXPECT_EQ(3, GetOrderOfRequest(4));
[email protected]2431756e2010-09-29 20:26:131255 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
1256 GetOrderOfRequest(5)); // Canceled request.
[email protected]c9d6a1d2009-07-14 16:15:201257 EXPECT_EQ(4, GetOrderOfRequest(6));
1258 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171259
1260 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:131261 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091262}
1263
1264class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1265 public:
[email protected]2ab05b52009-07-01 23:57:581266 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241267 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581268 TestConnectJobFactory* test_connect_job_factory,
1269 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091270 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061271 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581272 within_callback_(false),
1273 test_connect_job_factory_(test_connect_job_factory),
1274 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091275
1276 virtual void RunWithParams(const Tuple1<int>& params) {
1277 callback_.RunWithParams(params);
1278 ASSERT_EQ(OK, params.a);
1279
1280 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581281 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111282
1283 // Don't allow reuse of the socket. Disconnect it and then release it and
1284 // run through the MessageLoop once to get it completely released.
1285 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091286 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111287 {
1288 MessageLoop::ScopedNestableTaskAllower nestable(
1289 MessageLoop::current());
1290 MessageLoop::current()->RunAllPending();
1291 }
[email protected]f6d1d6eb2009-06-24 20:16:091292 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471293 TestCompletionCallback next_job_callback;
[email protected]ad8e04a2010-11-01 04:16:271294 scoped_refptr<TestSocketParams> params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:131295 int rv = handle_->Init("a",
1296 params,
1297 kDefaultPriority,
1298 &next_job_callback,
1299 pool_,
1300 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581301 switch (next_job_type_) {
1302 case TestConnectJob::kMockJob:
1303 EXPECT_EQ(OK, rv);
1304 break;
1305 case TestConnectJob::kMockPendingJob:
1306 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471307
1308 // For pending jobs, wait for new socket to be created. This makes
1309 // sure there are no more pending operations nor any unclosed sockets
1310 // when the test finishes.
1311 // We need to give it a little bit of time to run, so that all the
1312 // operations that happen on timers (e.g. cleanup of idle
1313 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111314 {
1315 MessageLoop::ScopedNestableTaskAllower nestable(
1316 MessageLoop::current());
1317 PlatformThread::Sleep(10);
1318 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1319 }
[email protected]2ab05b52009-07-01 23:57:581320 break;
1321 default:
1322 FAIL() << "Unexpected job type: " << next_job_type_;
1323 break;
1324 }
[email protected]f6d1d6eb2009-06-24 20:16:091325 }
1326 }
1327
1328 int WaitForResult() {
1329 return callback_.WaitForResult();
1330 }
1331
1332 private:
1333 ClientSocketHandle* const handle_;
[email protected]2431756e2010-09-29 20:26:131334 TestClientSocketPool* const pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091335 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581336 TestConnectJobFactory* const test_connect_job_factory_;
1337 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091338 TestCompletionCallback callback_;
1339};
1340
[email protected]2ab05b52009-07-01 23:57:581341TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531342 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201343
[email protected]0b7648c2009-07-06 20:14:011344 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061345 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581346 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061347 &handle, pool_.get(), connect_job_factory_,
1348 TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131349 int rv = handle.Init("a",
1350 params_,
1351 kDefaultPriority,
1352 &callback,
1353 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211354 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091355 ASSERT_EQ(ERR_IO_PENDING, rv);
1356
1357 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581358}
[email protected]f6d1d6eb2009-06-24 20:16:091359
[email protected]2ab05b52009-07-01 23:57:581360TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531361 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201362
[email protected]0b7648c2009-07-06 20:14:011363 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061364 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581365 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061366 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2431756e2010-09-29 20:26:131367 int rv = handle.Init("a",
1368 params_,
1369 kDefaultPriority,
1370 &callback,
1371 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211372 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581373 ASSERT_EQ(ERR_IO_PENDING, rv);
1374
1375 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091376}
1377
1378// Make sure that pending requests get serviced after active requests get
1379// cancelled.
[email protected]ab838892009-06-30 18:49:051380TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531381 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201382
[email protected]0b7648c2009-07-06 20:14:011383 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091384
[email protected]c9d6a1d2009-07-14 16:15:201385 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1386 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1387 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1388 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1389 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1390 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1391 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091392
[email protected]c9d6a1d2009-07-14 16:15:201393 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1394 // Let's cancel them.
1395 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]2431756e2010-09-29 20:26:131396 ASSERT_FALSE(request(i)->handle()->is_initialized());
1397 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091398 }
1399
[email protected]f6d1d6eb2009-06-24 20:16:091400 // Let's wait for the rest to complete now.
[email protected]2431756e2010-09-29 20:26:131401 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_size(); ++i) {
1402 EXPECT_EQ(OK, request(i)->WaitForResult());
1403 request(i)->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091404 }
1405
[email protected]2431756e2010-09-29 20:26:131406 EXPECT_EQ(requests_size() - kDefaultMaxSocketsPerGroup,
1407 completion_count());
[email protected]f6d1d6eb2009-06-24 20:16:091408}
1409
1410// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051411TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531412 const size_t kMaxSockets = 5;
1413 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201414
[email protected]0b7648c2009-07-06 20:14:011415 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091416
[email protected]211d21722009-07-22 15:48:531417 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1418 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091419
1420 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531421 for (size_t i = 0; i < kNumberOfRequests; ++i)
1422 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091423
[email protected]211d21722009-07-22 15:48:531424 for (size_t i = 0; i < kNumberOfRequests; ++i)
[email protected]2431756e2010-09-29 20:26:131425 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091426}
1427
[email protected]5fc08e32009-07-15 17:09:571428TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531429 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571430
1431 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1432
[email protected]2431756e2010-09-29 20:26:131433 ClientSocketHandle handle;
1434 TestCompletionCallback callback;
1435 int rv = handle.Init("a",
1436 params_,
1437 kDefaultPriority,
1438 &callback,
1439 pool_.get(),
1440 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571441 EXPECT_EQ(ERR_IO_PENDING, rv);
1442
1443 // Cancel the active request.
[email protected]2431756e2010-09-29 20:26:131444 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571445
[email protected]2431756e2010-09-29 20:26:131446 rv = handle.Init("a",
1447 params_,
1448 kDefaultPriority,
1449 &callback,
1450 pool_.get(),
1451 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571452 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131453 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571454
[email protected]2431756e2010-09-29 20:26:131455 EXPECT_FALSE(handle.is_reused());
[email protected]5fc08e32009-07-15 17:09:571456 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1457}
1458
[email protected]2b7523d2009-07-29 20:29:231459// Regression test for http://crbug.com/17985.
1460TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1461 const int kMaxSockets = 3;
1462 const int kMaxSocketsPerGroup = 2;
1463 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1464
[email protected]ac790b42009-12-02 04:31:311465 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231466
1467 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1468 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1469
1470 // This is going to be a pending request in an otherwise empty group.
1471 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1472
1473 // Reach the maximum socket limit.
1474 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1475
1476 // Create a stalled group with high priorities.
1477 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1478 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]2b7523d2009-07-29 20:29:231479
[email protected]eb5a99382010-07-11 03:18:261480 // Release the first two sockets from "a". Because this is a keepalive,
1481 // the first release will unblock the pending request for "a". The
1482 // second release will unblock a request for "c", becaue it is the next
1483 // high priority socket.
[email protected]2431756e2010-09-29 20:26:131484 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
1485 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::KEEP_ALIVE));
[email protected]2b7523d2009-07-29 20:29:231486
1487 // Closing idle sockets should not get us into trouble, but in the bug
1488 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411489 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541490 pool_->CloseIdleSockets();
[email protected]eb5a99382010-07-11 03:18:261491
1492 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]2b7523d2009-07-29 20:29:231493}
1494
[email protected]4d3b05d2010-01-27 21:27:291495TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571497
1498 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131499 ClientSocketHandle handle;
1500 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531501 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131502 int rv = handle.Init("a",
1503 params_,
1504 LOWEST,
1505 &callback,
1506 pool_.get(),
1507 log.bound());
[email protected]5fc08e32009-07-15 17:09:571508 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131509 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1510 EXPECT_EQ(OK, callback.WaitForResult());
1511 EXPECT_TRUE(handle.is_initialized());
1512 EXPECT_TRUE(handle.socket());
1513 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301514
[email protected]b2fcd0e2010-12-01 15:19:401515 net::CapturingNetLog::EntryList entries;
1516 log.GetEntries(&entries);
1517
1518 EXPECT_EQ(4u, entries.size());
[email protected]e9002a92010-01-29 07:10:461519 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401520 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171521 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401522 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171523 NetLog::PHASE_NONE));
1524 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401525 entries, 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]06650c52010-06-03 00:49:171526 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461527 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401528 entries, 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571529}
1530
[email protected]4d3b05d2010-01-27 21:27:291531TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571532 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531533 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571534
1535 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2431756e2010-09-29 20:26:131536 ClientSocketHandle handle;
1537 TestCompletionCallback callback;
[email protected]9e743cd2010-03-16 07:03:531538 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]e60e47a2010-07-14 03:37:181539 // Set the additional error state members to ensure that they get cleared.
[email protected]2431756e2010-09-29 20:26:131540 handle.set_is_ssl_error(true);
[email protected]8b498692010-07-16 17:11:431541 HttpResponseInfo info;
1542 info.headers = new HttpResponseHeaders("");
[email protected]2431756e2010-09-29 20:26:131543 handle.set_ssl_error_response_info(info);
1544 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
1545 params_,
1546 kDefaultPriority,
1547 &callback,
1548 pool_.get(),
1549 log.bound()));
1550 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1551 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1552 EXPECT_FALSE(handle.is_ssl_error());
1553 EXPECT_TRUE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]fd7b7c92009-08-20 19:38:301554
[email protected]b2fcd0e2010-12-01 15:19:401555 net::CapturingNetLog::EntryList entries;
1556 log.GetEntries(&entries);
1557
1558 EXPECT_EQ(3u, entries.size());
[email protected]e9002a92010-01-29 07:10:461559 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]b2fcd0e2010-12-01 15:19:401560 entries, 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171561 EXPECT_TRUE(LogContainsEvent(
[email protected]b2fcd0e2010-12-01 15:19:401562 entries, 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
[email protected]06650c52010-06-03 00:49:171563 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321564 EXPECT_TRUE(LogContainsEndEvent(
[email protected]b2fcd0e2010-12-01 15:19:401565 entries, 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571566}
1567
[email protected]4d3b05d2010-01-27 21:27:291568TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101569 // TODO(eroman): Add back the log expectations! Removed them because the
1570 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531571 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571572
1573 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2431756e2010-09-29 20:26:131574 ClientSocketHandle handle;
1575 TestCompletionCallback callback;
1576 ClientSocketHandle handle2;
1577 TestCompletionCallback callback2;
[email protected]5fc08e32009-07-15 17:09:571578
[email protected]2431756e2010-09-29 20:26:131579 EXPECT_EQ(ERR_IO_PENDING,
1580 handle.Init("a",
1581 params_,
1582 kDefaultPriority,
1583 &callback,
1584 pool_.get(),
1585 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531586 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131587 EXPECT_EQ(ERR_IO_PENDING,
1588 handle2.Init("a",
1589 params_,
1590 kDefaultPriority,
1591 &callback2,
1592 pool_.get(),
1593 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571594
[email protected]2431756e2010-09-29 20:26:131595 handle.Reset();
[email protected]5fc08e32009-07-15 17:09:571596
[email protected]fd7b7c92009-08-20 19:38:301597
1598 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301599
[email protected]2431756e2010-09-29 20:26:131600 EXPECT_EQ(OK, callback2.WaitForResult());
1601 handle2.Reset();
[email protected]fd7b7c92009-08-20 19:38:301602
1603 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531604 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571605}
1606
[email protected]4d3b05d2010-01-27 21:27:291607TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341608 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1609
[email protected]17a0c6c2009-08-04 00:07:041610 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1611
[email protected]ac790b42009-12-02 04:31:311612 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1613 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1614 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1615 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341616
1617 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]2431756e2010-09-29 20:26:131618 (*requests())[2]->handle()->Reset();
1619 (*requests())[3]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341620 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1621
[email protected]2431756e2010-09-29 20:26:131622 (*requests())[1]->handle()->Reset();
[email protected]974ebd62009-08-03 23:14:341623 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1624
[email protected]2431756e2010-09-29 20:26:131625 (*requests())[0]->handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261626 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341627}
1628
[email protected]5fc08e32009-07-15 17:09:571629// When requests and ConnectJobs are not coupled, the request will get serviced
1630// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291631TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531632 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571633
1634 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321635 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571636
[email protected]2431756e2010-09-29 20:26:131637 std::vector<TestSocketRequest*> request_order;
1638 size_t completion_count; // unused
1639 TestSocketRequest req1(&request_order, &completion_count);
1640 int rv = req1.handle()->Init("a",
1641 params_,
1642 kDefaultPriority,
1643 &req1, pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211644 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571645 EXPECT_EQ(ERR_IO_PENDING, rv);
1646 EXPECT_EQ(OK, req1.WaitForResult());
1647
1648 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1649 // without a job.
1650 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1651
[email protected]2431756e2010-09-29 20:26:131652 TestSocketRequest req2(&request_order, &completion_count);
1653 rv = req2.handle()->Init("a",
1654 params_,
1655 kDefaultPriority,
1656 &req2,
1657 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211658 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571659 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131660 TestSocketRequest req3(&request_order, &completion_count);
1661 rv = req3.handle()->Init("a",
1662 params_,
1663 kDefaultPriority,
1664 &req3,
1665 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211666 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571667 EXPECT_EQ(ERR_IO_PENDING, rv);
1668
1669 // Both Requests 2 and 3 are pending. We release socket 1 which should
1670 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331671 req1.handle()->Reset();
[email protected]eb5a99382010-07-11 03:18:261672 MessageLoop::current()->RunAllPending(); // Run the released socket wakeups
[email protected]a6c59f62009-07-29 16:33:331673 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571674 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331675 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571676
1677 // Signal job 2, which should service request 3.
1678
1679 client_socket_factory_.SignalJobs();
1680 EXPECT_EQ(OK, req3.WaitForResult());
1681
[email protected]2431756e2010-09-29 20:26:131682 ASSERT_EQ(3U, request_order.size());
1683 EXPECT_EQ(&req1, request_order[0]);
1684 EXPECT_EQ(&req2, request_order[1]);
1685 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571686 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1687}
1688
1689// The requests are not coupled to the jobs. So, the requests should finish in
1690// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291691TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531692 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571693 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321694 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571695
[email protected]2431756e2010-09-29 20:26:131696 std::vector<TestSocketRequest*> request_order;
1697 size_t completion_count; // unused
1698 TestSocketRequest req1(&request_order, &completion_count);
1699 int rv = req1.handle()->Init("a",
1700 params_,
1701 kDefaultPriority,
1702 &req1,
1703 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211704 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571705 EXPECT_EQ(ERR_IO_PENDING, rv);
1706
[email protected]2431756e2010-09-29 20:26:131707 TestSocketRequest req2(&request_order, &completion_count);
1708 rv = req2.handle()->Init("a",
1709 params_,
1710 kDefaultPriority,
1711 &req2,
1712 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211713 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571714 EXPECT_EQ(ERR_IO_PENDING, rv);
1715
1716 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321717 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571718
[email protected]2431756e2010-09-29 20:26:131719 TestSocketRequest req3(&request_order, &completion_count);
1720 rv = req3.handle()->Init("a",
1721 params_,
1722 kDefaultPriority,
1723 &req3,
1724 pool_.get(),
[email protected]df4b4ef2010-07-12 18:25:211725 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571726 EXPECT_EQ(ERR_IO_PENDING, rv);
1727
1728 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1729 EXPECT_EQ(OK, req2.WaitForResult());
1730 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1731
[email protected]2431756e2010-09-29 20:26:131732 ASSERT_EQ(3U, request_order.size());
1733 EXPECT_EQ(&req1, request_order[0]);
1734 EXPECT_EQ(&req2, request_order[1]);
1735 EXPECT_EQ(&req3, request_order[2]);
[email protected]5fc08e32009-07-15 17:09:571736}
1737
[email protected]e6ec67b2010-06-16 00:12:461738TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571740 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321741 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571742
[email protected]2431756e2010-09-29 20:26:131743 ClientSocketHandle handle;
1744 TestCompletionCallback callback;
1745 int rv = handle.Init("a",
1746 params_,
1747 kDefaultPriority,
1748 &callback,
1749 pool_.get(),
1750 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571751 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131752 EXPECT_EQ(LOAD_STATE_IDLE, handle.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571753
1754 MessageLoop::current()->RunAllPending();
1755
[email protected]2431756e2010-09-29 20:26:131756 ClientSocketHandle handle2;
1757 TestCompletionCallback callback2;
1758 rv = handle2.Init("a",
1759 params_,
1760 kDefaultPriority,
1761 &callback2, pool_.get(),
1762 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571763 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131764 EXPECT_NE(LOAD_STATE_IDLE, handle.GetLoadState());
1765 EXPECT_NE(LOAD_STATE_IDLE, handle2.GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571766}
1767
[email protected]e772db3f2010-07-12 18:11:131768TEST_F(ClientSocketPoolBaseTest, Recoverable) {
1769 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1770 connect_job_factory_->set_job_type(TestConnectJob::kMockRecoverableJob);
1771
[email protected]2431756e2010-09-29 20:26:131772 ClientSocketHandle handle;
1773 TestCompletionCallback callback;
1774 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, handle.Init("a",
1775 params_,
1776 kDefaultPriority,
1777 &callback, pool_.get(),
1778 BoundNetLog()));
1779 EXPECT_TRUE(handle.is_initialized());
1780 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131781}
1782
1783TEST_F(ClientSocketPoolBaseTest, AsyncRecoverable) {
1784 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1785
1786 connect_job_factory_->set_job_type(
1787 TestConnectJob::kMockPendingRecoverableJob);
[email protected]2431756e2010-09-29 20:26:131788 ClientSocketHandle handle;
1789 TestCompletionCallback callback;
1790 EXPECT_EQ(ERR_IO_PENDING,
1791 handle.Init("a",
1792 params_,
1793 kDefaultPriority,
1794 &callback,
1795 pool_.get(),
1796 BoundNetLog()));
1797 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1798 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
1799 EXPECT_TRUE(handle.is_initialized());
1800 EXPECT_TRUE(handle.socket());
[email protected]e772db3f2010-07-12 18:11:131801}
1802
[email protected]e60e47a2010-07-14 03:37:181803TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) {
1804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1805 connect_job_factory_->set_job_type(
1806 TestConnectJob::kMockAdditionalErrorStateJob);
1807
[email protected]2431756e2010-09-29 20:26:131808 ClientSocketHandle handle;
1809 TestCompletionCallback callback;
1810 EXPECT_EQ(ERR_CONNECTION_FAILED,
1811 handle.Init("a",
1812 params_,
1813 kDefaultPriority,
1814 &callback,
1815 pool_.get(),
1816 BoundNetLog()));
1817 EXPECT_FALSE(handle.is_initialized());
1818 EXPECT_FALSE(handle.socket());
1819 EXPECT_TRUE(handle.is_ssl_error());
1820 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181821}
1822
1823TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) {
1824 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1825
1826 connect_job_factory_->set_job_type(
1827 TestConnectJob::kMockPendingAdditionalErrorStateJob);
[email protected]2431756e2010-09-29 20:26:131828 ClientSocketHandle handle;
1829 TestCompletionCallback callback;
1830 EXPECT_EQ(ERR_IO_PENDING,
1831 handle.Init("a",
1832 params_,
1833 kDefaultPriority,
1834 &callback,
1835 pool_.get(),
1836 BoundNetLog()));
1837 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
1838 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1839 EXPECT_FALSE(handle.is_initialized());
1840 EXPECT_FALSE(handle.socket());
1841 EXPECT_TRUE(handle.is_ssl_error());
1842 EXPECT_FALSE(handle.ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:181843}
1844
[email protected]4d3b05d2010-01-27 21:27:291845TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161846 CreatePoolWithIdleTimeouts(
1847 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1848 base::TimeDelta(), // Time out unused sockets immediately.
1849 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1850
1851 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1852
1853 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1854
[email protected]2431756e2010-09-29 20:26:131855 ClientSocketHandle handle;
1856 TestCompletionCallback callback;
1857 int rv = handle.Init("a",
1858 params_,
1859 LOWEST,
1860 &callback,
1861 pool_.get(),
1862 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161863 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131864 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle));
[email protected]9bf28db2009-08-29 01:35:161865
[email protected]2431756e2010-09-29 20:26:131866 ClientSocketHandle handle2;
1867 TestCompletionCallback callback2;
1868 rv = handle2.Init("a",
1869 params_,
1870 LOWEST,
1871 &callback2,
1872 pool_.get(),
1873 BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161874 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2431756e2010-09-29 20:26:131875 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &handle2));
[email protected]9bf28db2009-08-29 01:35:161876
1877 // Cancel one of the requests. Wait for the other, which will get the first
1878 // job. Release the socket. Run the loop again to make sure the second
1879 // socket is sitting idle and the first one is released (since ReleaseSocket()
1880 // just posts a DoReleaseSocket() task).
1881
[email protected]2431756e2010-09-29 20:26:131882 handle.Reset();
1883 EXPECT_EQ(OK, callback2.WaitForResult());
[email protected]0f873e82010-09-02 16:09:011884 // Use the socket.
[email protected]2431756e2010-09-29 20:26:131885 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL));
1886 handle2.Reset();
[email protected]6b175382009-10-13 06:47:471887
1888 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1889 // actually become pending until 2ms after they have been created. In order
1890 // to flush all tasks, we need to wait so that we know there are no
1891 // soon-to-be-pending tasks waiting.
1892 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161893 MessageLoop::current()->RunAllPending();
1894
1895 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041896
[email protected]9bf28db2009-08-29 01:35:161897 // Invoke the idle socket cleanup check. Only one socket should be left, the
1898 // used socket. Request it to make sure that it's used.
1899
1900 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531901 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]2431756e2010-09-29 20:26:131902 rv = handle.Init("a",
1903 params_,
1904 LOWEST,
1905 &callback,
1906 pool_.get(),
1907 log.bound());
[email protected]9bf28db2009-08-29 01:35:161908 EXPECT_EQ(OK, rv);
[email protected]2431756e2010-09-29 20:26:131909 EXPECT_TRUE(handle.is_reused());
[email protected]b2fcd0e2010-12-01 15:19:401910
1911 net::CapturingNetLog::EntryList entries;
1912 log.GetEntries(&entries);
[email protected]fd4fe0b2010-02-08 23:02:151913 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]b2fcd0e2010-12-01 15:19:401914 entries, 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161915}
1916
[email protected]2041cf342010-02-19 03:15:591917// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161918// because of multiple releasing disconnected sockets.
1919TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1920 CreatePoolWithIdleTimeouts(
1921 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1922 base::TimeDelta(), // Time out unused sockets immediately.
1923 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1924
1925 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1926
1927 // Startup 4 connect jobs. Two of them will be pending.
1928
[email protected]2431756e2010-09-29 20:26:131929 ClientSocketHandle handle;
1930 TestCompletionCallback callback;
1931 int rv = handle.Init("a",
1932 params_,
1933 LOWEST,
1934 &callback,
1935 pool_.get(),
1936 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161937 EXPECT_EQ(OK, rv);
1938
[email protected]2431756e2010-09-29 20:26:131939 ClientSocketHandle handle2;
1940 TestCompletionCallback callback2;
1941 rv = handle2.Init("a",
1942 params_,
1943 LOWEST,
1944 &callback2,
1945 pool_.get(),
1946 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161947 EXPECT_EQ(OK, rv);
1948
[email protected]2431756e2010-09-29 20:26:131949 ClientSocketHandle handle3;
1950 TestCompletionCallback callback3;
1951 rv = handle3.Init("a",
1952 params_,
1953 LOWEST,
1954 &callback3,
1955 pool_.get(),
1956 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161957 EXPECT_EQ(ERR_IO_PENDING, rv);
1958
[email protected]2431756e2010-09-29 20:26:131959 ClientSocketHandle handle4;
1960 TestCompletionCallback callback4;
1961 rv = handle4.Init("a",
1962 params_,
1963 LOWEST,
1964 &callback4,
1965 pool_.get(),
1966 BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161967 EXPECT_EQ(ERR_IO_PENDING, rv);
1968
1969 // Release two disconnected sockets.
1970
[email protected]2431756e2010-09-29 20:26:131971 handle.socket()->Disconnect();
1972 handle.Reset();
1973 handle2.socket()->Disconnect();
1974 handle2.Reset();
[email protected]4f2abec2010-02-03 18:10:161975
[email protected]2431756e2010-09-29 20:26:131976 EXPECT_EQ(OK, callback3.WaitForResult());
1977 EXPECT_FALSE(handle3.is_reused());
1978 EXPECT_EQ(OK, callback4.WaitForResult());
1979 EXPECT_FALSE(handle4.is_reused());
[email protected]4f2abec2010-02-03 18:10:161980}
1981
[email protected]d7027bb2010-05-10 18:58:541982// Regression test for http://crbug.com/42267.
1983// When DoReleaseSocket() is processed for one socket, it is blocked because the
1984// other stalled groups all have releasing sockets, so no progress can be made.
1985TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1986 CreatePoolWithIdleTimeouts(
1987 4 /* socket limit */, 4 /* socket limit per group */,
1988 base::TimeDelta(), // Time out unused sockets immediately.
1989 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1990
1991 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1992
1993 // Max out the socket limit with 2 per group.
1994
[email protected]2431756e2010-09-29 20:26:131995 ClientSocketHandle handle_a[4];
1996 TestCompletionCallback callback_a[4];
1997 ClientSocketHandle handle_b[4];
1998 TestCompletionCallback callback_b[4];
[email protected]d7027bb2010-05-10 18:58:541999
2000 for (int i = 0; i < 2; ++i) {
[email protected]2431756e2010-09-29 20:26:132001 EXPECT_EQ(OK, handle_a[i].Init("a",
2002 params_,
2003 LOWEST,
2004 &callback_a[i],
2005 pool_.get(),
2006 BoundNetLog()));
2007 EXPECT_EQ(OK, handle_b[i].Init("b",
2008 params_,
2009 LOWEST,
2010 &callback_b[i],
2011 pool_.get(),
2012 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542013 }
[email protected]b89f7e42010-05-20 20:37:002014
[email protected]d7027bb2010-05-10 18:58:542015 // Make 4 pending requests, 2 per group.
2016
2017 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132018 EXPECT_EQ(ERR_IO_PENDING,
2019 handle_a[i].Init("a",
2020 params_,
2021 LOWEST,
2022 &callback_a[i],
2023 pool_.get(),
2024 BoundNetLog()));
2025 EXPECT_EQ(ERR_IO_PENDING,
2026 handle_b[i].Init("b",
2027 params_,
2028 LOWEST,
2029 &callback_b[i],
2030 pool_.get(),
2031 BoundNetLog()));
[email protected]d7027bb2010-05-10 18:58:542032 }
2033
2034 // Release b's socket first. The order is important, because in
2035 // DoReleaseSocket(), we'll process b's released socket, and since both b and
2036 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
2037 // first, which has a releasing socket, so it refuses to start up another
2038 // ConnectJob. So, we used to infinite loop on this.
[email protected]2431756e2010-09-29 20:26:132039 handle_b[0].socket()->Disconnect();
2040 handle_b[0].Reset();
2041 handle_a[0].socket()->Disconnect();
2042 handle_a[0].Reset();
[email protected]d7027bb2010-05-10 18:58:542043
2044 // Used to get stuck here.
2045 MessageLoop::current()->RunAllPending();
2046
[email protected]2431756e2010-09-29 20:26:132047 handle_b[1].socket()->Disconnect();
2048 handle_b[1].Reset();
2049 handle_a[1].socket()->Disconnect();
2050 handle_a[1].Reset();
[email protected]d7027bb2010-05-10 18:58:542051
2052 for (int i = 2; i < 4; ++i) {
[email protected]2431756e2010-09-29 20:26:132053 EXPECT_EQ(OK, callback_b[i].WaitForResult());
2054 EXPECT_EQ(OK, callback_a[i].WaitForResult());
[email protected]d7027bb2010-05-10 18:58:542055 }
2056}
2057
[email protected]fd4fe0b2010-02-08 23:02:152058TEST_F(ClientSocketPoolBaseTest,
2059 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
2060 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2061
2062 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2063
2064 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2065 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2066 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2068
[email protected]2431756e2010-09-29 20:26:132069 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2070 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
2071 EXPECT_EQ(2u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152072
2073 // Releases one connection.
[email protected]2431756e2010-09-29 20:26:132074 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2075 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
[email protected]fd4fe0b2010-02-08 23:02:152076
[email protected]2431756e2010-09-29 20:26:132077 EXPECT_TRUE(ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE));
2078 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
2079 EXPECT_EQ(4u, completion_count());
[email protected]fd4fe0b2010-02-08 23:02:152080
2081 EXPECT_EQ(1, GetOrderOfRequest(1));
2082 EXPECT_EQ(2, GetOrderOfRequest(2));
2083 EXPECT_EQ(3, GetOrderOfRequest(3));
2084 EXPECT_EQ(4, GetOrderOfRequest(4));
2085
2086 // Make sure we test order of all requests made.
[email protected]2431756e2010-09-29 20:26:132087 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(5));
[email protected]fd4fe0b2010-02-08 23:02:152088}
2089
[email protected]4f1e4982010-03-02 18:31:042090class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
2091 public:
[email protected]2431756e2010-09-29 20:26:132092 TestReleasingSocketRequest(TestClientSocketPool* pool,
2093 int expected_result,
[email protected]e60e47a2010-07-14 03:37:182094 bool reset_releasing_handle)
2095 : pool_(pool),
2096 expected_result_(expected_result),
2097 reset_releasing_handle_(reset_releasing_handle) {}
[email protected]4f1e4982010-03-02 18:31:042098
2099 ClientSocketHandle* handle() { return &handle_; }
2100
2101 int WaitForResult() {
2102 return callback_.WaitForResult();
2103 }
2104
2105 virtual void RunWithParams(const Tuple1<int>& params) {
2106 callback_.RunWithParams(params);
[email protected]e60e47a2010-07-14 03:37:182107 if (reset_releasing_handle_)
2108 handle_.Reset();
[email protected]ad8e04a2010-11-01 04:16:272109 scoped_refptr<TestSocketParams> con_params(new TestSocketParams());
[email protected]2431756e2010-09-29 20:26:132110 EXPECT_EQ(expected_result_, handle2_.Init("a",
2111 con_params,
2112 kDefaultPriority,
2113 &callback2_,
2114 pool_,
[email protected]e60e47a2010-07-14 03:37:182115 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:042116 }
2117
2118 private:
[email protected]2431756e2010-09-29 20:26:132119 TestClientSocketPool* const pool_;
[email protected]e60e47a2010-07-14 03:37:182120 int expected_result_;
2121 bool reset_releasing_handle_;
[email protected]4f1e4982010-03-02 18:31:042122 ClientSocketHandle handle_;
2123 ClientSocketHandle handle2_;
2124 TestCompletionCallback callback_;
2125 TestCompletionCallback callback2_;
2126};
2127
[email protected]e60e47a2010-07-14 03:37:182128
2129TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) {
2130 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2131
2132 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2133 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2134 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
2135
[email protected]2431756e2010-09-29 20:26:132136 EXPECT_EQ(static_cast<int>(requests_size()),
[email protected]e60e47a2010-07-14 03:37:182137 client_socket_factory_.allocation_count());
2138
2139 connect_job_factory_->set_job_type(
2140 TestConnectJob::kMockPendingAdditionalErrorStateJob);
2141 TestReleasingSocketRequest req(pool_.get(), OK, false);
[email protected]2431756e2010-09-29 20:26:132142 EXPECT_EQ(ERR_IO_PENDING,
2143 req.handle()->Init("a",
2144 params_,
2145 kDefaultPriority,
2146 &req,
2147 pool_.get(),
2148 BoundNetLog()));
[email protected]e60e47a2010-07-14 03:37:182149 // The next job should complete synchronously
2150 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2151
2152 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
2153 EXPECT_FALSE(req.handle()->is_initialized());
2154 EXPECT_FALSE(req.handle()->socket());
2155 EXPECT_TRUE(req.handle()->is_ssl_error());
[email protected]8b498692010-07-16 17:11:432156 EXPECT_FALSE(req.handle()->ssl_error_response_info().headers.get() == NULL);
[email protected]e60e47a2010-07-14 03:37:182157}
2158
[email protected]b6501d3d2010-06-03 23:53:342159// http://crbug.com/44724 regression test.
2160// We start releasing the pool when we flush on network change. When that
2161// happens, the only active references are in the ClientSocketHandles. When a
2162// ConnectJob completes and calls back into the last ClientSocketHandle, that
2163// callback can release the last reference and delete the pool. After the
2164// callback finishes, we go back to the stack frame within the now-deleted pool.
2165// Executing any code that refers to members of the now-deleted pool can cause
2166// crashes.
2167TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
2168 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2169 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2170
2171 ClientSocketHandle handle;
2172 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132173 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2174 params_,
2175 kDefaultPriority,
2176 &callback,
2177 pool_.get(),
2178 BoundNetLog()));
[email protected]b6501d3d2010-06-03 23:53:342179
[email protected]2431756e2010-09-29 20:26:132180 pool_->Flush();
[email protected]b6501d3d2010-06-03 23:53:342181
2182 // We'll call back into this now.
2183 callback.WaitForResult();
2184}
2185
[email protected]a7e38572010-06-07 18:22:242186TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
2187 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2188 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2189
2190 ClientSocketHandle handle;
2191 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132192 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2193 params_,
2194 kDefaultPriority,
2195 &callback,
2196 pool_.get(),
2197 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242198 EXPECT_EQ(OK, callback.WaitForResult());
2199 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2200
2201 pool_->Flush();
2202
2203 handle.Reset();
2204 MessageLoop::current()->RunAllPending();
2205
[email protected]2431756e2010-09-29 20:26:132206 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2207 params_,
2208 kDefaultPriority,
2209 &callback,
2210 pool_.get(),
2211 BoundNetLog()));
[email protected]a7e38572010-06-07 18:22:242212 EXPECT_EQ(OK, callback.WaitForResult());
2213 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
2214}
2215
[email protected]06f92462010-08-31 19:24:142216class ConnectWithinCallback : public CallbackRunner< Tuple1<int> > {
2217 public:
2218 ConnectWithinCallback(
2219 const std::string& group_name,
2220 const scoped_refptr<TestSocketParams>& params,
[email protected]2431756e2010-09-29 20:26:132221 TestClientSocketPool* pool)
[email protected]06f92462010-08-31 19:24:142222 : group_name_(group_name), params_(params), pool_(pool) {}
2223
2224 ~ConnectWithinCallback() {}
2225
2226 virtual void RunWithParams(const Tuple1<int>& params) {
2227 callback_.RunWithParams(params);
2228 EXPECT_EQ(ERR_IO_PENDING,
2229 handle_.Init(group_name_,
2230 params_,
2231 kDefaultPriority,
2232 &nested_callback_,
2233 pool_,
2234 BoundNetLog()));
2235 }
2236
2237 int WaitForResult() {
2238 return callback_.WaitForResult();
2239 }
2240
2241 int WaitForNestedResult() {
2242 return nested_callback_.WaitForResult();
2243 }
2244
2245 private:
2246 const std::string group_name_;
2247 const scoped_refptr<TestSocketParams> params_;
[email protected]2431756e2010-09-29 20:26:132248 TestClientSocketPool* const pool_;
[email protected]06f92462010-08-31 19:24:142249 ClientSocketHandle handle_;
2250 TestCompletionCallback callback_;
2251 TestCompletionCallback nested_callback_;
2252};
2253
2254TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) {
2255 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2256
2257 // First job will be waiting until it gets aborted.
2258 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2259
2260 ClientSocketHandle handle;
[email protected]2431756e2010-09-29 20:26:132261 ConnectWithinCallback callback("a", params_, pool_.get());
2262 EXPECT_EQ(ERR_IO_PENDING, handle.Init("a",
2263 params_,
2264 kDefaultPriority,
2265 &callback,
2266 pool_.get(),
2267 BoundNetLog()));
[email protected]06f92462010-08-31 19:24:142268
2269 // Second job will be started during the first callback, and will
2270 // asynchronously complete with OK.
2271 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2272 pool_->Flush();
2273 EXPECT_EQ(ERR_ABORTED, callback.WaitForResult());
2274 EXPECT_EQ(OK, callback.WaitForNestedResult());
2275}
2276
[email protected]25eea382010-07-10 23:55:262277// Cancel a pending socket request while we're at max sockets,
2278// and verify that the backup socket firing doesn't cause a crash.
2279TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
2280 // Max 4 sockets globally, max 4 sockets per group.
2281 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
[email protected]06d94042010-08-25 01:45:222282 pool_->EnableConnectBackupJobs();
[email protected]25eea382010-07-10 23:55:262283
[email protected]4baaf9d2010-08-31 15:15:442284 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2285 // timer.
[email protected]25eea382010-07-10 23:55:262286 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2287 ClientSocketHandle handle;
2288 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132289 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2290 params_,
2291 kDefaultPriority,
2292 &callback,
2293 pool_.get(),
2294 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262295
2296 // Start (MaxSockets - 1) connected sockets to reach max sockets.
2297 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2298 ClientSocketHandle handles[kDefaultMaxSockets];
2299 for (int i = 1; i < kDefaultMaxSockets; ++i) {
2300 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132301 EXPECT_EQ(OK, handles[i].Init("bar",
2302 params_,
2303 kDefaultPriority,
2304 &callback,
2305 pool_.get(),
2306 BoundNetLog()));
[email protected]25eea382010-07-10 23:55:262307 }
2308
2309 MessageLoop::current()->RunAllPending();
2310
2311 // Cancel the pending request.
2312 handle.Reset();
2313
2314 // Wait for the backup timer to fire (add some slop to ensure it fires)
2315 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2316
2317 MessageLoop::current()->RunAllPending();
2318 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
2319}
2320
[email protected]3f00be82010-09-27 19:50:022321TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) {
[email protected]4baaf9d2010-08-31 15:15:442322 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2323 pool_->EnableConnectBackupJobs();
2324
2325 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2326 // timer.
2327 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2328 ClientSocketHandle handle;
2329 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132330 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2331 params_,
2332 kDefaultPriority,
2333 &callback,
2334 pool_.get(),
2335 BoundNetLog()));
[email protected]4baaf9d2010-08-31 15:15:442336 ASSERT_TRUE(pool_->HasGroup("bar"));
2337 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2338
2339 // Cancel the socket request. This should cancel the backup timer. Wait for
2340 // the backup time to see if it indeed got canceled.
2341 handle.Reset();
2342 // Wait for the backup timer to fire (add some slop to ensure it fires)
2343 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2344 MessageLoop::current()->RunAllPending();
2345 ASSERT_TRUE(pool_->HasGroup("bar"));
2346 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
2347}
2348
[email protected]3f00be82010-09-27 19:50:022349TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) {
2350 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2351 pool_->EnableConnectBackupJobs();
2352
2353 // Create the first socket and set to ERR_IO_PENDING. This starts the backup
2354 // timer.
2355 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2356 ClientSocketHandle handle;
2357 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132358 EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar",
2359 params_,
2360 kDefaultPriority,
2361 &callback,
2362 pool_.get(),
2363 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022364 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2365 ClientSocketHandle handle2;
2366 TestCompletionCallback callback2;
[email protected]2431756e2010-09-29 20:26:132367 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("bar",
2368 params_,
2369 kDefaultPriority,
2370 &callback2,
2371 pool_.get(),
2372 BoundNetLog()));
[email protected]3f00be82010-09-27 19:50:022373 ASSERT_TRUE(pool_->HasGroup("bar"));
2374 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("bar"));
2375
2376 // Cancel request 1 and then complete request 2. With the requests finished,
2377 // the backup timer should be cancelled.
2378 handle.Reset();
2379 EXPECT_EQ(OK, callback2.WaitForResult());
2380 // Wait for the backup timer to fire (add some slop to ensure it fires)
2381 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
2382 MessageLoop::current()->RunAllPending();
2383}
2384
[email protected]eb5a99382010-07-11 03:18:262385// Test delayed socket binding for the case where we have two connects,
2386// and while one is waiting on a connect, the other frees up.
2387// The socket waiting on a connect should switch immediately to the freed
2388// up socket.
2389TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) {
2390 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2391 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2392
2393 ClientSocketHandle handle1;
2394 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132395 EXPECT_EQ(ERR_IO_PENDING,
2396 handle1.Init("a",
2397 params_,
2398 kDefaultPriority,
2399 &callback,
2400 pool_.get(),
2401 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262402 EXPECT_EQ(OK, callback.WaitForResult());
2403
2404 // No idle sockets, no pending jobs.
2405 EXPECT_EQ(0, pool_->IdleSocketCount());
2406 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2407
2408 // Create a second socket to the same host, but this one will wait.
2409 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2410 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132411 EXPECT_EQ(ERR_IO_PENDING,
2412 handle2.Init("a",
2413 params_,
2414 kDefaultPriority,
2415 &callback,
2416 pool_.get(),
2417 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262418 // No idle sockets, and one connecting job.
2419 EXPECT_EQ(0, pool_->IdleSocketCount());
2420 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2421
2422 // Return the first handle to the pool. This will initiate the delayed
2423 // binding.
2424 handle1.Reset();
2425
2426 MessageLoop::current()->RunAllPending();
2427
2428 // Still no idle sockets, still one pending connect job.
2429 EXPECT_EQ(0, pool_->IdleSocketCount());
2430 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2431
2432 // The second socket connected, even though it was a Waiting Job.
2433 EXPECT_EQ(OK, callback.WaitForResult());
2434
2435 // And we can see there is still one job waiting.
2436 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2437
2438 // Finally, signal the waiting Connect.
2439 client_socket_factory_.SignalJobs();
2440 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2441
2442 MessageLoop::current()->RunAllPending();
2443}
2444
2445// Test delayed socket binding when a group is at capacity and one
2446// of the group's sockets frees up.
2447TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) {
2448 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2449 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2450
2451 ClientSocketHandle handle1;
2452 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132453 EXPECT_EQ(ERR_IO_PENDING,
2454 handle1.Init("a",
2455 params_,
2456 kDefaultPriority,
2457 &callback,
2458 pool_.get(),
2459 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262460 EXPECT_EQ(OK, callback.WaitForResult());
2461
2462 // No idle sockets, no pending jobs.
2463 EXPECT_EQ(0, pool_->IdleSocketCount());
2464 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2465
2466 // Create a second socket to the same host, but this one will wait.
2467 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2468 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132469 EXPECT_EQ(ERR_IO_PENDING,
2470 handle2.Init("a",
2471 params_,
2472 kDefaultPriority,
2473 &callback,
2474 pool_.get(),
2475 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262476 // No idle sockets, and one connecting job.
2477 EXPECT_EQ(0, pool_->IdleSocketCount());
2478 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2479
2480 // Return the first handle to the pool. This will initiate the delayed
2481 // binding.
2482 handle1.Reset();
2483
2484 MessageLoop::current()->RunAllPending();
2485
2486 // Still no idle sockets, still one pending connect job.
2487 EXPECT_EQ(0, pool_->IdleSocketCount());
2488 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2489
2490 // The second socket connected, even though it was a Waiting Job.
2491 EXPECT_EQ(OK, callback.WaitForResult());
2492
2493 // And we can see there is still one job waiting.
2494 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2495
2496 // Finally, signal the waiting Connect.
2497 client_socket_factory_.SignalJobs();
2498 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2499
2500 MessageLoop::current()->RunAllPending();
2501}
2502
2503// Test out the case where we have one socket connected, one
2504// connecting, when the first socket finishes and goes idle.
[email protected]2abfe90a2010-08-25 17:49:512505// Although the second connection is pending, the second request
[email protected]eb5a99382010-07-11 03:18:262506// should complete, by taking the first socket's idle socket.
2507TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) {
2508 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2509 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2510
2511 ClientSocketHandle handle1;
2512 TestCompletionCallback callback;
[email protected]2431756e2010-09-29 20:26:132513 EXPECT_EQ(ERR_IO_PENDING,
2514 handle1.Init("a",
2515 params_,
2516 kDefaultPriority,
2517 &callback,
2518 pool_.get(),
2519 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262520 EXPECT_EQ(OK, callback.WaitForResult());
2521
2522 // No idle sockets, no pending jobs.
2523 EXPECT_EQ(0, pool_->IdleSocketCount());
2524 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2525
2526 // Create a second socket to the same host, but this one will wait.
2527 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
2528 ClientSocketHandle handle2;
[email protected]2431756e2010-09-29 20:26:132529 EXPECT_EQ(ERR_IO_PENDING,
2530 handle2.Init("a",
2531 params_,
2532 kDefaultPriority,
2533 &callback,
2534 pool_.get(),
2535 BoundNetLog()));
[email protected]eb5a99382010-07-11 03:18:262536 // No idle sockets, and one connecting job.
2537 EXPECT_EQ(0, pool_->IdleSocketCount());
2538 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2539
2540 // Return the first handle to the pool. This will initiate the delayed
2541 // binding.
2542 handle1.Reset();
2543
2544 MessageLoop::current()->RunAllPending();
2545
2546 // Still no idle sockets, still one pending connect job.
2547 EXPECT_EQ(0, pool_->IdleSocketCount());
2548 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2549
2550 // The second socket connected, even though it was a Waiting Job.
2551 EXPECT_EQ(OK, callback.WaitForResult());
2552
2553 // And we can see there is still one job waiting.
2554 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2555
2556 // Finally, signal the waiting Connect.
2557 client_socket_factory_.SignalJobs();
2558 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2559
2560 MessageLoop::current()->RunAllPending();
2561}
2562
[email protected]2abfe90a2010-08-25 17:49:512563// Cover the case where on an available socket slot, we have one pending
2564// request that completes synchronously, thereby making the Group empty.
2565TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) {
2566 const int kUnlimitedSockets = 100;
2567 const int kOneSocketPerGroup = 1;
2568 CreatePool(kUnlimitedSockets, kOneSocketPerGroup);
2569
2570 // Make the first request asynchronous fail.
2571 // This will free up a socket slot later.
2572 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
2573
2574 ClientSocketHandle handle1;
2575 TestCompletionCallback callback1;
[email protected]2431756e2010-09-29 20:26:132576 EXPECT_EQ(ERR_IO_PENDING,
2577 handle1.Init("a",
2578 params_,
2579 kDefaultPriority,
2580 &callback1,
2581 pool_.get(),
2582 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512583 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2584
2585 // Make the second request synchronously fail. This should make the Group
2586 // empty.
2587 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2588 ClientSocketHandle handle2;
2589 TestCompletionCallback callback2;
2590 // It'll be ERR_IO_PENDING now, but the TestConnectJob will synchronously fail
2591 // when created.
[email protected]2431756e2010-09-29 20:26:132592 EXPECT_EQ(ERR_IO_PENDING,
2593 handle2.Init("a",
2594 params_,
2595 kDefaultPriority,
2596 &callback2,
2597 pool_.get(),
2598 BoundNetLog()));
[email protected]2abfe90a2010-08-25 17:49:512599
2600 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2601
2602 EXPECT_EQ(ERR_CONNECTION_FAILED, callback1.WaitForResult());
2603 EXPECT_EQ(ERR_CONNECTION_FAILED, callback2.WaitForResult());
2604 EXPECT_FALSE(pool_->HasGroup("a"));
2605}
2606
[email protected]e1b54dc2010-10-06 21:27:222607TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) {
2608 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2609
2610 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2611
2612 ClientSocketHandle handle1;
2613 TestCompletionCallback callback1;
2614 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2615 params_,
2616 kDefaultPriority,
2617 &callback1,
2618 pool_.get(),
2619 BoundNetLog()));
2620
2621 ClientSocketHandle handle2;
2622 TestCompletionCallback callback2;
2623 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2624 params_,
2625 kDefaultPriority,
2626 &callback2,
2627 pool_.get(),
2628 BoundNetLog()));
2629 ClientSocketHandle handle3;
2630 TestCompletionCallback callback3;
2631 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2632 params_,
2633 kDefaultPriority,
2634 &callback3,
2635 pool_.get(),
2636 BoundNetLog()));
2637
2638 EXPECT_EQ(OK, callback1.WaitForResult());
2639 EXPECT_EQ(OK, callback2.WaitForResult());
2640 EXPECT_EQ(OK, callback3.WaitForResult());
2641
2642 // Use the socket.
2643 EXPECT_EQ(1, handle1.socket()->Write(NULL, 1, NULL));
2644 EXPECT_EQ(1, handle3.socket()->Write(NULL, 1, NULL));
2645
2646 handle1.Reset();
2647 handle2.Reset();
2648 handle3.Reset();
2649
2650 EXPECT_EQ(OK, handle1.Init("a",
2651 params_,
2652 kDefaultPriority,
2653 &callback1,
2654 pool_.get(),
2655 BoundNetLog()));
2656 EXPECT_EQ(OK, handle2.Init("a",
2657 params_,
2658 kDefaultPriority,
2659 &callback2,
2660 pool_.get(),
2661 BoundNetLog()));
2662 EXPECT_EQ(OK, handle3.Init("a",
2663 params_,
2664 kDefaultPriority,
2665 &callback3,
2666 pool_.get(),
2667 BoundNetLog()));
2668
2669 EXPECT_TRUE(handle1.socket()->WasEverUsed());
2670 EXPECT_TRUE(handle2.socket()->WasEverUsed());
2671 EXPECT_FALSE(handle3.socket()->WasEverUsed());
2672}
2673
[email protected]2c2bef152010-10-13 00:55:032674TEST_F(ClientSocketPoolBaseTest, RequestSockets) {
2675 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2677
2678 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2679
2680 ASSERT_TRUE(pool_->HasGroup("a"));
2681 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2682 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2683
2684 ClientSocketHandle handle1;
2685 TestCompletionCallback callback1;
2686 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2687 params_,
2688 kDefaultPriority,
2689 &callback1,
2690 pool_.get(),
2691 BoundNetLog()));
2692
2693 ClientSocketHandle handle2;
2694 TestCompletionCallback callback2;
2695 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2696 params_,
2697 kDefaultPriority,
2698 &callback2,
2699 pool_.get(),
2700 BoundNetLog()));
2701
2702 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2703 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2704
2705 EXPECT_EQ(OK, callback1.WaitForResult());
2706 EXPECT_EQ(OK, callback2.WaitForResult());
2707 handle1.Reset();
2708 handle2.Reset();
2709
2710 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2711 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2712}
2713
2714TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) {
2715 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2716 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2717
2718 ClientSocketHandle handle1;
2719 TestCompletionCallback callback1;
2720 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2721 params_,
2722 kDefaultPriority,
2723 &callback1,
2724 pool_.get(),
2725 BoundNetLog()));
2726
2727 ASSERT_TRUE(pool_->HasGroup("a"));
2728 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2729 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2730
2731 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2732
2733 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2734 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2735
2736 ClientSocketHandle handle2;
2737 TestCompletionCallback callback2;
2738 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2739 params_,
2740 kDefaultPriority,
2741 &callback2,
2742 pool_.get(),
2743 BoundNetLog()));
2744
2745 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2746 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2747
2748 EXPECT_EQ(OK, callback1.WaitForResult());
2749 EXPECT_EQ(OK, callback2.WaitForResult());
2750 handle1.Reset();
2751 handle2.Reset();
2752
2753 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2754 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2755}
2756
2757TEST_F(ClientSocketPoolBaseTest,
2758 RequestSocketsWhenAlreadyHaveMultipleConnectJob) {
2759 CreatePool(4, 4);
2760 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2761
2762 ClientSocketHandle handle1;
2763 TestCompletionCallback callback1;
2764 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2765 params_,
2766 kDefaultPriority,
2767 &callback1,
2768 pool_.get(),
2769 BoundNetLog()));
2770
2771 ClientSocketHandle handle2;
2772 TestCompletionCallback callback2;
2773 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("a",
2774 params_,
2775 kDefaultPriority,
2776 &callback2,
2777 pool_.get(),
2778 BoundNetLog()));
2779
2780 ClientSocketHandle handle3;
2781 TestCompletionCallback callback3;
2782 EXPECT_EQ(ERR_IO_PENDING, handle3.Init("a",
2783 params_,
2784 kDefaultPriority,
2785 &callback3,
2786 pool_.get(),
2787 BoundNetLog()));
2788
2789 ASSERT_TRUE(pool_->HasGroup("a"));
2790 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2791 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2792
2793 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2794
2795 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2796 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2797
2798 EXPECT_EQ(OK, callback1.WaitForResult());
2799 EXPECT_EQ(OK, callback2.WaitForResult());
2800 EXPECT_EQ(OK, callback3.WaitForResult());
2801 handle1.Reset();
2802 handle2.Reset();
2803 handle3.Reset();
2804
2805 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2806 EXPECT_EQ(3, pool_->IdleSocketCountInGroup("a"));
2807}
2808
2809TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) {
2810 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2811 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2812
2813 ASSERT_FALSE(pool_->HasGroup("a"));
2814
2815 pool_->RequestSockets("a", &params_, kDefaultMaxSockets,
2816 BoundNetLog());
2817
2818 ASSERT_TRUE(pool_->HasGroup("a"));
2819 EXPECT_EQ(kDefaultMaxSockets, pool_->NumConnectJobsInGroup("a"));
2820
2821 ASSERT_FALSE(pool_->HasGroup("b"));
2822
2823 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2824 BoundNetLog());
2825
2826 ASSERT_FALSE(pool_->HasGroup("b"));
2827}
2828
2829TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) {
2830 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
2831 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2832
2833 ASSERT_FALSE(pool_->HasGroup("a"));
2834
2835 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
2836 BoundNetLog());
2837
2838 ASSERT_TRUE(pool_->HasGroup("a"));
2839 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
2840
2841 ASSERT_FALSE(pool_->HasGroup("b"));
2842
2843 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
2844 BoundNetLog());
2845
2846 ASSERT_TRUE(pool_->HasGroup("b"));
2847 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
2848}
2849
2850TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
2851 CreatePool(4, 4);
2852 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2853
2854 ClientSocketHandle handle1;
2855 TestCompletionCallback callback1;
2856 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2857 params_,
2858 kDefaultPriority,
2859 &callback1,
2860 pool_.get(),
2861 BoundNetLog()));
2862 ASSERT_EQ(OK, callback1.WaitForResult());
2863 handle1.Reset();
2864
2865 ASSERT_TRUE(pool_->HasGroup("a"));
2866 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2867 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2868
2869 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2870
2871 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2872 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
2873}
2874
2875TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) {
2876 CreatePool(4, 4);
2877 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2878
2879 ClientSocketHandle handle1;
2880 TestCompletionCallback callback1;
2881 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2882 params_,
2883 kDefaultPriority,
2884 &callback1,
2885 pool_.get(),
2886 BoundNetLog()));
2887 ASSERT_EQ(OK, callback1.WaitForResult());
2888
2889 ASSERT_TRUE(pool_->HasGroup("a"));
2890 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2891 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2892 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2893
2894 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2895
2896 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2897 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2898 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
2899}
2900
2901TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
2902 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2903 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
2904
2905 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2906 BoundNetLog());
2907
2908 ASSERT_TRUE(pool_->HasGroup("a"));
2909 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2910 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("a"));
2911
2912 pool_->RequestSockets("b", &params_, kDefaultMaxSocketsPerGroup,
2913 BoundNetLog());
2914
2915 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
2916 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
2917}
2918
[email protected]3c819f522010-12-02 02:03:122919TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
2920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
2921 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
2922
2923 pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
2924 BoundNetLog());
2925
2926 ASSERT_FALSE(pool_->HasGroup("a"));
2927}
2928
[email protected]2c2bef152010-10-13 00:55:032929TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
2930 CreatePool(4, 4);
2931 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2932
2933 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2934
2935 ASSERT_TRUE(pool_->HasGroup("a"));
2936 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2937 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2938
2939 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2940 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2941 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2942
2943 ClientSocketHandle handle1;
2944 TestCompletionCallback callback1;
2945 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
2946 params_,
2947 kDefaultPriority,
2948 &callback1,
2949 pool_.get(),
2950 BoundNetLog()));
2951 ASSERT_EQ(OK, callback1.WaitForResult());
2952
2953 ClientSocketHandle handle2;
2954 TestCompletionCallback callback2;
2955 int rv = handle2.Init("a",
2956 params_,
2957 kDefaultPriority,
2958 &callback2,
2959 pool_.get(),
2960 BoundNetLog());
2961 if (rv != OK) {
2962 EXPECT_EQ(ERR_IO_PENDING, rv);
2963 EXPECT_EQ(OK, callback2.WaitForResult());
2964 }
2965
2966 handle1.Reset();
2967 handle2.Reset();
2968
2969 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2970
2971 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2972 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
2973 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
2974}
2975
2976TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) {
2977 CreatePool(4, 4);
2978 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
2979
2980 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2981
2982 ASSERT_TRUE(pool_->HasGroup("a"));
2983 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
2984 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2985
2986 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
2987 EXPECT_EQ(2, pool_->NumConnectJobsInGroup("a"));
2988 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2989
2990 pool_->RequestSockets("a", &params_, 3, BoundNetLog());
2991 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2992 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2993
2994 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
2995 EXPECT_EQ(3, pool_->NumConnectJobsInGroup("a"));
2996 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
2997}
2998
2999TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) {
3000 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3001 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3002
3003 pool_->RequestSockets("a", &params_, 1, BoundNetLog());
3004
3005 ASSERT_TRUE(pool_->HasGroup("a"));
3006 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3007 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3008
3009 ClientSocketHandle handle1;
3010 TestCompletionCallback callback1;
3011 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3012 params_,
3013 kDefaultPriority,
3014 &callback1,
3015 pool_.get(),
3016 BoundNetLog()));
3017
3018 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3019 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3020
3021 ASSERT_EQ(OK, callback1.WaitForResult());
3022
3023 handle1.Reset();
3024
3025 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3026}
3027
[email protected]dcbe168a2010-12-02 03:14:463028// http://crbug.com/64940 regression test.
3029TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) {
3030 const int kMaxTotalSockets = 3;
3031 const int kMaxSocketsPerGroup = 2;
3032 CreatePool(kMaxTotalSockets, kMaxSocketsPerGroup);
3033 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3034
3035 // Note that group name ordering matters here. "a" comes before "b", so
3036 // CloseOneIdleSocket() will try to close "a"'s idle socket.
3037
3038 // Set up one idle socket in "a".
3039 ClientSocketHandle handle1;
3040 TestCompletionCallback callback1;
3041 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3042 params_,
3043 kDefaultPriority,
3044 &callback1,
3045 pool_.get(),
3046 BoundNetLog()));
3047
3048 ASSERT_EQ(OK, callback1.WaitForResult());
3049 handle1.Reset();
3050 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3051
3052 // Set up two active sockets in "b".
3053 ClientSocketHandle handle2;
3054 TestCompletionCallback callback2;
3055 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("b",
3056 params_,
3057 kDefaultPriority,
3058 &callback1,
3059 pool_.get(),
3060 BoundNetLog()));
3061 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("b",
3062 params_,
3063 kDefaultPriority,
3064 &callback2,
3065 pool_.get(),
3066 BoundNetLog()));
3067
3068 ASSERT_EQ(OK, callback1.WaitForResult());
3069 ASSERT_EQ(OK, callback2.WaitForResult());
3070 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3071 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3072
3073 // Now we have 1 idle socket in "a" and 2 active sockets in "b". This means
3074 // we've maxed out on sockets, since we set |kMaxTotalSockets| to 3.
3075 // Requesting 2 preconnected sockets for "a" should fail to allocate any more
3076 // sockets for "a", and "b" should still have 2 active sockets.
3077
3078 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3079 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("a"));
3080 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3081 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3082 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3083 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("b"));
3084 EXPECT_EQ(2, pool_->NumActiveSocketsInGroup("b"));
3085
3086 // Now release the 2 active sockets for "b". This will give us 1 idle socket
3087 // in "a" and 2 idle sockets in "b". Requesting 2 preconnected sockets for
3088 // "a" should result in closing 1 for "b".
3089 handle1.Reset();
3090 handle2.Reset();
3091 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("b"));
3092 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3093
3094 pool_->RequestSockets("a", &params_, 2, BoundNetLog());
3095 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3096 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("a"));
3097 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3098 EXPECT_EQ(0, pool_->NumConnectJobsInGroup("b"));
3099 EXPECT_EQ(1, pool_->IdleSocketCountInGroup("b"));
3100 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("b"));
3101}
3102
[email protected]f6d1d6eb2009-06-24 20:16:093103} // namespace
3104
3105} // namespace net