blob: 3e20eb9b87286815f7ba504b738aa14fb7c6203c [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]9e743cd2010-03-16 07:03:5312#include "net/base/net_log.h"
13#include "net/base/net_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0914#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3115#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0916#include "net/base/test_completion_callback.h"
17#include "net/socket/client_socket.h"
18#include "net/socket/client_socket_factory.h"
19#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1720#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0921#include "testing/gtest/include/gtest/gtest.h"
22
23namespace net {
24
25namespace {
26
[email protected]211d21722009-07-22 15:48:5327const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2028const int kDefaultMaxSocketsPerGroup = 2;
[email protected]ac790b42009-12-02 04:31:3129const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0130
[email protected]7fc5b09a2010-02-27 00:07:3831typedef const void* TestSocketParams;
32typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
[email protected]d80a4322009-08-14 07:07:4933
[email protected]f6d1d6eb2009-06-24 20:16:0934class MockClientSocket : public ClientSocket {
35 public:
36 MockClientSocket() : connected_(false) {}
37
[email protected]ab838892009-06-30 18:49:0538 // Socket methods:
39 virtual int Read(
40 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
41 return ERR_UNEXPECTED;
42 }
43
44 virtual int Write(
45 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
46 return ERR_UNEXPECTED;
47 }
[email protected]d3f66572009-09-09 22:38:0448 virtual bool SetReceiveBufferSize(int32 size) { return true; };
49 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0550
[email protected]f6d1d6eb2009-06-24 20:16:0951 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0552
[email protected]a2006ece2010-04-23 16:44:0253 virtual int Connect(CompletionCallback* callback) {
[email protected]f6d1d6eb2009-06-24 20:16:0954 connected_ = true;
55 return OK;
56 }
[email protected]f6d1d6eb2009-06-24 20:16:0957
[email protected]ab838892009-06-30 18:49:0558 virtual void Disconnect() { connected_ = false; }
59 virtual bool IsConnected() const { return connected_; }
60 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0161
[email protected]ac9eec62010-02-20 18:50:3862 virtual int GetPeerAddress(AddressList* /* address */) const {
[email protected]9f864b32010-01-20 15:01:1663 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0964 }
[email protected]f6d1d6eb2009-06-24 20:16:0965
[email protected]a2006ece2010-04-23 16:44:0266 virtual const BoundNetLog& NetLog() const {
67 return net_log_;
68 }
69
[email protected]f6d1d6eb2009-06-24 20:16:0970 private:
71 bool connected_;
[email protected]a2006ece2010-04-23 16:44:0272 BoundNetLog net_log_;
[email protected]f6d1d6eb2009-06-24 20:16:0973
[email protected]ab838892009-06-30 18:49:0574 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0975};
76
[email protected]5fc08e32009-07-15 17:09:5777class TestConnectJob;
78
[email protected]f6d1d6eb2009-06-24 20:16:0979class MockClientSocketFactory : public ClientSocketFactory {
80 public:
[email protected]ab838892009-06-30 18:49:0581 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0982
[email protected]a2006ece2010-04-23 16:44:0283 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses,
84 NetLog* /* net_log */) {
[email protected]f6d1d6eb2009-06-24 20:16:0985 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0586 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0987 }
88
89 virtual SSLClientSocket* CreateSSLClientSocket(
90 ClientSocket* transport_socket,
91 const std::string& hostname,
92 const SSLConfig& ssl_config) {
93 NOTIMPLEMENTED();
94 return NULL;
95 }
96
[email protected]5fc08e32009-07-15 17:09:5797 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
98 void SignalJobs();
99
[email protected]f6d1d6eb2009-06-24 20:16:09100 int allocation_count() const { return allocation_count_; }
101
[email protected]f6d1d6eb2009-06-24 20:16:09102 private:
103 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:57104 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:09105};
106
[email protected]ab838892009-06-30 18:49:05107class TestConnectJob : public ConnectJob {
108 public:
109 enum JobType {
110 kMockJob,
111 kMockFailingJob,
112 kMockPendingJob,
113 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57114 kMockWaitingJob,
115 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05116 };
117
118 TestConnectJob(JobType job_type,
119 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49120 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34121 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05122 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30123 MockClientSocketFactory* client_socket_factory,
[email protected]9e743cd2010-03-16 07:03:53124 const BoundNetLog& net_log)
125 : ConnectJob(group_name, timeout_duration, delegate, net_log),
[email protected]2ab05b52009-07-01 23:57:58126 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05127 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21128 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
129 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05130
[email protected]974ebd62009-08-03 23:14:34131 void Signal() {
132 DoConnect(waiting_success_, true /* async */);
133 }
134
[email protected]46451352009-09-01 14:54:21135 virtual LoadState GetLoadState() const { return load_state_; }
136
[email protected]974ebd62009-08-03 23:14:34137 private:
[email protected]ab838892009-06-30 18:49:05138 // ConnectJob methods:
139
[email protected]974ebd62009-08-03 23:14:34140 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05141 AddressList ignored;
[email protected]a2006ece2010-04-23 16:44:02142 client_socket_factory_->CreateTCPClientSocket(ignored, NULL);
[email protected]6e713f02009-08-06 02:56:40143 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05144 switch (job_type_) {
145 case kMockJob:
146 return DoConnect(true /* successful */, false /* sync */);
147 case kMockFailingJob:
148 return DoConnect(false /* error */, false /* sync */);
149 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57150 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47151
152 // Depending on execution timings, posting a delayed task can result
153 // in the task getting executed the at the earliest possible
154 // opportunity or only after returning once from the message loop and
155 // then a second call into the message loop. In order to make behavior
156 // more deterministic, we change the default delay to 2ms. This should
157 // always require us to wait for the second call into the message loop.
158 //
159 // N.B. The correct fix for this and similar timing problems is to
160 // abstract time for the purpose of unittests. Unfortunately, we have
161 // a lot of third-party components that directly call the various
162 // time functions, so this change would be rather invasive.
163 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05164 FROM_HERE,
165 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47166 &TestConnectJob::DoConnect,
167 true /* successful */,
168 true /* async */),
169 2);
[email protected]ab838892009-06-30 18:49:05170 return ERR_IO_PENDING;
171 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57172 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47173 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05174 FROM_HERE,
175 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47176 &TestConnectJob::DoConnect,
177 false /* error */,
178 true /* async */),
179 2);
[email protected]ab838892009-06-30 18:49:05180 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57181 case kMockWaitingJob:
182 client_socket_factory_->WaitForSignal(this);
183 waiting_success_ = true;
184 return ERR_IO_PENDING;
185 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47186 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57187 FROM_HERE,
188 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47189 &TestConnectJob::AdvanceLoadState, load_state_),
190 2);
[email protected]5fc08e32009-07-15 17:09:57191 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05192 default:
193 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40194 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05195 return ERR_FAILED;
196 }
197 }
198
[email protected]46451352009-09-01 14:54:21199 void set_load_state(LoadState load_state) { load_state_ = load_state; }
200
[email protected]ab838892009-06-30 18:49:05201 int DoConnect(bool succeed, bool was_async) {
202 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05203 if (succeed) {
204 result = OK;
[email protected]a2006ece2010-04-23 16:44:02205 socket()->Connect(NULL);
[email protected]6e713f02009-08-06 02:56:40206 } else {
207 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05208 }
[email protected]2ab05b52009-07-01 23:57:58209
210 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30211 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05212 return result;
213 }
214
[email protected]5fc08e32009-07-15 17:09:57215 void AdvanceLoadState(LoadState state) {
216 int tmp = state;
217 tmp++;
218 state = static_cast<LoadState>(tmp);
219 set_load_state(state);
220 // Post a delayed task so RunAllPending() won't run it.
221 MessageLoop::current()->PostDelayedTask(
222 FROM_HERE,
223 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
224 state),
225 1 /* 1ms delay */);
226 }
227
228 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05229 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57230 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05231 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21232 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05233
234 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
235};
236
[email protected]d80a4322009-08-14 07:07:49237class TestConnectJobFactory
238 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05239 public:
[email protected]5fc08e32009-07-15 17:09:57240 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05241 : job_type_(TestConnectJob::kMockJob),
242 client_socket_factory_(client_socket_factory) {}
243
244 virtual ~TestConnectJobFactory() {}
245
246 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
247
[email protected]974ebd62009-08-03 23:14:34248 void set_timeout_duration(base::TimeDelta timeout_duration) {
249 timeout_duration_ = timeout_duration;
250 }
251
[email protected]ab838892009-06-30 18:49:05252 // ConnectJobFactory methods:
253
254 virtual ConnectJob* NewConnectJob(
255 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49256 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30257 ConnectJob::Delegate* delegate,
[email protected]9e743cd2010-03-16 07:03:53258 const BoundNetLog& net_log) const {
[email protected]ab838892009-06-30 18:49:05259 return new TestConnectJob(job_type_,
260 group_name,
261 request,
[email protected]974ebd62009-08-03 23:14:34262 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05263 delegate,
[email protected]fd7b7c92009-08-20 19:38:30264 client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53265 net_log);
[email protected]ab838892009-06-30 18:49:05266 }
267
[email protected]a796bcec2010-03-22 17:17:26268 virtual base::TimeDelta ConnectionTimeout() const {
269 return timeout_duration_;
270 }
271
[email protected]ab838892009-06-30 18:49:05272 private:
273 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34274 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57275 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05276
277 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
278};
279
280class TestClientSocketPool : public ClientSocketPool {
281 public:
282 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53283 int max_sockets,
[email protected]ab838892009-06-30 18:49:05284 int max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26285 const std::string& name,
[email protected]9bf28db2009-08-29 01:35:16286 base::TimeDelta unused_idle_socket_timeout,
287 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49288 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]a796bcec2010-03-22 17:17:26289 : base_(max_sockets, max_sockets_per_group, name,
[email protected]9bf28db2009-08-29 01:35:16290 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]61a86c42010-04-19 22:45:53291 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05292
293 virtual int RequestSocket(
294 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49295 const void* params,
[email protected]ac790b42009-12-02 04:31:31296 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05297 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46298 CompletionCallback* callback,
[email protected]9e743cd2010-03-16 07:03:53299 const BoundNetLog& net_log) {
[email protected]d80a4322009-08-14 07:07:49300 return base_.RequestSocket(
[email protected]9e743cd2010-03-16 07:03:53301 group_name, params, priority, handle, callback, net_log);
[email protected]ab838892009-06-30 18:49:05302 }
303
304 virtual void CancelRequest(
305 const std::string& group_name,
306 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49307 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05308 }
309
310 virtual void ReleaseSocket(
311 const std::string& group_name,
312 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49313 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05314 }
315
316 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49317 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05318 }
319
[email protected]d80a4322009-08-14 07:07:49320 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05321
322 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49323 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05324 }
325
326 virtual LoadState GetLoadState(const std::string& group_name,
327 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49328 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05329 }
330
[email protected]a796bcec2010-03-22 17:17:26331 virtual base::TimeDelta ConnectionTimeout() const {
332 return base_.ConnectionTimeout();
333 }
334
335 virtual const std::string& name() const { return base_.name(); }
336
[email protected]d80a4322009-08-14 07:07:49337 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20338
[email protected]974ebd62009-08-03 23:14:34339 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49340 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34341 }
342
[email protected]9bf28db2009-08-29 01:35:16343 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
344
[email protected]ab838892009-06-30 18:49:05345 private:
[email protected]5389bc72009-11-05 23:34:24346 ~TestClientSocketPool() {}
347
[email protected]d80a4322009-08-14 07:07:49348 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05349
350 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
351};
352
[email protected]a937a06d2009-08-19 21:19:24353} // namespace
354
[email protected]7fc5b09a2010-02-27 00:07:38355REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
[email protected]a937a06d2009-08-19 21:19:24356
357namespace {
358
[email protected]5fc08e32009-07-15 17:09:57359void MockClientSocketFactory::SignalJobs() {
360 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
361 it != waiting_jobs_.end(); ++it) {
362 (*it)->Signal();
363 }
364 waiting_jobs_.clear();
365}
366
[email protected]974ebd62009-08-03 23:14:34367class TestConnectJobDelegate : public ConnectJob::Delegate {
368 public:
369 TestConnectJobDelegate()
370 : have_result_(false), waiting_for_result_(false), result_(OK) {}
371 virtual ~TestConnectJobDelegate() {}
372
373 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
374 result_ = result;
[email protected]6e713f02009-08-06 02:56:40375 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07376 // socket.get() should be NULL iff result != OK
377 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34378 delete job;
379 have_result_ = true;
380 if (waiting_for_result_)
381 MessageLoop::current()->Quit();
382 }
383
384 int WaitForResult() {
385 DCHECK(!waiting_for_result_);
386 while (!have_result_) {
387 waiting_for_result_ = true;
388 MessageLoop::current()->Run();
389 waiting_for_result_ = false;
390 }
391 have_result_ = false; // auto-reset for next callback
392 return result_;
393 }
394
395 private:
396 bool have_result_;
397 bool waiting_for_result_;
398 int result_;
399};
400
[email protected]75439d3b2009-07-23 22:11:17401class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09402 protected:
[email protected]17a0c6c2009-08-04 00:07:04403 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20404
[email protected]211d21722009-07-22 15:48:53405 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16406 CreatePoolWithIdleTimeouts(
407 max_sockets,
408 max_sockets_per_group,
409 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
410 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
411 }
412
413 void CreatePoolWithIdleTimeouts(
414 int max_sockets, int max_sockets_per_group,
415 base::TimeDelta unused_idle_socket_timeout,
416 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20417 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04418 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53419 pool_ = new TestClientSocketPool(max_sockets,
420 max_sockets_per_group,
[email protected]a796bcec2010-03-22 17:17:26421 "IdleTimeoutTestPool",
[email protected]9bf28db2009-08-29 01:35:16422 unused_idle_socket_timeout,
423 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20424 connect_job_factory_);
425 }
[email protected]f6d1d6eb2009-06-24 20:16:09426
[email protected]ac790b42009-12-02 04:31:31427 int StartRequest(const std::string& group_name,
428 net::RequestPriority priority) {
[email protected]7fc5b09a2010-02-27 00:07:38429 return StartRequestUsingPool<TestClientSocketPool, TestSocketParams>(
[email protected]a796bcec2010-03-22 17:17:26430 pool_, group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09431 }
432
433 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47434 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
435 // actually become pending until 2ms after they have been created. In order
436 // to flush all tasks, we need to wait so that we know there are no
437 // soon-to-be-pending tasks waiting.
438 PlatformThread::Sleep(10);
439 MessageLoop::current()->RunAllPending();
440
[email protected]211d21722009-07-22 15:48:53441 // Need to delete |pool_| before we turn late binding back off. We also need
442 // to delete |requests_| because the pool is reference counted and requests
443 // keep reference to it.
444 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57445 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53446 requests_.reset();
447
[email protected]75439d3b2009-07-23 22:11:17448 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09449 }
450
[email protected]f6d1d6eb2009-06-24 20:16:09451 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04452 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20453 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09454};
455
[email protected]a937a06d2009-08-19 21:19:24456// Helper function which explicitly specifies the template parameters, since
457// the compiler will infer (in this case, incorrectly) that NULL is of type int.
458int InitHandle(ClientSocketHandle* handle,
459 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31460 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24461 CompletionCallback* callback,
[email protected]a796bcec2010-03-22 17:17:26462 const scoped_refptr<TestClientSocketPool>& pool,
[email protected]9e743cd2010-03-16 07:03:53463 const BoundNetLog& net_log) {
[email protected]7fc5b09a2010-02-27 00:07:38464 return handle->Init<TestSocketParams, TestClientSocketPool>(
[email protected]9e743cd2010-03-16 07:03:53465 group_name, NULL, priority, callback, pool, net_log);
[email protected]a937a06d2009-08-19 21:19:24466}
467
[email protected]974ebd62009-08-03 23:14:34468// Even though a timeout is specified, it doesn't time out on a synchronous
469// completion.
470TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
471 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06472 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49473 TestClientSocketPoolBase::Request request(
[email protected]5a1d7ca2010-04-28 20:12:27474 &ignored, NULL, kDefaultPriority, NULL, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34475 scoped_ptr<TestConnectJob> job(
476 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12477 "a",
[email protected]974ebd62009-08-03 23:14:34478 request,
479 base::TimeDelta::FromMicroseconds(1),
480 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30481 &client_socket_factory_,
[email protected]5a1d7ca2010-04-28 20:12:27482 BoundNetLog()));
[email protected]974ebd62009-08-03 23:14:34483 EXPECT_EQ(OK, job->Connect());
484}
485
486TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
487 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06488 ClientSocketHandle ignored;
[email protected]9e743cd2010-03-16 07:03:53489 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
490
[email protected]d80a4322009-08-14 07:07:49491 TestClientSocketPoolBase::Request request(
[email protected]5a1d7ca2010-04-28 20:12:27492 &ignored, NULL, kDefaultPriority, NULL, BoundNetLog());
[email protected]974ebd62009-08-03 23:14:34493 // Deleted by TestConnectJobDelegate.
494 TestConnectJob* job =
495 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12496 "a",
[email protected]974ebd62009-08-03 23:14:34497 request,
498 base::TimeDelta::FromMicroseconds(1),
499 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30500 &client_socket_factory_,
[email protected]9e743cd2010-03-16 07:03:53501 log.bound());
[email protected]974ebd62009-08-03 23:14:34502 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
503 PlatformThread::Sleep(1);
504 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30505
[email protected]9e743cd2010-03-16 07:03:53506 EXPECT_EQ(3u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:46507 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53508 log.entries(), 0, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:46509 EXPECT_TRUE(LogContainsEvent(
[email protected]9e743cd2010-03-16 07:03:53510 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
511 NetLog::PHASE_NONE));
[email protected]e9002a92010-01-29 07:10:46512 EXPECT_TRUE(LogContainsEndEvent(
[email protected]9e743cd2010-03-16 07:03:53513 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34514}
515
[email protected]5fc08e32009-07-15 17:09:57516TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53517 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20518
[email protected]f6d1d6eb2009-06-24 20:16:09519 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06520 ClientSocketHandle handle;
[email protected]9e743cd2010-03-16 07:03:53521 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
522
[email protected]a796bcec2010-03-22 17:17:26523 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
524 log.bound()));
[email protected]f6d1d6eb2009-06-24 20:16:09525 EXPECT_TRUE(handle.is_initialized());
526 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09527 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30528
[email protected]a2006ece2010-04-23 16:44:02529 EXPECT_EQ(7u, 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));
532 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]a2006ece2010-04-23 16:44:02533 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID));
534 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53535 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]a2006ece2010-04-23 16:44:02536 EXPECT_TRUE(LogContainsEndEvent(
537 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
538 EXPECT_TRUE(LogContainsEndEvent(
539 log.entries(), 4, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID));
[email protected]9e743cd2010-03-16 07:03:53540 EXPECT_TRUE(LogContainsEvent(
[email protected]a2006ece2010-04-23 16:44:02541 log.entries(), 5, NetLog::TYPE_SOCKET_POOL_SOCKET_ID,
[email protected]9e743cd2010-03-16 07:03:53542 NetLog::PHASE_NONE));
543 EXPECT_TRUE(LogContainsEndEvent(
[email protected]a2006ece2010-04-23 16:44:02544 log.entries(), 6, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09545}
546
[email protected]ab838892009-06-30 18:49:05547TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53548 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20549
[email protected]ab838892009-06-30 18:49:05550 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]9e743cd2010-03-16 07:03:53551 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
552
[email protected]a512f5982009-08-18 16:01:06553 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21554 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a796bcec2010-03-22 17:17:26555 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
556 log.bound()));
[email protected]fd7b7c92009-08-20 19:38:30557
[email protected]a2006ece2010-04-23 16:44:02558 EXPECT_EQ(6u, log.entries().size());
[email protected]5a1d7ca2010-04-28 20:12:27559 EXPECT_TRUE(LogContainsBeginEvent(
560 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]e9002a92010-01-29 07:10:46561 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53562 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]a2006ece2010-04-23 16:44:02563 EXPECT_TRUE(LogContainsEndEvent(
564 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
565 EXPECT_TRUE(LogContainsEndEvent(log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09566}
567
[email protected]211d21722009-07-22 15:48:53568TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
569 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
570
[email protected]9e743cd2010-03-16 07:03:53571 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30572
[email protected]211d21722009-07-22 15:48:53573 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
574 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
575 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
576 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
577
578 EXPECT_EQ(static_cast<int>(requests_.size()),
579 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17580 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53581
582 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
583 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
584 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
585
[email protected]42df4e8e2010-04-13 22:02:56586 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53587
588 EXPECT_EQ(static_cast<int>(requests_.size()),
589 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17590 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53591
592 EXPECT_EQ(1, GetOrderOfRequest(1));
593 EXPECT_EQ(2, GetOrderOfRequest(2));
594 EXPECT_EQ(3, GetOrderOfRequest(3));
595 EXPECT_EQ(4, GetOrderOfRequest(4));
596 EXPECT_EQ(5, GetOrderOfRequest(5));
597 EXPECT_EQ(6, GetOrderOfRequest(6));
598 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17599
600 // Make sure we test order of all requests made.
601 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53602}
603
604TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
605 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
606
[email protected]9e743cd2010-03-16 07:03:53607 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30608
[email protected]211d21722009-07-22 15:48:53609 // Reach all limits: max total sockets, and max sockets per group.
610 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
611 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
612 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
613 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
614
615 EXPECT_EQ(static_cast<int>(requests_.size()),
616 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17617 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53618
619 // Now create a new group and verify that we don't starve it.
620 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
621
[email protected]42df4e8e2010-04-13 22:02:56622 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53623
624 EXPECT_EQ(static_cast<int>(requests_.size()),
625 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17626 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53627
628 EXPECT_EQ(1, GetOrderOfRequest(1));
629 EXPECT_EQ(2, GetOrderOfRequest(2));
630 EXPECT_EQ(3, GetOrderOfRequest(3));
631 EXPECT_EQ(4, GetOrderOfRequest(4));
632 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17633
634 // Make sure we test order of all requests made.
635 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53636}
637
638TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
639 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
640
[email protected]ac790b42009-12-02 04:31:31641 EXPECT_EQ(OK, StartRequest("b", LOWEST));
642 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
643 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
644 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53645
646 EXPECT_EQ(static_cast<int>(requests_.size()),
647 client_socket_factory_.allocation_count());
648
[email protected]ac790b42009-12-02 04:31:31649 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
650 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
651 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53652
[email protected]42df4e8e2010-04-13 22:02:56653 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53654
[email protected]42df4e8e2010-04-13 22:02:56655 // We're re-using one socket for group "a", and one for "b".
656 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
657 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17658 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53659
660 // First 4 requests don't have to wait, and finish in order.
661 EXPECT_EQ(1, GetOrderOfRequest(1));
662 EXPECT_EQ(2, GetOrderOfRequest(2));
663 EXPECT_EQ(3, GetOrderOfRequest(3));
664 EXPECT_EQ(4, GetOrderOfRequest(4));
665
[email protected]ac790b42009-12-02 04:31:31666 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
667 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53668 EXPECT_EQ(7, GetOrderOfRequest(5));
669 EXPECT_EQ(6, GetOrderOfRequest(6));
670 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17671
672 // Make sure we test order of all requests made.
673 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53674}
675
676TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
677 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
678
[email protected]ac790b42009-12-02 04:31:31679 EXPECT_EQ(OK, StartRequest("a", LOWEST));
680 EXPECT_EQ(OK, StartRequest("a", LOW));
681 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
682 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53683
684 EXPECT_EQ(static_cast<int>(requests_.size()),
685 client_socket_factory_.allocation_count());
686
[email protected]ac790b42009-12-02 04:31:31687 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
688 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
689 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53690
[email protected]42df4e8e2010-04-13 22:02:56691 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53692
[email protected]42df4e8e2010-04-13 22:02:56693 // We're re-using one socket for group "a", and one for "b".
694 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
[email protected]211d21722009-07-22 15:48:53695 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17696 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53697
698 // First 4 requests don't have to wait, and finish in order.
699 EXPECT_EQ(1, GetOrderOfRequest(1));
700 EXPECT_EQ(2, GetOrderOfRequest(2));
701 EXPECT_EQ(3, GetOrderOfRequest(3));
702 EXPECT_EQ(4, GetOrderOfRequest(4));
703
704 // Request ("b", 7) has the highest priority, but we can't make new socket for
705 // group "b", because it has reached the per-group limit. Then we make
706 // socket for ("c", 6), because it has higher priority than ("a", 4),
707 // and we still can't make a socket for group "b".
708 EXPECT_EQ(5, GetOrderOfRequest(5));
709 EXPECT_EQ(6, GetOrderOfRequest(6));
710 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17711
712 // Make sure we test order of all requests made.
713 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53714}
715
716// Make sure that we count connecting sockets against the total limit.
717TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
718 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
719
720 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
721 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
722 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
723
724 // Create one asynchronous request.
725 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
726 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
727
[email protected]6b175382009-10-13 06:47:47728 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
729 // actually become pending until 2ms after they have been created. In order
730 // to flush all tasks, we need to wait so that we know there are no
731 // soon-to-be-pending tasks waiting.
732 PlatformThread::Sleep(10);
733 MessageLoop::current()->RunAllPending();
734
[email protected]211d21722009-07-22 15:48:53735 // The next synchronous request should wait for its turn.
736 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
737 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
738
[email protected]42df4e8e2010-04-13 22:02:56739 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53740
741 EXPECT_EQ(static_cast<int>(requests_.size()),
742 client_socket_factory_.allocation_count());
743
744 EXPECT_EQ(1, GetOrderOfRequest(1));
745 EXPECT_EQ(2, GetOrderOfRequest(2));
746 EXPECT_EQ(3, GetOrderOfRequest(3));
747 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17748 EXPECT_EQ(5, GetOrderOfRequest(5));
749
750 // Make sure we test order of all requests made.
751 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53752}
753
754// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
755// which tells it to use more expensive, but accurate, group selection
756// algorithm. Make sure it doesn't get stuck in the "on" state.
757TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
758 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
759
760 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
761
762 // Reach group socket limit.
763 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
764 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
765 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
766
767 // Reach total limit, but don't request more sockets.
768 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
769 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
770 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
771
772 // Request one more socket while we are at the maximum sockets limit.
773 // This should flip the may_have_stalled_group flag.
774 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
775 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
776
777 // After releasing first connection for "a", we're still at the
778 // maximum sockets limit, but every group's pending queue is empty,
779 // so we reset the flag.
[email protected]42df4e8e2010-04-13 22:02:56780 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53781 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
782
783 // Requesting additional socket while at the total limit should
784 // flip the flag back to "on".
785 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
786 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
787
788 // We'll request one more socket to verify that we don't reset the flag
789 // too eagerly.
790 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
791 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
792
793 // We're at the maximum socket limit, and still have one request pending
794 // for "d". Flag should be "on".
[email protected]42df4e8e2010-04-13 22:02:56795 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53796 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
797
798 // Now every group's pending queue should be empty again.
[email protected]42df4e8e2010-04-13 22:02:56799 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53800 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
801
[email protected]42df4e8e2010-04-13 22:02:56802 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53803 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
804}
805
[email protected]6427fe22010-04-16 22:27:41806TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
807 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
808 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
809
810 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
811 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
812 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
813 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
814
815 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
816
817 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
818
819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
820 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
821
822 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
823
824 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
825 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
826 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
827 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
828 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
829 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
830 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
831}
832
[email protected]ab838892009-06-30 18:49:05833TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53834 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09835
[email protected]c9d6a1d2009-07-14 16:15:20836 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
837 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31838 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
839 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
840 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
841 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
842 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09843
[email protected]c9d6a1d2009-07-14 16:15:20844 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09845
[email protected]c9d6a1d2009-07-14 16:15:20846 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
847 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17848 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09849
[email protected]c9d6a1d2009-07-14 16:15:20850 EXPECT_EQ(1, GetOrderOfRequest(1));
851 EXPECT_EQ(2, GetOrderOfRequest(2));
852 EXPECT_EQ(6, GetOrderOfRequest(3));
853 EXPECT_EQ(4, GetOrderOfRequest(4));
854 EXPECT_EQ(3, GetOrderOfRequest(5));
855 EXPECT_EQ(5, GetOrderOfRequest(6));
856 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17857
858 // Make sure we test order of all requests made.
859 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09860}
861
[email protected]ab838892009-06-30 18:49:05862TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53863 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09864
[email protected]c9d6a1d2009-07-14 16:15:20865 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
866 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31867 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
871 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09872
[email protected]c9d6a1d2009-07-14 16:15:20873 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09874
[email protected]c9d6a1d2009-07-14 16:15:20875 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
876 EXPECT_EQ(OK, requests_[i]->WaitForResult());
877
878 EXPECT_EQ(static_cast<int>(requests_.size()),
879 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17880 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09881}
882
883// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05884// The pending connect job will be cancelled and should not call back into
885// ClientSocketPoolBase.
886TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53887 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20888
[email protected]ab838892009-06-30 18:49:05889 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06890 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05891 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:27892 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
893 BoundNetLog()));
[email protected]a6c59f62009-07-29 16:33:33894 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09895}
896
[email protected]ab838892009-06-30 18:49:05897TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53898 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20899
[email protected]ab838892009-06-30 18:49:05900 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06901 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09902 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06903 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09904
[email protected]ab838892009-06-30 18:49:05905 EXPECT_EQ(ERR_IO_PENDING,
[email protected]5a1d7ca2010-04-28 20:12:27906 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
907 BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:09908
909 handle.Reset();
910
911 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:26912 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:27913 &callback2, pool_, BoundNetLog()));
[email protected]f6d1d6eb2009-06-24 20:16:09914
915 EXPECT_EQ(OK, callback2.WaitForResult());
916 EXPECT_FALSE(callback.have_result());
917
918 handle.Reset();
919}
920
[email protected]ab838892009-06-30 18:49:05921TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53922 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09923
[email protected]c9d6a1d2009-07-14 16:15:20924 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
925 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31926 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
927 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
928 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
929 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
930 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09931
932 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20933 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33934 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
935 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09936
[email protected]c9d6a1d2009-07-14 16:15:20937 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09938
[email protected]c9d6a1d2009-07-14 16:15:20939 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
940 client_socket_factory_.allocation_count());
941 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17942 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09943
[email protected]c9d6a1d2009-07-14 16:15:20944 EXPECT_EQ(1, GetOrderOfRequest(1));
945 EXPECT_EQ(2, GetOrderOfRequest(2));
946 EXPECT_EQ(5, GetOrderOfRequest(3));
947 EXPECT_EQ(3, GetOrderOfRequest(4));
948 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
949 EXPECT_EQ(4, GetOrderOfRequest(6));
950 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17951
952 // Make sure we test order of all requests made.
953 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09954}
955
956class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
957 public:
[email protected]2ab05b52009-07-01 23:57:58958 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24959 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58960 TestConnectJobFactory* test_connect_job_factory,
961 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09962 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06963 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58964 within_callback_(false),
965 test_connect_job_factory_(test_connect_job_factory),
966 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09967
968 virtual void RunWithParams(const Tuple1<int>& params) {
969 callback_.RunWithParams(params);
970 ASSERT_EQ(OK, params.a);
971
972 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58973 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11974
975 // Don't allow reuse of the socket. Disconnect it and then release it and
976 // run through the MessageLoop once to get it completely released.
977 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09978 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11979 {
980 MessageLoop::ScopedNestableTaskAllower nestable(
981 MessageLoop::current());
982 MessageLoop::current()->RunAllPending();
983 }
[email protected]f6d1d6eb2009-06-24 20:16:09984 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47985 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:26986 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
[email protected]5a1d7ca2010-04-28 20:12:27987 pool_, BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:58988 switch (next_job_type_) {
989 case TestConnectJob::kMockJob:
990 EXPECT_EQ(OK, rv);
991 break;
992 case TestConnectJob::kMockPendingJob:
993 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47994
995 // For pending jobs, wait for new socket to be created. This makes
996 // sure there are no more pending operations nor any unclosed sockets
997 // when the test finishes.
998 // We need to give it a little bit of time to run, so that all the
999 // operations that happen on timers (e.g. cleanup of idle
1000 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:111001 {
1002 MessageLoop::ScopedNestableTaskAllower nestable(
1003 MessageLoop::current());
1004 PlatformThread::Sleep(10);
1005 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1006 }
[email protected]2ab05b52009-07-01 23:57:581007 break;
1008 default:
1009 FAIL() << "Unexpected job type: " << next_job_type_;
1010 break;
1011 }
[email protected]f6d1d6eb2009-06-24 20:16:091012 }
1013 }
1014
1015 int WaitForResult() {
1016 return callback_.WaitForResult();
1017 }
1018
1019 private:
1020 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241021 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091022 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581023 TestConnectJobFactory* const test_connect_job_factory_;
1024 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091025 TestCompletionCallback callback_;
1026};
1027
[email protected]2ab05b52009-07-01 23:57:581028TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531029 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201030
[email protected]0b7648c2009-07-06 20:14:011031 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061032 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581033 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061034 &handle, pool_.get(), connect_job_factory_,
1035 TestConnectJob::kMockPendingJob);
[email protected]5a1d7ca2010-04-28 20:12:271036 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1037 BoundNetLog());
[email protected]f6d1d6eb2009-06-24 20:16:091038 ASSERT_EQ(ERR_IO_PENDING, rv);
1039
1040 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581041}
[email protected]f6d1d6eb2009-06-24 20:16:091042
[email protected]2ab05b52009-07-01 23:57:581043TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531044 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201045
[email protected]0b7648c2009-07-06 20:14:011046 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061047 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581048 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061049 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]5a1d7ca2010-04-28 20:12:271050 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1051 BoundNetLog());
[email protected]2ab05b52009-07-01 23:57:581052 ASSERT_EQ(ERR_IO_PENDING, rv);
1053
1054 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091055}
1056
1057// Make sure that pending requests get serviced after active requests get
1058// cancelled.
[email protected]ab838892009-06-30 18:49:051059TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531060 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201061
[email protected]0b7648c2009-07-06 20:14:011062 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091063
[email protected]c9d6a1d2009-07-14 16:15:201064 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1065 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1066 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1070 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091071
[email protected]c9d6a1d2009-07-14 16:15:201072 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1073 // Let's cancel them.
1074 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331075 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1076 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091077 }
1078
[email protected]f6d1d6eb2009-06-24 20:16:091079 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201080 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1081 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331082 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091083 }
1084
[email protected]75439d3b2009-07-23 22:11:171085 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091086}
1087
1088// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051089TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531090 const size_t kMaxSockets = 5;
1091 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201092
[email protected]0b7648c2009-07-06 20:14:011093 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091094
[email protected]211d21722009-07-22 15:48:531095 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1096 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091097
1098 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531099 for (size_t i = 0; i < kNumberOfRequests; ++i)
1100 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091101
[email protected]211d21722009-07-22 15:48:531102 for (size_t i = 0; i < kNumberOfRequests; ++i)
1103 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091104}
1105
[email protected]5fc08e32009-07-15 17:09:571106TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531107 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571108
1109 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1110
[email protected]a512f5982009-08-18 16:01:061111 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271112 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1113 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571114 EXPECT_EQ(ERR_IO_PENDING, rv);
1115
1116 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331117 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571118
[email protected]5a1d7ca2010-04-28 20:12:271119 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1120 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571121 EXPECT_EQ(ERR_IO_PENDING, rv);
1122 EXPECT_EQ(OK, req.WaitForResult());
1123
[email protected]a6c59f62009-07-29 16:33:331124 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171125 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571126 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1127}
1128
[email protected]2b7523d2009-07-29 20:29:231129// Regression test for http://crbug.com/17985.
1130TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1131 const int kMaxSockets = 3;
1132 const int kMaxSocketsPerGroup = 2;
1133 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1134
[email protected]ac790b42009-12-02 04:31:311135 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231136
1137 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1138 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1139
1140 // This is going to be a pending request in an otherwise empty group.
1141 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1142
1143 // Reach the maximum socket limit.
1144 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1145
1146 // Create a stalled group with high priorities.
1147 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1148 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1149 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1150
1151 // Release the first two sockets from "a", which will make room
1152 // for requests from "c". After that "a" will have no active sockets
1153 // and one pending request.
1154 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1155 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1156
1157 // Closing idle sockets should not get us into trouble, but in the bug
1158 // we were hitting a CHECK here.
[email protected]42df4e8e2010-04-13 22:02:561159 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
[email protected]d43002e2010-04-07 21:29:491160 pool_->CloseIdleSockets();
[email protected]42df4e8e2010-04-13 22:02:561161 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2b7523d2009-07-29 20:29:231162}
1163
[email protected]4d3b05d2010-01-27 21:27:291164TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531165 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571166
1167 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061168 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531169 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261170 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571171 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331172 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571173 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331174 EXPECT_TRUE(req.handle()->is_initialized());
1175 EXPECT_TRUE(req.handle()->socket());
1176 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301177
[email protected]a2006ece2010-04-23 16:44:021178 EXPECT_EQ(7u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461179 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531180 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1181 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531182 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461183 EXPECT_TRUE(LogContainsEndEvent(
[email protected]a2006ece2010-04-23 16:44:021184 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1185 EXPECT_TRUE(LogContainsEndEvent(
1186 log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571187}
1188
[email protected]4d3b05d2010-01-27 21:27:291189TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571190 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531191 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571192
1193 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061194 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531195 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571196 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261197 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1198 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331199 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571200 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301201
[email protected]a2006ece2010-04-23 16:44:021202 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461203 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531204 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1205 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531206 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321207 EXPECT_TRUE(LogContainsEndEvent(
[email protected]a2006ece2010-04-23 16:44:021208 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1209 EXPECT_TRUE(LogContainsEndEvent(
1210 log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571211}
1212
[email protected]4d3b05d2010-01-27 21:27:291213TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101214 // TODO(eroman): Add back the log expectations! Removed them because the
1215 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531216 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571217
1218 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061219 TestSocketRequest req(&request_order_, &completion_count_);
1220 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571221
1222 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261223 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1224 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531225 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571226 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261227 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1228 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571229
[email protected]a6c59f62009-07-29 16:33:331230 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571231
[email protected]fd7b7c92009-08-20 19:38:301232
1233 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301234
[email protected]5fc08e32009-07-15 17:09:571235 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331236 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301237
1238 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531239 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571240}
1241
[email protected]4d3b05d2010-01-27 21:27:291242TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341243 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1244
[email protected]17a0c6c2009-08-04 00:07:041245 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1246
[email protected]ac790b42009-12-02 04:31:311247 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1248 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1249 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1250 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341251
1252 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1253 requests_[2]->handle()->Reset();
1254 requests_[3]->handle()->Reset();
1255 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1256
1257 requests_[1]->handle()->Reset();
1258 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1259
1260 requests_[0]->handle()->Reset();
1261 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1262}
1263
[email protected]5fc08e32009-07-15 17:09:571264// When requests and ConnectJobs are not coupled, the request will get serviced
1265// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291266TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531267 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571268
1269 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321270 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571271
[email protected]a512f5982009-08-18 16:01:061272 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271273 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1274 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571275 EXPECT_EQ(ERR_IO_PENDING, rv);
1276 EXPECT_EQ(OK, req1.WaitForResult());
1277
1278 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1279 // without a job.
1280 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1281
[email protected]a512f5982009-08-18 16:01:061282 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271283 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1284 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061286 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271287 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1288 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571289 EXPECT_EQ(ERR_IO_PENDING, rv);
1290
1291 // Both Requests 2 and 3 are pending. We release socket 1 which should
1292 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331293 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571294 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331295 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571296 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331297 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571298
1299 // Signal job 2, which should service request 3.
1300
1301 client_socket_factory_.SignalJobs();
1302 EXPECT_EQ(OK, req3.WaitForResult());
1303
1304 ASSERT_EQ(3U, request_order_.size());
1305 EXPECT_EQ(&req1, request_order_[0]);
1306 EXPECT_EQ(&req2, request_order_[1]);
1307 EXPECT_EQ(&req3, request_order_[2]);
1308 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1309}
1310
1311// The requests are not coupled to the jobs. So, the requests should finish in
1312// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291313TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531314 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571315 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321316 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571317
[email protected]a512f5982009-08-18 16:01:061318 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271319 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1320 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571321 EXPECT_EQ(ERR_IO_PENDING, rv);
1322
[email protected]a512f5982009-08-18 16:01:061323 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271324 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1325 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571326 EXPECT_EQ(ERR_IO_PENDING, rv);
1327
1328 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321329 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571330
[email protected]a512f5982009-08-18 16:01:061331 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271332 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_,
1333 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571334 EXPECT_EQ(ERR_IO_PENDING, rv);
1335
1336 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1337 EXPECT_EQ(OK, req2.WaitForResult());
1338 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1339
1340 ASSERT_EQ(3U, request_order_.size());
1341 EXPECT_EQ(&req1, request_order_[0]);
1342 EXPECT_EQ(&req2, request_order_[1]);
1343 EXPECT_EQ(&req3, request_order_[2]);
1344}
1345
[email protected]4d3b05d2010-01-27 21:27:291346TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531347 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571348 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321349 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571350
[email protected]a512f5982009-08-18 16:01:061351 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271352 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_,
1353 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571354 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331355 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571356
1357 MessageLoop::current()->RunAllPending();
1358
[email protected]a512f5982009-08-18 16:01:061359 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271360 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1361 BoundNetLog());
[email protected]5fc08e32009-07-15 17:09:571362 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331363 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1364 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571365}
1366
[email protected]4d3b05d2010-01-27 21:27:291367TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161368 CreatePoolWithIdleTimeouts(
1369 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1370 base::TimeDelta(), // Time out unused sockets immediately.
1371 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1372
1373 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1374
1375 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1376
1377 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271378 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161379 EXPECT_EQ(ERR_IO_PENDING, rv);
1380 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1381
1382 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271383 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]9bf28db2009-08-29 01:35:161384 EXPECT_EQ(ERR_IO_PENDING, rv);
1385 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1386
1387 // Cancel one of the requests. Wait for the other, which will get the first
1388 // job. Release the socket. Run the loop again to make sure the second
1389 // socket is sitting idle and the first one is released (since ReleaseSocket()
1390 // just posts a DoReleaseSocket() task).
1391
1392 req.handle()->Reset();
1393 EXPECT_EQ(OK, req2.WaitForResult());
1394 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471395
1396 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1397 // actually become pending until 2ms after they have been created. In order
1398 // to flush all tasks, we need to wait so that we know there are no
1399 // soon-to-be-pending tasks waiting.
1400 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161401 MessageLoop::current()->RunAllPending();
1402
1403 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041404
[email protected]9bf28db2009-08-29 01:35:161405 // Invoke the idle socket cleanup check. Only one socket should be left, the
1406 // used socket. Request it to make sure that it's used.
1407
1408 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531409 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261410 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161411 EXPECT_EQ(OK, rv);
1412 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151413 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451414 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161415}
1416
[email protected]2041cf342010-02-19 03:15:591417// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161418// because of multiple releasing disconnected sockets.
1419TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1420 CreatePoolWithIdleTimeouts(
1421 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1422 base::TimeDelta(), // Time out unused sockets immediately.
1423 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1424
1425 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1426
1427 // Startup 4 connect jobs. Two of them will be pending.
1428
1429 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271430 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161431 EXPECT_EQ(OK, rv);
1432
1433 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271434 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161435 EXPECT_EQ(OK, rv);
1436
1437 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271438 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161439 EXPECT_EQ(ERR_IO_PENDING, rv);
1440
1441 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]5a1d7ca2010-04-28 20:12:271442 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, BoundNetLog());
[email protected]4f2abec2010-02-03 18:10:161443 EXPECT_EQ(ERR_IO_PENDING, rv);
1444
1445 // Release two disconnected sockets.
1446
1447 req.handle()->socket()->Disconnect();
1448 req.handle()->Reset();
1449 req2.handle()->socket()->Disconnect();
1450 req2.handle()->Reset();
1451
1452 EXPECT_EQ(OK, req3.WaitForResult());
1453 EXPECT_FALSE(req3.handle()->is_reused());
1454 EXPECT_EQ(OK, req4.WaitForResult());
1455 EXPECT_FALSE(req4.handle()->is_reused());
1456}
1457
[email protected]fd4fe0b2010-02-08 23:02:151458TEST_F(ClientSocketPoolBaseTest,
1459 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1460 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1461
1462 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1463
1464 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1465 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1466 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1467 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1468
1469 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1470 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1471 EXPECT_EQ(2u, completion_count_);
1472
1473 // Releases one connection.
1474 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1475 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1476
1477 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1478 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1479 EXPECT_EQ(4u, completion_count_);
1480
1481 EXPECT_EQ(1, GetOrderOfRequest(1));
1482 EXPECT_EQ(2, GetOrderOfRequest(2));
1483 EXPECT_EQ(3, GetOrderOfRequest(3));
1484 EXPECT_EQ(4, GetOrderOfRequest(4));
1485
1486 // Make sure we test order of all requests made.
1487 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1488}
1489
[email protected]4f1e4982010-03-02 18:31:041490class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1491 public:
1492 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1493 : pool_(pool) {}
1494
1495 ClientSocketHandle* handle() { return &handle_; }
1496
1497 int WaitForResult() {
1498 return callback_.WaitForResult();
1499 }
1500
1501 virtual void RunWithParams(const Tuple1<int>& params) {
1502 callback_.RunWithParams(params);
1503 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261504 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271505 &callback2_, pool_, BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041506 }
1507
1508 private:
1509 TestClientSocketPool* const pool_;
1510 ClientSocketHandle handle_;
1511 ClientSocketHandle handle2_;
1512 TestCompletionCallback callback_;
1513 TestCompletionCallback callback2_;
1514};
1515
1516// This test covers the case where, within the same DoReleaseSocket() callback,
1517// we release the just acquired socket and start up a new request. See bug
1518// 36871 for details.
1519TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1521
1522 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1523
1524 // Complete one request and release the socket.
1525 ClientSocketHandle handle;
1526 TestCompletionCallback callback;
[email protected]a796bcec2010-03-22 17:17:261527 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
[email protected]5a1d7ca2010-04-28 20:12:271528 BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041529 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321530
[email protected]4f1e4982010-03-02 18:31:041531 // Before the DoReleaseSocket() task has run, start up a
1532 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1533 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1534 TestReleasingSocketRequest request(pool_.get());
[email protected]a796bcec2010-03-22 17:17:261535 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
[email protected]5a1d7ca2010-04-28 20:12:271536 &request, pool_, BoundNetLog()));
[email protected]4f1e4982010-03-02 18:31:041537
1538 EXPECT_EQ(OK, request.WaitForResult());
1539}
1540
[email protected]f6d1d6eb2009-06-24 20:16:091541} // namespace
1542
1543} // namespace net