blob: 1dcf89736b7363e6d3103bf6f15707fb20bcf4df [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]c9d6a1d2009-07-14 16:15:2011#include "base/scoped_vector.h"
[email protected]43a21b82010-06-10 21:30:5412#include "base/string_util.h"
[email protected]9e743cd2010-03-16 07:03:5313#include "net/base/net_log.h"
14#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3116#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0917#include "net/base/test_completion_callback.h"
18#include "net/socket/client_socket.h"
19#include "net/socket/client_socket_factory.h"
20#include "net/socket/client_socket_handle.h"
[email protected]b89f7e42010-05-20 20:37:0021#include "net/socket/client_socket_pool_histograms.h"
[email protected]75439d3b2009-07-23 22:11:1722#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0923#include "testing/gtest/include/gtest/gtest.h"
24
25namespace net {
26
27namespace {
28
[email protected]211d21722009-07-22 15:48:5329const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2030const int kDefaultMaxSocketsPerGroup = 2;
[email protected]a554a8262010-05-20 00:13:5231const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0132
[email protected]951269b2010-06-15 19:39:2433struct TestSocketParams {};
[email protected]7fc5b09a2010-02-27 00:07:3834typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4935
[email protected]f6d1d6eb2009-06-24 20:16:0936class MockClientSocket : public ClientSocket {
37 public:
38 MockClientSocket() : connected_(false) {}
39
[email protected]ab838892009-06-30 18:49:0540 // Socket methods:
41 virtual int Read(
42 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
43 return ERR_UNEXPECTED;
44 }
45
46 virtual int Write(
47 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
48 return ERR_UNEXPECTED;
49 }
[email protected]06650c52010-06-03 00:49:1750 virtual bool SetReceiveBufferSize(int32 size) { return true; }
51 virtual bool SetSendBufferSize(int32 size) { return true; }
[email protected]ab838892009-06-30 18:49:0552
[email protected]f6d1d6eb2009-06-24 20:16:0953 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0554
[email protected]a2006ece2010-04-23 16:44:0255 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0956 connected_ = true;
57 return OK;
58 }
[email protected]f6d1d6eb2009-06-24 20:16:0959
[email protected]ab838892009-06-30 18:49:0560 virtual void Disconnect() { connected_ = false; }
61 virtual bool IsConnected() const { return connected_; }
62 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0163
[email protected]ac9eec62010-02-20 18:50:3864 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1665 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0966 }
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]a2006ece2010-04-23 16:44:0268 virtual const BoundNetLog& NetLog() const {
69 return net_log_;
70 }
71
[email protected]f6d1d6eb2009-06-24 20:16:0972 private:
73 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0274 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0975
[email protected]ab838892009-06-30 18:49:0576 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0977};
78
[email protected]5fc08e32009-07-15 17:09:5779class TestConnectJob;
80
[email protected]f6d1d6eb2009-06-24 20:16:0981class MockClientSocketFactory : public ClientSocketFactory {
82 public:
[email protected]ab838892009-06-30 18:49:0583 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0984
[email protected]a2006ece2010-04-23 16:44:0285 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
86 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0987 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0588 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0989 }
90
91 virtual SSLClientSocket* CreateSSLClientSocket(
92 ClientSocket* transport_socket,
93 const std::string& hostname,
94 const SSLConfig& ssl_config) {
95 NOTIMPLEMENTED();
96 return NULL;
97 }
98
[email protected]5fc08e32009-07-15 17:09:5799 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
100 void SignalJobs();
101
[email protected]f6d1d6eb2009-06-24 20:16:09102 int allocation_count() const { return allocation_count_; }
103
[email protected]f6d1d6eb2009-06-24 20:16:09104 private:
105 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57106 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09107};
108
[email protected]ab838892009-06-30 18:49:05109class TestConnectJob : public ConnectJob {
110 public:
111 enum JobType {
112 kMockJob,
113 kMockFailingJob,
114 kMockPendingJob,
115 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57116 kMockWaitingJob,
117 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05118 };
119
120 TestConnectJob(JobType job_type,
121 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49122 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34123 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05124 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30125 MockClientSocketFactory* client_socket_factory,
[email protected]06650c52010-06-03 00:49:17126 NetLog* net_log)
127 : ConnectJob(group_name, timeout_duration, delegate,
128 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
[email protected]2ab05b52009-07-01 23:57:58129 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05130 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21131 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
132 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05133
[email protected]974ebd62009-08-03 23:14:34134 void Signal() {
135 DoConnect(waiting_success_, true /* async */);
136 }
137
[email protected]46451352009-09-01 14:54:21138 virtual LoadState GetLoadState() const { return load_state_; }
139
[email protected]974ebd62009-08-03 23:14:34140 private:
[email protected]ab838892009-06-30 18:49:05141 // ConnectJob methods:
142
[email protected]974ebd62009-08-03 23:14:34143 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05144 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02145 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40146 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05147 switch (job_type_) {
148 case kMockJob:
149 return DoConnect(true /* successful */, false /* sync */);
150 case kMockFailingJob:
151 return DoConnect(false /* error */, false /* sync */);
152 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57153 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47154
155 // Depending on execution timings, posting a delayed task can result
156 // in the task getting executed the at the earliest possible
157 // opportunity or only after returning once from the message loop and
158 // then a second call into the message loop. In order to make behavior
159 // more deterministic, we change the default delay to 2ms. This should
160 // always require us to wait for the second call into the message loop.
161 //
162 // N.B. The correct fix for this and similar timing problems is to
163 // abstract time for the purpose of unittests. Unfortunately, we have
164 // a lot of third-party components that directly call the various
165 // time functions, so this change would be rather invasive.
166 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05167 FROM_HERE,
168 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47169 &TestConnectJob::DoConnect,
170 true /* successful */,
171 true /* async */),
172 2);
[email protected]ab838892009-06-30 18:49:05173 return ERR_IO_PENDING;
174 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57175 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47176 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05177 FROM_HERE,
178 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47179 &TestConnectJob::DoConnect,
180 false /* error */,
181 true /* async */),
182 2);
[email protected]ab838892009-06-30 18:49:05183 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57184 case kMockWaitingJob:
185 client_socket_factory_->WaitForSignal(this);
186 waiting_success_ = true;
187 return ERR_IO_PENDING;
188 case kMockAdvancingLoadStateJob:
[email protected]e6ec67b2010-06-16 00:12:46189 MessageLoop::current()->PostTask(
[email protected]5fc08e32009-07-15 17:09:57190 FROM_HERE,
191 method_factory_.NewRunnableMethod(
[email protected]e6ec67b2010-06-16 00:12:46192 &TestConnectJob::AdvanceLoadState, load_state_));
[email protected]5fc08e32009-07-15 17:09:57193 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05194 default:
195 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40196 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05197 return ERR_FAILED;
198 }
199 }
200
[email protected]46451352009-09-01 14:54:21201 void set_load_state(LoadState load_state) { load_state_ = load_state; }
202
[email protected]ab838892009-06-30 18:49:05203 int DoConnect(bool succeed, bool was_async) {
204 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05205 if (succeed) {
206 result = OK;
[email protected]a2006ece2010-04-23 16:44:02207 socket()->Connect(NULL);
[email protected]6e713f02009-08-06 02:56:40208 } else {
209 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05210 }
[email protected]2ab05b52009-07-01 23:57:58211
212 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30213 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05214 return result;
215 }
216
[email protected]cfa8228c2010-06-17 01:07:56217 // This function helps simulate the progress of load states on a ConnectJob.
218 // Each time it is called it advances the load state and posts a task to be
219 // called again. It stops at the last connecting load state (the one
220 // before LOAD_STATE_SENDING_REQUEST).
[email protected]5fc08e32009-07-15 17:09:57221 void AdvanceLoadState(LoadState state) {
222 int tmp = state;
223 tmp++;
[email protected]cfa8228c2010-06-17 01:07:56224 if (tmp < LOAD_STATE_SENDING_REQUEST) {
225 state = static_cast<LoadState>(tmp);
226 set_load_state(state);
227 MessageLoop::current()->PostTask(
228 FROM_HERE,
229 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
230 state));
231 }
[email protected]5fc08e32009-07-15 17:09:57232 }
233
234 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05235 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57236 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05237 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21238 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05239
240 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
241};
242
[email protected]d80a4322009-08-14 07:07:49243class TestConnectJobFactory
244 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05245 public:
[email protected]5fc08e32009-07-15 17:09:57246 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05247 : job_type_(TestConnectJob::kMockJob),
248 client_socket_factory_(client_socket_factory) {}
249
250 virtual ~TestConnectJobFactory() {}
251
252 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
253
[email protected]974ebd62009-08-03 23:14:34254 void set_timeout_duration(base::TimeDelta timeout_duration) {
255 timeout_duration_ = timeout_duration;
256 }
257
[email protected]ab838892009-06-30 18:49:05258 // ConnectJobFactory methods:
259
260 virtual ConnectJob* NewConnectJob(
261 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49262 const TestClientSocketPoolBase::Request& request,
[email protected]06650c52010-06-03 00:49:17263 ConnectJob::Delegate* delegate) const {
[email protected]ab838892009-06-30 18:49:05264 return new TestConnectJob(job_type_,
265 group_name,
266 request,
[email protected]974ebd62009-08-03 23:14:34267 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05268 delegate,
[email protected]fd7b7c92009-08-20 19:38:30269 client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17270 NULL);
[email protected]ab838892009-06-30 18:49:05271 }
272
[email protected]a796bcec2010-03-22 17:17:26273 virtual base::TimeDelta ConnectionTimeout() const {
274 return timeout_duration_;
275 }
276
[email protected]ab838892009-06-30 18:49:05277 private:
278 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34279 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57280 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05281
282 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
283};
284
285class TestClientSocketPool : public ClientSocketPool {
286 public:
287 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53288 int max_sockets,
[email protected]ab838892009-06-30 18:49:05289 int max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00290 const scoped_refptr<ClientSocketPoolHistograms>& histograms,
[email protected]9bf28db2009-08-29 01:35:16291 base::TimeDelta unused_idle_socket_timeout,
292 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49293 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]b89f7e42010-05-20 20:37:00294 : base_(max_sockets, max_sockets_per_group, histograms,
[email protected]9bf28db2009-08-29 01:35:16295 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]66761b952010-06-25 21:30:38296 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05297
298 virtual int RequestSocket(
299 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49300 const void* params,
[email protected]ac790b42009-12-02 04:31:31301 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05302 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46303 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53304 const BoundNetLog& net_log) {
[email protected]951269b2010-06-15 19:39:24305 const TestSocketParams* casted_socket_params =
306 static_cast<const TestSocketParams*>(params);
[email protected]d80a4322009-08-14 07:07:49307 return base_.RequestSocket(
[email protected]951269b2010-06-15 19:39:24308 group_name, *casted_socket_params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05309 }
310
311 virtual void CancelRequest(
312 const std::string& group_name,
313 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49314 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05315 }
316
317 virtual void ReleaseSocket(
318 const std::string& group_name,
[email protected]a7e38572010-06-07 18:22:24319 ClientSocket* socket,
320 int id) {
321 base_.ReleaseSocket(group_name, socket, id);
322 }
323
324 virtual void Flush() {
325 base_.Flush();
[email protected]ab838892009-06-30 18:49:05326 }
327
328 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49329 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05330 }
331
[email protected]d80a4322009-08-14 07:07:49332 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05333
334 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49335 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05336 }
337
338 virtual LoadState GetLoadState(const std::string& group_name,
339 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49340 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05341 }
342
[email protected]a796bcec2010-03-22 17:17:26343 virtual base::TimeDelta ConnectionTimeout() const {
344 return base_.ConnectionTimeout();
345 }
346
[email protected]b89f7e42010-05-20 20:37:00347 virtual scoped_refptr<ClientSocketPoolHistograms> histograms() const {
348 return base_.histograms();
349 }
[email protected]a796bcec2010-03-22 17:17:26350
[email protected]d80a4322009-08-14 07:07:49351 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20352
[email protected]974ebd62009-08-03 23:14:34353 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49354 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34355 }
356
[email protected]9bf28db2009-08-29 01:35:16357 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
358
[email protected]43a21b82010-06-10 21:30:54359 void EnableBackupJobs() { base_.EnableBackupJobs(); }
360
[email protected]ab838892009-06-30 18:49:05361 private:
[email protected]5389bc72009-11-05 23:34:24362 ~TestClientSocketPool() {}
363
[email protected]d80a4322009-08-14 07:07:49364 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05365
366 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
367};
368
[email protected]a937a06d2009-08-19 21:19:24369} // namespace
370
[email protected]7fc5b09a2010-02-27 00:07:38371REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24372
373namespace {
374
[email protected]5fc08e32009-07-15 17:09:57375void MockClientSocketFactory::SignalJobs() {
376 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
377 it != waiting_jobs_.end(); ++it) {
378 (*it)->Signal();
379 }
380 waiting_jobs_.clear();
381}
382
[email protected]974ebd62009-08-03 23:14:34383class TestConnectJobDelegate : public ConnectJob::Delegate {
384 public:
385 TestConnectJobDelegate()
386 : have_result_(false), waiting_for_result_(false), result_(OK) {}
387 virtual ~TestConnectJobDelegate() {}
388
389 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
390 result_ = result;
[email protected]6e713f02009-08-06 02:56:40391 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07392 // socket.get() should be NULL iff result != OK
393 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34394 delete job;
395 have_result_ = true;
396 if (waiting_for_result_)
397 MessageLoop::current()->Quit();
398 }
399
400 int WaitForResult() {
401 DCHECK(!waiting_for_result_);
402 while (!have_result_) {
403 waiting_for_result_ = true;
404 MessageLoop::current()->Run();
405 waiting_for_result_ = false;
406 }
407 have_result_ = false; // auto-reset for next callback
408 return result_;
409 }
410
411 private:
412 bool have_result_;
413 bool waiting_for_result_;
414 int result_;
415};
416
[email protected]75439d3b2009-07-23 22:11:17417class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09418 protected:
[email protected]b89f7e42010-05-20 20:37:00419 ClientSocketPoolBaseTest()
420 : histograms_(new ClientSocketPoolHistograms("ClientSocketPoolTest")) {}
[email protected]c9d6a1d2009-07-14 16:15:20421
[email protected]211d21722009-07-22 15:48:53422 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16423 CreatePoolWithIdleTimeouts(
424 max_sockets,
425 max_sockets_per_group,
[email protected]241c5c2c2010-06-21 18:46:00426 base::TimeDelta::FromSeconds(
427 ClientSocketPool::unused_idle_socket_timeout()),
[email protected]9bf28db2009-08-29 01:35:16428 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
429 }
430
431 void CreatePoolWithIdleTimeouts(
432 int max_sockets, int max_sockets_per_group,
433 base::TimeDelta unused_idle_socket_timeout,
434 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20435 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04436 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53437 pool_ = new TestClientSocketPool(max_sockets,
438 max_sockets_per_group,
[email protected]b89f7e42010-05-20 20:37:00439 histograms_,
[email protected]9bf28db2009-08-29 01:35:16440 unused_idle_socket_timeout,
441 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20442 connect_job_factory_);
443 }
[email protected]f6d1d6eb2009-06-24 20:16:09444
[email protected]ac790b42009-12-02 04:31:31445 int StartRequest(const std::string& group_name,
446 net::RequestPriority priority) {
[email protected]951269b2010-06-15 19:39:24447 TestSocketParams params;
[email protected]7fc5b09a2010-02-27 00:07:38448 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]951269b2010-06-15 19:39:24449 pool_, group_name, priority, params);
[email protected]f6d1d6eb2009-06-24 20:16:09450 }
451
452 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47453 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
454 // actually become pending until 2ms after they have been created. In order
455 // to flush all tasks, we need to wait so that we know there are no
456 // soon-to-be-pending tasks waiting.
457 PlatformThread::Sleep(10);
458 MessageLoop::current()->RunAllPending();
459
[email protected]211d21722009-07-22 15:48:53460 // Need to delete |pool_| before we turn late binding back off. We also need
461 // to delete |requests_| because the pool is reference counted and requests
462 // keep reference to it.
463 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57464 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53465 requests_.reset();
466
[email protected]75439d3b2009-07-23 22:11:17467 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09468 }
469
[email protected]f6d1d6eb2009-06-24 20:16:09470 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04471 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20472 scoped_refptr<TestClientSocketPool> pool_;
[email protected]b89f7e42010-05-20 20:37:00473 scoped_refptr<ClientSocketPoolHistograms> histograms_;
[email protected]f6d1d6eb2009-06-24 20:16:09474};
475
[email protected]a937a06d2009-08-19 21:19:24476// Helper function which explicitly specifies the template parameters, since
477// the compiler will infer (in this case, incorrectly) that NULL is of type int.
478int InitHandle(ClientSocketHandle* handle,
479 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31480 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24481 CompletionCallback* callback,
[email protected]a796bcec2010-03-22 17:17:26482 const scoped_refptr<TestClientSocketPool>& pool,
[email protected]9e743cd2010-03-16 07:03:53483 const BoundNetLog& net_log) {
[email protected]951269b2010-06-15 19:39:24484 TestSocketParams params;
[email protected]7fc5b09a2010-02-27 00:07:38485 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]951269b2010-06-15 19:39:24486 group_name, params, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24487}
488
[email protected]974ebd62009-08-03 23:14:34489// Even though a timeout is specified, it doesn't time out on a synchronous
490// completion.
491TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
492 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06493 ClientSocketHandle ignored;
[email protected]951269b2010-06-15 19:39:24494 TestSocketParams params;
[email protected]d80a4322009-08-14 07:07:49495 TestClientSocketPoolBase::Request request(
[email protected]951269b2010-06-15 19:39:24496 &ignored, NULL, kDefaultPriority, params, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34497 scoped_ptr<TestConnectJob> job(
498 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12499 "a",
[email protected]974ebd62009-08-03 23:14:34500 request,
501 base::TimeDelta::FromMicroseconds(1),
502 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30503 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17504 NULL));
[email protected]974ebd62009-08-03 23:14:34505 EXPECT_EQ(OK, job->Connect());
506}
507
508TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
509 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06510 ClientSocketHandle ignored;
[email protected]06650c52010-06-03 00:49:17511 CapturingNetLog log(CapturingNetLog::kUnbounded);
[email protected]9e743cd2010-03-16 07:03:53512
[email protected]951269b2010-06-15 19:39:24513 TestSocketParams params;
[email protected]d80a4322009-08-14 07:07:49514 TestClientSocketPoolBase::Request request(
[email protected]951269b2010-06-15 19:39:24515 &ignored, NULL, kDefaultPriority, params, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34516 // Deleted by TestConnectJobDelegate.
517 TestConnectJob* job =
518 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12519 "a",
[email protected]974ebd62009-08-03 23:14:34520 request,
521 base::TimeDelta::FromMicroseconds(1),
522 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30523 &client_socket_factory_,
[email protected]06650c52010-06-03 00:49:17524 &log);
[email protected]974ebd62009-08-03 23:14:34525 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
526 PlatformThread::Sleep(1);
527 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30528
[email protected]06650c52010-06-03 00:49:17529 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46530 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53531 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]06650c52010-06-03 00:49:17532 EXPECT_TRUE(LogContainsBeginEvent(
533 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
[email protected]e9002a92010-01-29 07:10:46534 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17535 log.entries(), 2, NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
536 NetLog::PHASE_NONE));
537 EXPECT_TRUE(LogContainsEvent(
538 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
[email protected]9e743cd2010-03-16 07:03:53539 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46540 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17541 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT));
542 EXPECT_TRUE(LogContainsEndEvent(
543 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34544}
545
[email protected]5fc08e32009-07-15 17:09:57546TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53547 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20548
[email protected]f6d1d6eb2009-06-24 20:16:09549 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06550 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53551 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
552
[email protected]a796bcec2010-03-22 17:17:26553 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
554 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09555 EXPECT_TRUE(handle.is_initialized());
556 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09557 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30558
[email protected]06650c52010-06-03 00:49:17559 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46560 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53561 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]9e743cd2010-03-16 07:03:53562 EXPECT_TRUE(LogContainsEvent(
[email protected]06650c52010-06-03 00:49:17563 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
564 NetLog::PHASE_NONE));
565 EXPECT_TRUE(LogContainsEvent(
566 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
[email protected]9e743cd2010-03-16 07:03:53567 NetLog::PHASE_NONE));
568 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17569 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09570}
571
[email protected]ab838892009-06-30 18:49:05572TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53573 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20574
[email protected]ab838892009-06-30 18:49:05575 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53576 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
577
[email protected]a512f5982009-08-18 16:01:06578 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21579 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a796bcec2010-03-22 17:17:26580 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
581 log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30582
[email protected]06650c52010-06-03 00:49:17583 EXPECT_EQ(3u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27584 EXPECT_TRUE(LogContainsBeginEvent(
585 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:17586 EXPECT_TRUE(LogContainsEvent(
587 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
588 NetLog::PHASE_NONE));
[email protected]a2006ece2010-04-23 16:44:02589 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:17590 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09591}
592
[email protected]211d21722009-07-22 15:48:53593TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
594 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
595
[email protected]9e743cd2010-03-16 07:03:53596 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30597
[email protected]211d21722009-07-22 15:48:53598 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
599 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
600 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
601 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
602
603 EXPECT_EQ(static_cast<int>(requests_.size()),
604 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17605 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53606
607 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
608 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
609 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
610
[email protected]43a21b82010-06-10 21:30:54611 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53612
613 EXPECT_EQ(static_cast<int>(requests_.size()),
614 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17615 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53616
617 EXPECT_EQ(1, GetOrderOfRequest(1));
618 EXPECT_EQ(2, GetOrderOfRequest(2));
619 EXPECT_EQ(3, GetOrderOfRequest(3));
620 EXPECT_EQ(4, GetOrderOfRequest(4));
621 EXPECT_EQ(5, GetOrderOfRequest(5));
622 EXPECT_EQ(6, GetOrderOfRequest(6));
623 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17624
625 // Make sure we test order of all requests made.
626 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53627}
628
629TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
630 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
631
[email protected]9e743cd2010-03-16 07:03:53632 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30633
[email protected]211d21722009-07-22 15:48:53634 // Reach all limits: max total sockets, and max sockets per group.
635 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
636 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
637 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
638 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
639
640 EXPECT_EQ(static_cast<int>(requests_.size()),
641 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17642 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53643
644 // Now create a new group and verify that we don't starve it.
645 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
646
[email protected]43a21b82010-06-10 21:30:54647 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53648
649 EXPECT_EQ(static_cast<int>(requests_.size()),
650 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17651 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53652
653 EXPECT_EQ(1, GetOrderOfRequest(1));
654 EXPECT_EQ(2, GetOrderOfRequest(2));
655 EXPECT_EQ(3, GetOrderOfRequest(3));
656 EXPECT_EQ(4, GetOrderOfRequest(4));
657 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17658
659 // Make sure we test order of all requests made.
660 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53661}
662
663TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
664 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
665
[email protected]ac790b42009-12-02 04:31:31666 EXPECT_EQ(OK, StartRequest("b", LOWEST));
667 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
668 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
669 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53670
671 EXPECT_EQ(static_cast<int>(requests_.size()),
672 client_socket_factory_.allocation_count());
673
[email protected]ac790b42009-12-02 04:31:31674 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
675 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
676 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53677
[email protected]43a21b82010-06-10 21:30:54678 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53679
[email protected]75439d3b2009-07-23 22:11:17680 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53681
682 // First 4 requests don't have to wait, and finish in order.
683 EXPECT_EQ(1, GetOrderOfRequest(1));
684 EXPECT_EQ(2, GetOrderOfRequest(2));
685 EXPECT_EQ(3, GetOrderOfRequest(3));
686 EXPECT_EQ(4, GetOrderOfRequest(4));
687
[email protected]ac790b42009-12-02 04:31:31688 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
689 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53690 EXPECT_EQ(7, GetOrderOfRequest(5));
691 EXPECT_EQ(6, GetOrderOfRequest(6));
692 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17693
694 // Make sure we test order of all requests made.
695 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53696}
697
698TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
699 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
700
[email protected]ac790b42009-12-02 04:31:31701 EXPECT_EQ(OK, StartRequest("a", LOWEST));
702 EXPECT_EQ(OK, StartRequest("a", LOW));
703 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
704 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53705
706 EXPECT_EQ(static_cast<int>(requests_.size()),
707 client_socket_factory_.allocation_count());
708
[email protected]ac790b42009-12-02 04:31:31709 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
710 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
711 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53712
[email protected]43a21b82010-06-10 21:30:54713 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53714
[email protected]43a21b82010-06-10 21:30:54715 EXPECT_EQ(static_cast<int>(requests_.size()),
[email protected]211d21722009-07-22 15:48:53716 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17717 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53718
719 // First 4 requests don't have to wait, and finish in order.
720 EXPECT_EQ(1, GetOrderOfRequest(1));
721 EXPECT_EQ(2, GetOrderOfRequest(2));
722 EXPECT_EQ(3, GetOrderOfRequest(3));
723 EXPECT_EQ(4, GetOrderOfRequest(4));
724
725 // Request ("b", 7) has the highest priority, but we can't make new socket for
726 // group "b", because it has reached the per-group limit. Then we make
727 // socket for ("c", 6), because it has higher priority than ("a", 4),
728 // and we still can't make a socket for group "b".
729 EXPECT_EQ(5, GetOrderOfRequest(5));
730 EXPECT_EQ(6, GetOrderOfRequest(6));
731 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17732
733 // Make sure we test order of all requests made.
734 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53735}
736
737// Make sure that we count connecting sockets against the total limit.
738TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
739 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
740
741 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
742 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
743 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
744
745 // Create one asynchronous request.
746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
747 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
748
[email protected]6b175382009-10-13 06:47:47749 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
750 // actually become pending until 2ms after they have been created. In order
751 // to flush all tasks, we need to wait so that we know there are no
752 // soon-to-be-pending tasks waiting.
753 PlatformThread::Sleep(10);
754 MessageLoop::current()->RunAllPending();
755
[email protected]211d21722009-07-22 15:48:53756 // The next synchronous request should wait for its turn.
757 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
758 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
759
[email protected]43a21b82010-06-10 21:30:54760 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53761
762 EXPECT_EQ(static_cast<int>(requests_.size()),
763 client_socket_factory_.allocation_count());
764
765 EXPECT_EQ(1, GetOrderOfRequest(1));
766 EXPECT_EQ(2, GetOrderOfRequest(2));
767 EXPECT_EQ(3, GetOrderOfRequest(3));
768 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17769 EXPECT_EQ(5, GetOrderOfRequest(5));
770
771 // Make sure we test order of all requests made.
772 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53773}
774
[email protected]8ae03f42010-07-07 19:08:10775// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
776// which tells it to use more expensive, but accurate, group selection
777// algorithm. Make sure it doesn't get stuck in the "on" state.
778TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
779 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
780
781 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
782
783 // Reach group socket limit.
784 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
785 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
786 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
787
788 // Reach total limit, but don't request more sockets.
789 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
790 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
791 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
792
793 // Request one more socket while we are at the maximum sockets limit.
794 // This should flip the may_have_stalled_group flag.
795 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
796 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
797
798 // After releasing first connection for "a", we're still at the
799 // maximum sockets limit, but every group's pending queue is empty,
800 // so we reset the flag.
801 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
802 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
803
804 // Requesting additional socket while at the total limit should
805 // flip the flag back to "on".
806 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
807 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
808
809 // We'll request one more socket to verify that we don't reset the flag
810 // too eagerly.
811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
812 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
813
814 // We're at the maximum socket limit, and still have one request pending
815 // for "d". Flag should be "on".
816 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
817 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
818
819 // Now every group's pending queue should be empty again.
820 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
821 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
822
823 ReleaseAllConnections(NO_KEEP_ALIVE);
824 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
825}
826
[email protected]6427fe22010-04-16 22:27:41827TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
828 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
829 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
830
831 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
832 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
833 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
834 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
835
836 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
837
838 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
839
840 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
841 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
842
843 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
844
845 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
846 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
847 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
848 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
849 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
850 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
851 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
852}
853
[email protected]d7027bb2010-05-10 18:58:54854TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
855 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
856 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
857
858 ClientSocketHandle handle;
859 TestCompletionCallback callback;
860 EXPECT_EQ(ERR_IO_PENDING,
861 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
862 BoundNetLog()));
863
864 ClientSocketHandle handles[4];
865 for (size_t i = 0; i < arraysize(handles); ++i) {
866 TestCompletionCallback callback;
867 EXPECT_EQ(ERR_IO_PENDING,
868 InitHandle(&handles[i], "b", kDefaultPriority, &callback, pool_,
869 BoundNetLog()));
870 }
871
872 // One will be stalled, cancel all the handles now.
873 // This should hit the OnAvailableSocketSlot() code where we previously had
874 // stalled groups, but no longer have any.
875 for (size_t i = 0; i < arraysize(handles); ++i)
876 handles[i].Reset();
877}
878
[email protected]8ae03f42010-07-07 19:08:10879TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimit) {
[email protected]43a21b82010-06-10 21:30:54880 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
881 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
882
[email protected]8ae03f42010-07-07 19:08:10883 for (int i = 0; i < kDefaultMaxSockets; ++i) {
884 ClientSocketHandle handle;
[email protected]43a21b82010-06-10 21:30:54885 TestCompletionCallback callback;
[email protected]8ae03f42010-07-07 19:08:10886 EXPECT_EQ(OK,
887 InitHandle(&handle, IntToString(i), kDefaultPriority, &callback,
[email protected]43a21b82010-06-10 21:30:54888 pool_, BoundNetLog()));
889 }
890
[email protected]8ae03f42010-07-07 19:08:10891 // Stall a group
892 ClientSocketHandle handle;
893 TestCompletionCallback callback;
894 EXPECT_EQ(ERR_IO_PENDING,
895 InitHandle(&handle, "foo", kDefaultPriority, &callback, pool_,
896 BoundNetLog()));
897
898 // Cancel the stalled request.
899 handle.Reset();
900
901 // Flush all the DoReleaseSocket tasks.
902 MessageLoop::current()->RunAllPending();
903
[email protected]43a21b82010-06-10 21:30:54904 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
905 EXPECT_EQ(kDefaultMaxSockets, pool_->IdleSocketCount());
906
[email protected]8ae03f42010-07-07 19:08:10907 for (int i = 0; i < kDefaultMaxSockets; ++i) {
908 ClientSocketHandle handle;
[email protected]43a21b82010-06-10 21:30:54909 TestCompletionCallback callback;
[email protected]8ae03f42010-07-07 19:08:10910 EXPECT_EQ(OK,
911 InitHandle(&handle, StringPrintf("Take 2: %d", i),
912 kDefaultPriority, &callback, pool_, BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:54913 }
914
[email protected]8ae03f42010-07-07 19:08:10915 EXPECT_EQ(2 * kDefaultMaxSockets, client_socket_factory_.allocation_count());
916 EXPECT_EQ(0, pool_->IdleSocketCount());
[email protected]43a21b82010-06-10 21:30:54917
[email protected]8ae03f42010-07-07 19:08:10918 // Before the next round of DoReleaseSocket tasks run, we will hit the
919 // socket limit.
[email protected]43a21b82010-06-10 21:30:54920
[email protected]8ae03f42010-07-07 19:08:10921 EXPECT_EQ(ERR_IO_PENDING,
922 InitHandle(&handle, "foo", kDefaultPriority, &callback, pool_,
923 BoundNetLog()));
[email protected]43a21b82010-06-10 21:30:54924
925 // But if we wait for it, the released idle sockets will be closed in
926 // preference of the waiting request.
[email protected]934152ea2010-06-29 01:02:50927
[email protected]8ae03f42010-07-07 19:08:10928 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]43a21b82010-06-10 21:30:54929}
930
931// Regression test for http://crbug.com/40952.
932TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) {
933 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
934 pool_->EnableBackupJobs();
935 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
936
937 for (int i = 0; i < kDefaultMaxSockets; ++i) {
938 ClientSocketHandle handle;
939 TestCompletionCallback callback;
940 EXPECT_EQ(OK,
941 InitHandle(&handle, IntToString(i), kDefaultPriority, &callback,
942 pool_, BoundNetLog()));
943 }
944
945 // Flush all the DoReleaseSocket tasks.
946 MessageLoop::current()->RunAllPending();
947
948 // Stall a group. Set a pending job so it'll trigger a backup job if we don't
949 // reuse a socket.
950 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
951 ClientSocketHandle handle;
952 TestCompletionCallback callback;
953
954 // "0" is special here, since it should be the first entry in the sorted map,
955 // which is the one which we would close an idle socket for. We shouldn't
956 // close an idle socket though, since we should reuse the idle socket.
957 EXPECT_EQ(
958 OK,
959 InitHandle(
960 &handle, "0", kDefaultPriority, &callback, pool_, BoundNetLog()));
961
962 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
963 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->IdleSocketCount());
964}
965
[email protected]ab838892009-06-30 18:49:05966TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53967 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09968
[email protected]c9d6a1d2009-07-14 16:15:20969 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
970 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31971 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
972 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
973 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
974 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
975 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09976
[email protected]c9d6a1d2009-07-14 16:15:20977 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09978
[email protected]c9d6a1d2009-07-14 16:15:20979 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
980 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17981 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09982
[email protected]c9d6a1d2009-07-14 16:15:20983 EXPECT_EQ(1, GetOrderOfRequest(1));
984 EXPECT_EQ(2, GetOrderOfRequest(2));
985 EXPECT_EQ(6, GetOrderOfRequest(3));
986 EXPECT_EQ(4, GetOrderOfRequest(4));
987 EXPECT_EQ(3, GetOrderOfRequest(5));
988 EXPECT_EQ(5, GetOrderOfRequest(6));
989 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17990
991 // Make sure we test order of all requests made.
992 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09993}
994
[email protected]ab838892009-06-30 18:49:05995TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53996 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09997
[email protected]c9d6a1d2009-07-14 16:15:20998 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
999 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311000 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1001 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1002 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1003 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1004 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091005
[email protected]c9d6a1d2009-07-14 16:15:201006 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091007
[email protected]c9d6a1d2009-07-14 16:15:201008 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1009 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1010
1011 EXPECT_EQ(static_cast<int>(requests_.size()),
1012 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171013 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091014}
1015
1016// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:051017// The pending connect job will be cancelled and should not call back into
1018// ClientSocketPoolBase.
1019TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531020 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201021
[email protected]ab838892009-06-30 18:49:051022 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061023 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:051024 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:271025 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1026 BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:331027 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091028}
1029
[email protected]ab838892009-06-30 18:49:051030TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531031 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201032
[email protected]ab838892009-06-30 18:49:051033 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061034 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:091035 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061036 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091037
[email protected]ab838892009-06-30 18:49:051038 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:271039 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1040 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091041
1042 handle.Reset();
1043
1044 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:261045 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271046 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:091047
1048 EXPECT_EQ(OK, callback2.WaitForResult());
1049 EXPECT_FALSE(callback.have_result());
1050
1051 handle.Reset();
1052}
1053
[email protected]ab838892009-06-30 18:49:051054TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:091056
[email protected]c9d6a1d2009-07-14 16:15:201057 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1058 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:311059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1063 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:091064
1065 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:201066 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331067 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1068 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091069
[email protected]c9d6a1d2009-07-14 16:15:201070 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:091071
[email protected]c9d6a1d2009-07-14 16:15:201072 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1073 client_socket_factory_.allocation_count());
1074 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171075 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091076
[email protected]c9d6a1d2009-07-14 16:15:201077 EXPECT_EQ(1, GetOrderOfRequest(1));
1078 EXPECT_EQ(2, GetOrderOfRequest(2));
1079 EXPECT_EQ(5, GetOrderOfRequest(3));
1080 EXPECT_EQ(3, GetOrderOfRequest(4));
1081 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1082 EXPECT_EQ(4, GetOrderOfRequest(6));
1083 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171084
1085 // Make sure we test order of all requests made.
1086 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:091087}
1088
1089class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
1090 public:
[email protected]2ab05b52009-07-01 23:57:581091 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:241092 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:581093 TestConnectJobFactory* test_connect_job_factory,
1094 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:091095 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:061096 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:581097 within_callback_(false),
1098 test_connect_job_factory_(test_connect_job_factory),
1099 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:091100
1101 virtual void RunWithParams(const Tuple1<int>& params) {
1102 callback_.RunWithParams(params);
1103 ASSERT_EQ(OK, params.a);
1104
1105 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:581106 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:111107
1108 // Don't allow reuse of the socket. Disconnect it and then release it and
1109 // run through the MessageLoop once to get it completely released.
1110 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:091111 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:111112 {
1113 MessageLoop::ScopedNestableTaskAllower nestable(
1114 MessageLoop::current());
1115 MessageLoop::current()->RunAllPending();
1116 }
[email protected]f6d1d6eb2009-06-24 20:16:091117 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:471118 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:261119 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
[email protected]5a1d7ca2010-04-28 20:12:271120 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581121 switch (next_job_type_) {
1122 case TestConnectJob::kMockJob:
1123 EXPECT_EQ(OK, rv);
1124 break;
1125 case TestConnectJob::kMockPendingJob:
1126 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:471127
1128 // For pending jobs, wait for new socket to be created. This makes
1129 // sure there are no more pending operations nor any unclosed sockets
1130 // when the test finishes.
1131 // We need to give it a little bit of time to run, so that all the
1132 // operations that happen on timers (e.g. cleanup of idle
1133 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111134 {
1135 MessageLoop::ScopedNestableTaskAllower nestable(
1136 MessageLoop::current());
1137 PlatformThread::Sleep(10);
1138 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1139 }
[email protected]2ab05b52009-07-01 23:57:581140 break;
1141 default:
1142 FAIL() << "Unexpected job type: " << next_job_type_;
1143 break;
1144 }
[email protected]f6d1d6eb2009-06-24 20:16:091145 }
1146 }
1147
1148 int WaitForResult() {
1149 return callback_.WaitForResult();
1150 }
1151
1152 private:
1153 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241154 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091155 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581156 TestConnectJobFactory* const test_connect_job_factory_;
1157 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091158 TestCompletionCallback callback_;
1159};
1160
[email protected]2ab05b52009-07-01 23:57:581161TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531162 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201163
[email protected]0b7648c2009-07-06 20:14:011164 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061165 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581166 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061167 &handle, pool_.get(), connect_job_factory_,
1168 TestConnectJob::kMockPendingJob);
[email protected]5a1d7ca2010-04-28 20:12:271169 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1170 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091171 ASSERT_EQ(ERR_IO_PENDING, rv);
1172
1173 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581174}
[email protected]f6d1d6eb2009-06-24 20:16:091175
[email protected]2ab05b52009-07-01 23:57:581176TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531177 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201178
[email protected]0b7648c2009-07-06 20:14:011179 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061180 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581181 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061182 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]5a1d7ca2010-04-28 20:12:271183 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1184 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581185 ASSERT_EQ(ERR_IO_PENDING, rv);
1186
1187 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091188}
1189
1190// Make sure that pending requests get serviced after active requests get
1191// cancelled.
[email protected]ab838892009-06-30 18:49:051192TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531193 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201194
[email protected]0b7648c2009-07-06 20:14:011195 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091196
[email protected]c9d6a1d2009-07-14 16:15:201197 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1198 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1199 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1200 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1201 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1202 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1203 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091204
[email protected]c9d6a1d2009-07-14 16:15:201205 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1206 // Let's cancel them.
1207 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331208 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1209 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091210 }
1211
[email protected]f6d1d6eb2009-06-24 20:16:091212 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201213 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1214 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331215 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091216 }
1217
[email protected]75439d3b2009-07-23 22:11:171218 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091219}
1220
1221// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051222TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531223 const size_t kMaxSockets = 5;
1224 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201225
[email protected]0b7648c2009-07-06 20:14:011226 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091227
[email protected]211d21722009-07-22 15:48:531228 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1229 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091230
1231 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531232 for (size_t i = 0; i < kNumberOfRequests; ++i)
1233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091234
[email protected]211d21722009-07-22 15:48:531235 for (size_t i = 0; i < kNumberOfRequests; ++i)
1236 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091237}
1238
[email protected]5fc08e32009-07-15 17:09:571239TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531240 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571241
1242 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1243
[email protected]a512f5982009-08-18 16:01:061244 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271245 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1246 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571247 EXPECT_EQ(ERR_IO_PENDING, rv);
1248
1249 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331250 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571251
[email protected]5a1d7ca2010-04-28 20:12:271252 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1253 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571254 EXPECT_EQ(ERR_IO_PENDING, rv);
1255 EXPECT_EQ(OK, req.WaitForResult());
1256
[email protected]a6c59f62009-07-29 16:33:331257 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171258 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571259 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1260}
1261
[email protected]2b7523d2009-07-29 20:29:231262// Regression test for http://crbug.com/17985.
1263TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1264 const int kMaxSockets = 3;
1265 const int kMaxSocketsPerGroup = 2;
1266 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1267
[email protected]ac790b42009-12-02 04:31:311268 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231269
1270 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1271 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1272
1273 // This is going to be a pending request in an otherwise empty group.
1274 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1275
1276 // Reach the maximum socket limit.
1277 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1278
1279 // Create a stalled group with high priorities.
1280 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1281 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
[email protected]8ae03f42010-07-07 19:08:101282 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
[email protected]2b7523d2009-07-29 20:29:231283
[email protected]8ae03f42010-07-07 19:08:101284 // Release the first two sockets from "a", which will make room
1285 // for requests from "c". After that "a" will have no active sockets
1286 // and one pending request.
[email protected]2b7523d2009-07-29 20:29:231287 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1288 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1289
1290 // Closing idle sockets should not get us into trouble, but in the bug
1291 // we were hitting a CHECK here.
[email protected]93054cc12010-06-08 06:12:411292 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]43a21b82010-06-10 21:30:541293 pool_->CloseIdleSockets();
[email protected]2b7523d2009-07-29 20:29:231294}
1295
[email protected]4d3b05d2010-01-27 21:27:291296TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531297 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571298
1299 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061300 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531301 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261302 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571303 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331304 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571305 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331306 EXPECT_TRUE(req.handle()->is_initialized());
1307 EXPECT_TRUE(req.handle()->socket());
1308 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301309
[email protected]06650c52010-06-03 00:49:171310 EXPECT_EQ(4u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461311 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531312 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171313 EXPECT_TRUE(LogContainsEvent(
1314 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1315 NetLog::PHASE_NONE));
1316 EXPECT_TRUE(LogContainsEvent(
1317 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
1318 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:461319 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171320 log.entries(), 3, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571321}
1322
[email protected]4d3b05d2010-01-27 21:27:291323TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571324 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571326
1327 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061328 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531329 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571330 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261331 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1332 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331333 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571334 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301335
[email protected]06650c52010-06-03 00:49:171336 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461337 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531338 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]06650c52010-06-03 00:49:171339 EXPECT_TRUE(LogContainsEvent(
1340 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
1341 NetLog::PHASE_NONE));
[email protected]6b624c62010-03-14 08:37:321342 EXPECT_TRUE(LogContainsEndEvent(
[email protected]06650c52010-06-03 00:49:171343 log.entries(), 2, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571344}
1345
[email protected]4d3b05d2010-01-27 21:27:291346TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101347 // TODO(eroman): Add back the log expectations! Removed them because the
1348 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531349 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571350
1351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061352 TestSocketRequest req(&request_order_, &completion_count_);
1353 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571354
1355 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261356 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1357 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531358 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571359 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261360 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1361 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571362
[email protected]a6c59f62009-07-29 16:33:331363 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571364
[email protected]fd7b7c92009-08-20 19:38:301365
1366 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301367
[email protected]5fc08e32009-07-15 17:09:571368 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331369 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301370
1371 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531372 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571373}
1374
[email protected]4d3b05d2010-01-27 21:27:291375TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341376 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1377
[email protected]17a0c6c2009-08-04 00:07:041378 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1379
[email protected]ac790b42009-12-02 04:31:311380 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1381 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1382 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1383 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341384
1385 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1386 requests_[2]->handle()->Reset();
1387 requests_[3]->handle()->Reset();
1388 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1389
1390 requests_[1]->handle()->Reset();
1391 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1392
1393 requests_[0]->handle()->Reset();
[email protected]8ae03f42010-07-07 19:08:101394 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
[email protected]974ebd62009-08-03 23:14:341395}
1396
[email protected]5fc08e32009-07-15 17:09:571397// When requests and ConnectJobs are not coupled, the request will get serviced
1398// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291399TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531400 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571401
1402 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321403 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571404
[email protected]a512f5982009-08-18 16:01:061405 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271406 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1407 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571408 EXPECT_EQ(ERR_IO_PENDING, rv);
1409 EXPECT_EQ(OK, req1.WaitForResult());
1410
1411 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1412 // without a job.
1413 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1414
[email protected]a512f5982009-08-18 16:01:061415 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271416 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1417 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571418 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061419 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271420 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1421 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571422 EXPECT_EQ(ERR_IO_PENDING, rv);
1423
1424 // Both Requests 2 and 3 are pending. We release socket 1 which should
1425 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331426 req1.handle()->Reset();
[email protected]8ae03f42010-07-07 19:08:101427 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331428 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571429 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331430 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571431
1432 // Signal job 2, which should service request 3.
1433
1434 client_socket_factory_.SignalJobs();
1435 EXPECT_EQ(OK, req3.WaitForResult());
1436
1437 ASSERT_EQ(3U, request_order_.size());
1438 EXPECT_EQ(&req1, request_order_[0]);
1439 EXPECT_EQ(&req2, request_order_[1]);
1440 EXPECT_EQ(&req3, request_order_[2]);
1441 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1442}
1443
1444// The requests are not coupled to the jobs. So, the requests should finish in
1445// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291446TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531447 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571448 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321449 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571450
[email protected]a512f5982009-08-18 16:01:061451 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271452 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1453 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571454 EXPECT_EQ(ERR_IO_PENDING, rv);
1455
[email protected]a512f5982009-08-18 16:01:061456 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271457 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1458 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571459 EXPECT_EQ(ERR_IO_PENDING, rv);
1460
1461 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321462 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571463
[email protected]a512f5982009-08-18 16:01:061464 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271465 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1466 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571467 EXPECT_EQ(ERR_IO_PENDING, rv);
1468
1469 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1470 EXPECT_EQ(OK, req2.WaitForResult());
1471 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1472
1473 ASSERT_EQ(3U, request_order_.size());
1474 EXPECT_EQ(&req1, request_order_[0]);
1475 EXPECT_EQ(&req2, request_order_[1]);
1476 EXPECT_EQ(&req3, request_order_[2]);
1477}
1478
[email protected]e6ec67b2010-06-16 00:12:461479TEST_F(ClientSocketPoolBaseTest, LoadState) {
[email protected]211d21722009-07-22 15:48:531480 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571481 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321482 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571483
[email protected]a512f5982009-08-18 16:01:061484 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271485 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1486 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571487 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331488 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571489
1490 MessageLoop::current()->RunAllPending();
1491
[email protected]a512f5982009-08-18 16:01:061492 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271493 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1494 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571495 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]cfa8228c2010-06-17 01:07:561496 EXPECT_NE(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
1497 EXPECT_NE(LOAD_STATE_IDLE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571498}
1499
[email protected]4d3b05d2010-01-27 21:27:291500TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161501 CreatePoolWithIdleTimeouts(
1502 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1503 base::TimeDelta(), // Time out unused sockets immediately.
1504 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1505
1506 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1507
1508 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1509
1510 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271511 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161512 EXPECT_EQ(ERR_IO_PENDING, rv);
1513 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1514
1515 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271516 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161517 EXPECT_EQ(ERR_IO_PENDING, rv);
1518 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1519
1520 // Cancel one of the requests. Wait for the other, which will get the first
1521 // job. Release the socket. Run the loop again to make sure the second
1522 // socket is sitting idle and the first one is released (since ReleaseSocket()
1523 // just posts a DoReleaseSocket() task).
1524
1525 req.handle()->Reset();
1526 EXPECT_EQ(OK, req2.WaitForResult());
1527 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471528
1529 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1530 // actually become pending until 2ms after they have been created. In order
1531 // to flush all tasks, we need to wait so that we know there are no
1532 // soon-to-be-pending tasks waiting.
1533 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161534 MessageLoop::current()->RunAllPending();
1535
1536 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041537
[email protected]9bf28db2009-08-29 01:35:161538 // Invoke the idle socket cleanup check. Only one socket should be left, the
1539 // used socket. Request it to make sure that it's used.
1540
1541 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531542 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261543 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161544 EXPECT_EQ(OK, rv);
1545 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151546 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451547 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161548}
1549
[email protected]2041cf342010-02-19 03:15:591550// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161551// because of multiple releasing disconnected sockets.
1552TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1553 CreatePoolWithIdleTimeouts(
1554 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1555 base::TimeDelta(), // Time out unused sockets immediately.
1556 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1557
1558 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1559
1560 // Startup 4 connect jobs. Two of them will be pending.
1561
1562 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271563 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161564 EXPECT_EQ(OK, rv);
1565
1566 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271567 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161568 EXPECT_EQ(OK, rv);
1569
1570 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271571 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161572 EXPECT_EQ(ERR_IO_PENDING, rv);
1573
1574 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271575 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161576 EXPECT_EQ(ERR_IO_PENDING, rv);
1577
1578 // Release two disconnected sockets.
1579
1580 req.handle()->socket()->Disconnect();
1581 req.handle()->Reset();
1582 req2.handle()->socket()->Disconnect();
1583 req2.handle()->Reset();
1584
1585 EXPECT_EQ(OK, req3.WaitForResult());
1586 EXPECT_FALSE(req3.handle()->is_reused());
1587 EXPECT_EQ(OK, req4.WaitForResult());
1588 EXPECT_FALSE(req4.handle()->is_reused());
1589}
1590
[email protected]d7027bb2010-05-10 18:58:541591// Regression test for http://crbug.com/42267.
1592// When DoReleaseSocket() is processed for one socket, it is blocked because the
1593// other stalled groups all have releasing sockets, so no progress can be made.
1594TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
1595 CreatePoolWithIdleTimeouts(
1596 4 /* socket limit */, 4 /* socket limit per group */,
1597 base::TimeDelta(), // Time out unused sockets immediately.
1598 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1599
1600 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1601
1602 // Max out the socket limit with 2 per group.
1603
1604 scoped_ptr<TestSocketRequest> req_a[4];
1605 scoped_ptr<TestSocketRequest> req_b[4];
1606
1607 for (int i = 0; i < 2; ++i) {
1608 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1609 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1610 EXPECT_EQ(OK,
1611 InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
1612 BoundNetLog()));
1613 EXPECT_EQ(OK,
1614 InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
1615 BoundNetLog()));
1616 }
[email protected]b89f7e42010-05-20 20:37:001617
[email protected]d7027bb2010-05-10 18:58:541618 // Make 4 pending requests, 2 per group.
1619
1620 for (int i = 2; i < 4; ++i) {
1621 req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1622 req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
1623 EXPECT_EQ(ERR_IO_PENDING,
1624 InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
1625 BoundNetLog()));
1626 EXPECT_EQ(ERR_IO_PENDING,
1627 InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
1628 BoundNetLog()));
1629 }
1630
1631 // Release b's socket first. The order is important, because in
1632 // DoReleaseSocket(), we'll process b's released socket, and since both b and
1633 // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
1634 // first, which has a releasing socket, so it refuses to start up another
1635 // ConnectJob. So, we used to infinite loop on this.
1636 req_b[0]->handle()->socket()->Disconnect();
1637 req_b[0]->handle()->Reset();
1638 req_a[0]->handle()->socket()->Disconnect();
1639 req_a[0]->handle()->Reset();
1640
1641 // Used to get stuck here.
1642 MessageLoop::current()->RunAllPending();
1643
1644 req_b[1]->handle()->socket()->Disconnect();
1645 req_b[1]->handle()->Reset();
1646 req_a[1]->handle()->socket()->Disconnect();
1647 req_a[1]->handle()->Reset();
1648
1649 for (int i = 2; i < 4; ++i) {
1650 EXPECT_EQ(OK, req_b[i]->WaitForResult());
1651 EXPECT_EQ(OK, req_a[i]->WaitForResult());
1652 }
1653}
1654
[email protected]fd4fe0b2010-02-08 23:02:151655TEST_F(ClientSocketPoolBaseTest,
1656 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1657 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1658
1659 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1660
1661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1662 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1663 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1664 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1665
1666 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1667 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1668 EXPECT_EQ(2u, completion_count_);
1669
1670 // Releases one connection.
1671 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1672 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1673
1674 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1675 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1676 EXPECT_EQ(4u, completion_count_);
1677
1678 EXPECT_EQ(1, GetOrderOfRequest(1));
1679 EXPECT_EQ(2, GetOrderOfRequest(2));
1680 EXPECT_EQ(3, GetOrderOfRequest(3));
1681 EXPECT_EQ(4, GetOrderOfRequest(4));
1682
1683 // Make sure we test order of all requests made.
1684 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1685}
1686
[email protected]4f1e4982010-03-02 18:31:041687class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1688 public:
1689 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1690 : pool_(pool) {}
1691
1692 ClientSocketHandle* handle() { return &handle_; }
1693
1694 int WaitForResult() {
1695 return callback_.WaitForResult();
1696 }
1697
1698 virtual void RunWithParams(const Tuple1<int>& params) {
1699 callback_.RunWithParams(params);
1700 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261701 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271702 &callback2_, pool_, BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041703 }
1704
1705 private:
1706 TestClientSocketPool* const pool_;
1707 ClientSocketHandle handle_;
1708 ClientSocketHandle handle2_;
1709 TestCompletionCallback callback_;
1710 TestCompletionCallback callback2_;
1711};
1712
[email protected]8ae03f42010-07-07 19:08:101713// This test covers the case where, within the same DoReleaseSocket() callback,
1714// we release the just acquired socket and start up a new request. See bug
1715// 36871 for details.
1716TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1718
1719 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1720
1721 // Complete one request and release the socket.
1722 ClientSocketHandle handle;
1723 TestCompletionCallback callback;
1724 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1725 BoundNetLog()));
1726 handle.Reset();
1727
1728 // Before the DoReleaseSocket() task has run, start up a
1729 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1730 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1731 TestReleasingSocketRequest request(pool_.get());
1732 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
1733 &request, pool_, BoundNetLog()));
1734
1735 EXPECT_EQ(OK, request.WaitForResult());
1736}
1737
[email protected]b6501d3d2010-06-03 23:53:341738// http://crbug.com/44724 regression test.
1739// We start releasing the pool when we flush on network change. When that
1740// happens, the only active references are in the ClientSocketHandles. When a
1741// ConnectJob completes and calls back into the last ClientSocketHandle, that
1742// callback can release the last reference and delete the pool. After the
1743// callback finishes, we go back to the stack frame within the now-deleted pool.
1744// Executing any code that refers to members of the now-deleted pool can cause
1745// crashes.
1746TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) {
1747 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1748 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1749
1750 ClientSocketHandle handle;
1751 TestCompletionCallback callback;
1752 EXPECT_EQ(ERR_IO_PENDING,
1753 InitHandle(&handle, "a", kDefaultPriority,
1754 &callback, pool_, BoundNetLog()));
1755
1756 // Simulate flushing the pool.
1757 pool_ = NULL;
1758
1759 // We'll call back into this now.
1760 callback.WaitForResult();
1761}
1762
[email protected]a7e38572010-06-07 18:22:241763TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) {
1764 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1765 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1766
1767 ClientSocketHandle handle;
1768 TestCompletionCallback callback;
1769 EXPECT_EQ(ERR_IO_PENDING,
1770 InitHandle(&handle, "a", kDefaultPriority,
1771 &callback, pool_, BoundNetLog()));
1772 EXPECT_EQ(OK, callback.WaitForResult());
1773 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1774
1775 pool_->Flush();
1776
1777 handle.Reset();
1778 MessageLoop::current()->RunAllPending();
1779
1780 EXPECT_EQ(ERR_IO_PENDING,
1781 InitHandle(&handle, "a", kDefaultPriority,
1782 &callback, pool_, BoundNetLog()));
1783 EXPECT_EQ(OK, callback.WaitForResult());
1784 EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
1785}
1786
[email protected]25eea382010-07-10 23:55:261787// Cancel a pending socket request while we're at max sockets,
1788// and verify that the backup socket firing doesn't cause a crash.
1789TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
1790 // Max 4 sockets globally, max 4 sockets per group.
1791 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
1792 pool_->EnableBackupJobs();
1793
1794 // Create the first socket and set to ERR_IO_PENDING. This creates a
1795 // backup job.
1796 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1797 ClientSocketHandle handle;
1798 TestCompletionCallback callback;
1799 EXPECT_EQ(
1800 ERR_IO_PENDING,
1801 InitHandle(
1802 &handle, "bar", kDefaultPriority, &callback, pool_, BoundNetLog()));
1803
1804 // Start (MaxSockets - 1) connected sockets to reach max sockets.
1805 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1806 ClientSocketHandle handles[kDefaultMaxSockets];
1807 for (int i = 1; i < kDefaultMaxSockets; ++i) {
1808 TestCompletionCallback callback;
1809 EXPECT_EQ(OK,
1810 InitHandle(&handles[i], "bar", kDefaultPriority,
1811 &callback, pool_, BoundNetLog()));
1812 }
1813
1814 MessageLoop::current()->RunAllPending();
1815
1816 // Cancel the pending request.
1817 handle.Reset();
1818
1819 // Wait for the backup timer to fire (add some slop to ensure it fires)
1820 PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
1821
1822 MessageLoop::current()->RunAllPending();
1823 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1824}
1825
[email protected]f6d1d6eb2009-06-24 20:16:091826} // namespace
1827
1828} // namespace net