blob: cd333ff9df9a7b80e44d1078be2599dfc52e55bf [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(
474 &ignored, NULL, kDefaultPriority, NULL, NULL);
[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_,
482 NULL));
[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(
492 &ignored, NULL, kDefaultPriority, NULL, NULL);
[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]9e743cd2010-03-16 07:03:53559 EXPECT_TRUE(LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
[email protected]e9002a92010-01-29 07:10:46560 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:53561 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]a2006ece2010-04-23 16:44:02562 EXPECT_TRUE(LogContainsEndEvent(
563 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
564 EXPECT_TRUE(LogContainsEndEvent(log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09565}
566
[email protected]211d21722009-07-22 15:48:53567TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
568 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
569
[email protected]9e743cd2010-03-16 07:03:53570 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30571
[email protected]211d21722009-07-22 15:48:53572 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
573 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
574 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
575 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
576
577 EXPECT_EQ(static_cast<int>(requests_.size()),
578 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17579 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53580
581 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
582 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
583 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
584
[email protected]42df4e8e2010-04-13 22:02:56585 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53586
587 EXPECT_EQ(static_cast<int>(requests_.size()),
588 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17589 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53590
591 EXPECT_EQ(1, GetOrderOfRequest(1));
592 EXPECT_EQ(2, GetOrderOfRequest(2));
593 EXPECT_EQ(3, GetOrderOfRequest(3));
594 EXPECT_EQ(4, GetOrderOfRequest(4));
595 EXPECT_EQ(5, GetOrderOfRequest(5));
596 EXPECT_EQ(6, GetOrderOfRequest(6));
597 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17598
599 // Make sure we test order of all requests made.
600 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53601}
602
603TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
604 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
605
[email protected]9e743cd2010-03-16 07:03:53606 // TODO(eroman): Check that the NetLog contains this event.
[email protected]fd7b7c92009-08-20 19:38:30607
[email protected]211d21722009-07-22 15:48:53608 // Reach all limits: max total sockets, and max sockets per group.
609 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
610 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
611 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
612 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
613
614 EXPECT_EQ(static_cast<int>(requests_.size()),
615 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17616 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53617
618 // Now create a new group and verify that we don't starve it.
619 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
620
[email protected]42df4e8e2010-04-13 22:02:56621 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53622
623 EXPECT_EQ(static_cast<int>(requests_.size()),
624 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17625 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53626
627 EXPECT_EQ(1, GetOrderOfRequest(1));
628 EXPECT_EQ(2, GetOrderOfRequest(2));
629 EXPECT_EQ(3, GetOrderOfRequest(3));
630 EXPECT_EQ(4, GetOrderOfRequest(4));
631 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17632
633 // Make sure we test order of all requests made.
634 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53635}
636
637TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
638 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
639
[email protected]ac790b42009-12-02 04:31:31640 EXPECT_EQ(OK, StartRequest("b", LOWEST));
641 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
642 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
643 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53644
645 EXPECT_EQ(static_cast<int>(requests_.size()),
646 client_socket_factory_.allocation_count());
647
[email protected]ac790b42009-12-02 04:31:31648 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
649 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
650 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53651
[email protected]42df4e8e2010-04-13 22:02:56652 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53653
[email protected]42df4e8e2010-04-13 22:02:56654 // We're re-using one socket for group "a", and one for "b".
655 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
656 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17657 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53658
659 // First 4 requests don't have to wait, and finish in order.
660 EXPECT_EQ(1, GetOrderOfRequest(1));
661 EXPECT_EQ(2, GetOrderOfRequest(2));
662 EXPECT_EQ(3, GetOrderOfRequest(3));
663 EXPECT_EQ(4, GetOrderOfRequest(4));
664
[email protected]ac790b42009-12-02 04:31:31665 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
666 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53667 EXPECT_EQ(7, GetOrderOfRequest(5));
668 EXPECT_EQ(6, GetOrderOfRequest(6));
669 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17670
671 // Make sure we test order of all requests made.
672 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53673}
674
675TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
676 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
677
[email protected]ac790b42009-12-02 04:31:31678 EXPECT_EQ(OK, StartRequest("a", LOWEST));
679 EXPECT_EQ(OK, StartRequest("a", LOW));
680 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
681 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53682
683 EXPECT_EQ(static_cast<int>(requests_.size()),
684 client_socket_factory_.allocation_count());
685
[email protected]ac790b42009-12-02 04:31:31686 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
687 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
688 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53689
[email protected]42df4e8e2010-04-13 22:02:56690 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53691
[email protected]42df4e8e2010-04-13 22:02:56692 // We're re-using one socket for group "a", and one for "b".
693 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
[email protected]211d21722009-07-22 15:48:53694 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17695 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53696
697 // First 4 requests don't have to wait, and finish in order.
698 EXPECT_EQ(1, GetOrderOfRequest(1));
699 EXPECT_EQ(2, GetOrderOfRequest(2));
700 EXPECT_EQ(3, GetOrderOfRequest(3));
701 EXPECT_EQ(4, GetOrderOfRequest(4));
702
703 // Request ("b", 7) has the highest priority, but we can't make new socket for
704 // group "b", because it has reached the per-group limit. Then we make
705 // socket for ("c", 6), because it has higher priority than ("a", 4),
706 // and we still can't make a socket for group "b".
707 EXPECT_EQ(5, GetOrderOfRequest(5));
708 EXPECT_EQ(6, GetOrderOfRequest(6));
709 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17710
711 // Make sure we test order of all requests made.
712 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53713}
714
715// Make sure that we count connecting sockets against the total limit.
716TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
718
719 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
720 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
721 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
722
723 // Create one asynchronous request.
724 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
725 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
726
[email protected]6b175382009-10-13 06:47:47727 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
728 // actually become pending until 2ms after they have been created. In order
729 // to flush all tasks, we need to wait so that we know there are no
730 // soon-to-be-pending tasks waiting.
731 PlatformThread::Sleep(10);
732 MessageLoop::current()->RunAllPending();
733
[email protected]211d21722009-07-22 15:48:53734 // The next synchronous request should wait for its turn.
735 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
736 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
737
[email protected]42df4e8e2010-04-13 22:02:56738 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53739
740 EXPECT_EQ(static_cast<int>(requests_.size()),
741 client_socket_factory_.allocation_count());
742
743 EXPECT_EQ(1, GetOrderOfRequest(1));
744 EXPECT_EQ(2, GetOrderOfRequest(2));
745 EXPECT_EQ(3, GetOrderOfRequest(3));
746 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17747 EXPECT_EQ(5, GetOrderOfRequest(5));
748
749 // Make sure we test order of all requests made.
750 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53751}
752
753// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
754// which tells it to use more expensive, but accurate, group selection
755// algorithm. Make sure it doesn't get stuck in the "on" state.
756TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
757 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
758
759 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
760
761 // Reach group socket limit.
762 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
763 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
764 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
765
766 // Reach total limit, but don't request more sockets.
767 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
768 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
769 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
770
771 // Request one more socket while we are at the maximum sockets limit.
772 // This should flip the may_have_stalled_group flag.
773 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
774 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
775
776 // After releasing first connection for "a", we're still at the
777 // maximum sockets limit, but every group's pending queue is empty,
778 // so we reset the flag.
[email protected]42df4e8e2010-04-13 22:02:56779 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53780 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
781
782 // Requesting additional socket while at the total limit should
783 // flip the flag back to "on".
784 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
785 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
786
787 // We'll request one more socket to verify that we don't reset the flag
788 // too eagerly.
789 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
790 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
791
792 // We're at the maximum socket limit, and still have one request pending
793 // for "d". Flag should be "on".
[email protected]42df4e8e2010-04-13 22:02:56794 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53795 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
796
797 // Now every group's pending queue should be empty again.
[email protected]42df4e8e2010-04-13 22:02:56798 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
[email protected]211d21722009-07-22 15:48:53799 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
800
[email protected]42df4e8e2010-04-13 22:02:56801 ReleaseAllConnections(KEEP_ALIVE);
[email protected]211d21722009-07-22 15:48:53802 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
803}
804
[email protected]6427fe22010-04-16 22:27:41805TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
806 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
807 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
808
809 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
810 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
811 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
812 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
813
814 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
815
816 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
817
818 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", kDefaultPriority));
819 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
820
821 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
822
823 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
824 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
825 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
826 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
827 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
828 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
829 EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
830}
831
[email protected]ab838892009-06-30 18:49:05832TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53833 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09834
[email protected]c9d6a1d2009-07-14 16:15:20835 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
836 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31837 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
838 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
839 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
840 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
841 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09842
[email protected]c9d6a1d2009-07-14 16:15:20843 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09844
[email protected]c9d6a1d2009-07-14 16:15:20845 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
846 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17847 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09848
[email protected]c9d6a1d2009-07-14 16:15:20849 EXPECT_EQ(1, GetOrderOfRequest(1));
850 EXPECT_EQ(2, GetOrderOfRequest(2));
851 EXPECT_EQ(6, GetOrderOfRequest(3));
852 EXPECT_EQ(4, GetOrderOfRequest(4));
853 EXPECT_EQ(3, GetOrderOfRequest(5));
854 EXPECT_EQ(5, GetOrderOfRequest(6));
855 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17856
857 // Make sure we test order of all requests made.
858 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09859}
860
[email protected]ab838892009-06-30 18:49:05861TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53862 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09863
[email protected]c9d6a1d2009-07-14 16:15:20864 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
865 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31866 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
867 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09871
[email protected]c9d6a1d2009-07-14 16:15:20872 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09873
[email protected]c9d6a1d2009-07-14 16:15:20874 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
875 EXPECT_EQ(OK, requests_[i]->WaitForResult());
876
877 EXPECT_EQ(static_cast<int>(requests_.size()),
878 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17879 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09880}
881
882// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05883// The pending connect job will be cancelled and should not call back into
884// ClientSocketPoolBase.
885TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20887
[email protected]ab838892009-06-30 18:49:05888 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06889 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05890 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26891 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL));
[email protected]a6c59f62009-07-29 16:33:33892 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09893}
894
[email protected]ab838892009-06-30 18:49:05895TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53896 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20897
[email protected]ab838892009-06-30 18:49:05898 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06899 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09900 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06901 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09902
[email protected]ab838892009-06-30 18:49:05903 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:26904 InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09905
906 handle.Reset();
907
908 TestCompletionCallback callback2;
[email protected]a796bcec2010-03-22 17:17:26909 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle, "a", kDefaultPriority,
910 &callback2, pool_, NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09911
912 EXPECT_EQ(OK, callback2.WaitForResult());
913 EXPECT_FALSE(callback.have_result());
914
915 handle.Reset();
916}
917
[email protected]ab838892009-06-30 18:49:05918TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53919 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09920
[email protected]c9d6a1d2009-07-14 16:15:20921 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
922 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31923 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
924 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
925 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
926 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
927 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09928
929 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20930 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33931 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
932 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09933
[email protected]c9d6a1d2009-07-14 16:15:20934 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09935
[email protected]c9d6a1d2009-07-14 16:15:20936 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
937 client_socket_factory_.allocation_count());
938 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17939 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09940
[email protected]c9d6a1d2009-07-14 16:15:20941 EXPECT_EQ(1, GetOrderOfRequest(1));
942 EXPECT_EQ(2, GetOrderOfRequest(2));
943 EXPECT_EQ(5, GetOrderOfRequest(3));
944 EXPECT_EQ(3, GetOrderOfRequest(4));
945 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
946 EXPECT_EQ(4, GetOrderOfRequest(6));
947 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17948
949 // Make sure we test order of all requests made.
950 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09951}
952
953class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
954 public:
[email protected]2ab05b52009-07-01 23:57:58955 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24956 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58957 TestConnectJobFactory* test_connect_job_factory,
958 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09959 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06960 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58961 within_callback_(false),
962 test_connect_job_factory_(test_connect_job_factory),
963 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09964
965 virtual void RunWithParams(const Tuple1<int>& params) {
966 callback_.RunWithParams(params);
967 ASSERT_EQ(OK, params.a);
968
969 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58970 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11971
972 // Don't allow reuse of the socket. Disconnect it and then release it and
973 // run through the MessageLoop once to get it completely released.
974 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09975 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11976 {
977 MessageLoop::ScopedNestableTaskAllower nestable(
978 MessageLoop::current());
979 MessageLoop::current()->RunAllPending();
980 }
[email protected]f6d1d6eb2009-06-24 20:16:09981 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47982 TestCompletionCallback next_job_callback;
[email protected]a796bcec2010-03-22 17:17:26983 int rv = InitHandle(handle_, "a", kDefaultPriority, &next_job_callback,
984 pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:58985 switch (next_job_type_) {
986 case TestConnectJob::kMockJob:
987 EXPECT_EQ(OK, rv);
988 break;
989 case TestConnectJob::kMockPendingJob:
990 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47991
992 // For pending jobs, wait for new socket to be created. This makes
993 // sure there are no more pending operations nor any unclosed sockets
994 // when the test finishes.
995 // We need to give it a little bit of time to run, so that all the
996 // operations that happen on timers (e.g. cleanup of idle
997 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:11998 {
999 MessageLoop::ScopedNestableTaskAllower nestable(
1000 MessageLoop::current());
1001 PlatformThread::Sleep(10);
1002 EXPECT_EQ(OK, next_job_callback.WaitForResult());
1003 }
[email protected]2ab05b52009-07-01 23:57:581004 break;
1005 default:
1006 FAIL() << "Unexpected job type: " << next_job_type_;
1007 break;
1008 }
[email protected]f6d1d6eb2009-06-24 20:16:091009 }
1010 }
1011
1012 int WaitForResult() {
1013 return callback_.WaitForResult();
1014 }
1015
1016 private:
1017 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:241018 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:091019 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:581020 TestConnectJobFactory* const test_connect_job_factory_;
1021 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:091022 TestCompletionCallback callback_;
1023};
1024
[email protected]2ab05b52009-07-01 23:57:581025TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531026 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201027
[email protected]0b7648c2009-07-06 20:14:011028 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061029 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581030 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061031 &handle, pool_.get(), connect_job_factory_,
1032 TestConnectJob::kMockPendingJob);
[email protected]a796bcec2010-03-22 17:17:261033 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091034 ASSERT_EQ(ERR_IO_PENDING, rv);
1035
1036 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581037}
[email protected]f6d1d6eb2009-06-24 20:16:091038
[email protected]2ab05b52009-07-01 23:57:581039TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531040 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201041
[email protected]0b7648c2009-07-06 20:14:011042 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061043 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581044 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061045 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a796bcec2010-03-22 17:17:261046 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback, pool_, NULL);
[email protected]2ab05b52009-07-01 23:57:581047 ASSERT_EQ(ERR_IO_PENDING, rv);
1048
1049 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091050}
1051
1052// Make sure that pending requests get serviced after active requests get
1053// cancelled.
[email protected]ab838892009-06-30 18:49:051054TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531055 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201056
[email protected]0b7648c2009-07-06 20:14:011057 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091058
[email protected]c9d6a1d2009-07-14 16:15:201059 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1060 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1061 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1062 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1063 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1064 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1065 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091066
[email protected]c9d6a1d2009-07-14 16:15:201067 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1068 // Let's cancel them.
1069 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331070 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1071 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091072 }
1073
[email protected]f6d1d6eb2009-06-24 20:16:091074 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201075 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1076 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331077 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091078 }
1079
[email protected]75439d3b2009-07-23 22:11:171080 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091081}
1082
1083// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051084TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531085 const size_t kMaxSockets = 5;
1086 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201087
[email protected]0b7648c2009-07-06 20:14:011088 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091089
[email protected]211d21722009-07-22 15:48:531090 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1091 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091092
1093 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531094 for (size_t i = 0; i < kNumberOfRequests; ++i)
1095 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091096
[email protected]211d21722009-07-22 15:48:531097 for (size_t i = 0; i < kNumberOfRequests; ++i)
1098 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091099}
1100
[email protected]5fc08e32009-07-15 17:09:571101TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531102 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571103
1104 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1105
[email protected]a512f5982009-08-18 16:01:061106 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261107 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571108 EXPECT_EQ(ERR_IO_PENDING, rv);
1109
1110 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331111 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571112
[email protected]a796bcec2010-03-22 17:17:261113 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571114 EXPECT_EQ(ERR_IO_PENDING, rv);
1115 EXPECT_EQ(OK, req.WaitForResult());
1116
[email protected]a6c59f62009-07-29 16:33:331117 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171118 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571119 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1120}
1121
[email protected]2b7523d2009-07-29 20:29:231122// Regression test for http://crbug.com/17985.
1123TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1124 const int kMaxSockets = 3;
1125 const int kMaxSocketsPerGroup = 2;
1126 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1127
[email protected]ac790b42009-12-02 04:31:311128 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231129
1130 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1131 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1132
1133 // This is going to be a pending request in an otherwise empty group.
1134 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1135
1136 // Reach the maximum socket limit.
1137 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1138
1139 // Create a stalled group with high priorities.
1140 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1141 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1142 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1143
1144 // Release the first two sockets from "a", which will make room
1145 // for requests from "c". After that "a" will have no active sockets
1146 // and one pending request.
1147 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1148 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1149
1150 // Closing idle sockets should not get us into trouble, but in the bug
1151 // we were hitting a CHECK here.
[email protected]42df4e8e2010-04-13 22:02:561152 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
[email protected]d43002e2010-04-07 21:29:491153 pool_->CloseIdleSockets();
[email protected]42df4e8e2010-04-13 22:02:561154 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
[email protected]2b7523d2009-07-29 20:29:231155}
1156
[email protected]4d3b05d2010-01-27 21:27:291157TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531158 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571159
1160 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061161 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531162 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261163 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]5fc08e32009-07-15 17:09:571164 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331165 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571166 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331167 EXPECT_TRUE(req.handle()->is_initialized());
1168 EXPECT_TRUE(req.handle()->socket());
1169 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301170
[email protected]a2006ece2010-04-23 16:44:021171 EXPECT_EQ(7u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461172 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531173 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1174 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531175 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]e9002a92010-01-29 07:10:461176 EXPECT_TRUE(LogContainsEndEvent(
[email protected]a2006ece2010-04-23 16:44:021177 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1178 EXPECT_TRUE(LogContainsEndEvent(
1179 log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571180}
1181
[email protected]4d3b05d2010-01-27 21:27:291182TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571183 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531184 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571185
1186 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061187 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]9e743cd2010-03-16 07:03:531188 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571189 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261190 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1191 log.bound()));
[email protected]a6c59f62009-07-29 16:33:331192 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571193 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301194
[email protected]a2006ece2010-04-23 16:44:021195 EXPECT_EQ(6u, log.entries().size());
[email protected]e9002a92010-01-29 07:10:461196 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531197 log.entries(), 0, NetLog::TYPE_SOCKET_POOL));
1198 EXPECT_TRUE(LogContainsBeginEvent(
[email protected]9e743cd2010-03-16 07:03:531199 log.entries(), 2, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]6b624c62010-03-14 08:37:321200 EXPECT_TRUE(LogContainsEndEvent(
[email protected]a2006ece2010-04-23 16:44:021201 log.entries(), 3, NetLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1202 EXPECT_TRUE(LogContainsEndEvent(
1203 log.entries(), 5, NetLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571204}
1205
[email protected]4d3b05d2010-01-27 21:27:291206TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]b22b5162010-03-16 07:53:101207 // TODO(eroman): Add back the log expectations! Removed them because the
1208 // ordering is difficult, and some may fire during destructor.
[email protected]211d21722009-07-22 15:48:531209 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571210
1211 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061212 TestSocketRequest req(&request_order_, &completion_count_);
1213 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571214
1215 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261216 InitHandle(req.handle(), "a", kDefaultPriority, &req, pool_,
1217 BoundNetLog()));
[email protected]9e743cd2010-03-16 07:03:531218 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded);
[email protected]5fc08e32009-07-15 17:09:571219 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a796bcec2010-03-22 17:17:261220 InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_,
1221 BoundNetLog()));
[email protected]5fc08e32009-07-15 17:09:571222
[email protected]a6c59f62009-07-29 16:33:331223 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571224
[email protected]fd7b7c92009-08-20 19:38:301225
1226 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]fd7b7c92009-08-20 19:38:301227
[email protected]5fc08e32009-07-15 17:09:571228 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331229 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301230
1231 // Now request 2 has actually finished.
[email protected]9e743cd2010-03-16 07:03:531232 // TODO(eroman): Add back log expectations.
[email protected]5fc08e32009-07-15 17:09:571233}
1234
[email protected]4d3b05d2010-01-27 21:27:291235TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341236 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1237
[email protected]17a0c6c2009-08-04 00:07:041238 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1239
[email protected]ac790b42009-12-02 04:31:311240 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1241 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1242 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1243 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341244
1245 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1246 requests_[2]->handle()->Reset();
1247 requests_[3]->handle()->Reset();
1248 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1249
1250 requests_[1]->handle()->Reset();
1251 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1252
1253 requests_[0]->handle()->Reset();
1254 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1255}
1256
[email protected]5fc08e32009-07-15 17:09:571257// When requests and ConnectJobs are not coupled, the request will get serviced
1258// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291259TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531260 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571261
1262 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321263 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571264
[email protected]a512f5982009-08-18 16:01:061265 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261266 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571267 EXPECT_EQ(ERR_IO_PENDING, rv);
1268 EXPECT_EQ(OK, req1.WaitForResult());
1269
1270 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1271 // without a job.
1272 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1273
[email protected]a512f5982009-08-18 16:01:061274 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261275 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571276 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061277 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261278 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571279 EXPECT_EQ(ERR_IO_PENDING, rv);
1280
1281 // Both Requests 2 and 3 are pending. We release socket 1 which should
1282 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331283 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571284 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331285 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571286 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331287 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571288
1289 // Signal job 2, which should service request 3.
1290
1291 client_socket_factory_.SignalJobs();
1292 EXPECT_EQ(OK, req3.WaitForResult());
1293
1294 ASSERT_EQ(3U, request_order_.size());
1295 EXPECT_EQ(&req1, request_order_[0]);
1296 EXPECT_EQ(&req2, request_order_[1]);
1297 EXPECT_EQ(&req3, request_order_[2]);
1298 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1299}
1300
1301// The requests are not coupled to the jobs. So, the requests should finish in
1302// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291303TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531304 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571305 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321306 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571307
[email protected]a512f5982009-08-18 16:01:061308 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261309 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571310 EXPECT_EQ(ERR_IO_PENDING, rv);
1311
[email protected]a512f5982009-08-18 16:01:061312 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261313 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571314 EXPECT_EQ(ERR_IO_PENDING, rv);
1315
1316 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321317 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571318
[email protected]a512f5982009-08-18 16:01:061319 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261320 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571321 EXPECT_EQ(ERR_IO_PENDING, rv);
1322
1323 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1324 EXPECT_EQ(OK, req2.WaitForResult());
1325 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1326
1327 ASSERT_EQ(3U, request_order_.size());
1328 EXPECT_EQ(&req1, request_order_[0]);
1329 EXPECT_EQ(&req2, request_order_[1]);
1330 EXPECT_EQ(&req3, request_order_[2]);
1331}
1332
[email protected]4d3b05d2010-01-27 21:27:291333TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531334 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571335 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321336 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571337
[email protected]a512f5982009-08-18 16:01:061338 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261339 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571340 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331341 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571342
1343 MessageLoop::current()->RunAllPending();
1344
[email protected]a512f5982009-08-18 16:01:061345 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261346 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2, pool_, NULL);
[email protected]5fc08e32009-07-15 17:09:571347 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331348 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1349 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571350}
1351
[email protected]4d3b05d2010-01-27 21:27:291352TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161353 CreatePoolWithIdleTimeouts(
1354 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1355 base::TimeDelta(), // Time out unused sockets immediately.
1356 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1357
1358 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1359
1360 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1361
1362 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261363 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161364 EXPECT_EQ(ERR_IO_PENDING, rv);
1365 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1366
1367 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261368 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]9bf28db2009-08-29 01:35:161369 EXPECT_EQ(ERR_IO_PENDING, rv);
1370 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1371
1372 // Cancel one of the requests. Wait for the other, which will get the first
1373 // job. Release the socket. Run the loop again to make sure the second
1374 // socket is sitting idle and the first one is released (since ReleaseSocket()
1375 // just posts a DoReleaseSocket() task).
1376
1377 req.handle()->Reset();
1378 EXPECT_EQ(OK, req2.WaitForResult());
1379 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471380
1381 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1382 // actually become pending until 2ms after they have been created. In order
1383 // to flush all tasks, we need to wait so that we know there are no
1384 // soon-to-be-pending tasks waiting.
1385 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161386 MessageLoop::current()->RunAllPending();
1387
1388 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041389
[email protected]9bf28db2009-08-29 01:35:161390 // Invoke the idle socket cleanup check. Only one socket should be left, the
1391 // used socket. Request it to make sure that it's used.
1392
1393 pool_->CleanupTimedOutIdleSockets();
[email protected]9e743cd2010-03-16 07:03:531394 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
[email protected]a796bcec2010-03-22 17:17:261395 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, log.bound());
[email protected]9bf28db2009-08-29 01:35:161396 EXPECT_EQ(OK, rv);
1397 EXPECT_TRUE(req.handle()->is_reused());
[email protected]fd4fe0b2010-02-08 23:02:151398 EXPECT_TRUE(LogContainsEntryWithType(
[email protected]d13f51b2010-04-27 23:20:451399 log.entries(), 1, NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET));
[email protected]9bf28db2009-08-29 01:35:161400}
1401
[email protected]2041cf342010-02-19 03:15:591402// Make sure that we process all pending requests even when we're stalling
[email protected]4f2abec2010-02-03 18:10:161403// because of multiple releasing disconnected sockets.
1404TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1405 CreatePoolWithIdleTimeouts(
1406 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1407 base::TimeDelta(), // Time out unused sockets immediately.
1408 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1409
1410 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1411
1412 // Startup 4 connect jobs. Two of them will be pending.
1413
1414 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261415 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161416 EXPECT_EQ(OK, rv);
1417
1418 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261419 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161420 EXPECT_EQ(OK, rv);
1421
1422 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261423 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161424 EXPECT_EQ(ERR_IO_PENDING, rv);
1425
1426 TestSocketRequest req4(&request_order_, &completion_count_);
[email protected]a796bcec2010-03-22 17:17:261427 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_, NULL);
[email protected]4f2abec2010-02-03 18:10:161428 EXPECT_EQ(ERR_IO_PENDING, rv);
1429
1430 // Release two disconnected sockets.
1431
1432 req.handle()->socket()->Disconnect();
1433 req.handle()->Reset();
1434 req2.handle()->socket()->Disconnect();
1435 req2.handle()->Reset();
1436
1437 EXPECT_EQ(OK, req3.WaitForResult());
1438 EXPECT_FALSE(req3.handle()->is_reused());
1439 EXPECT_EQ(OK, req4.WaitForResult());
1440 EXPECT_FALSE(req4.handle()->is_reused());
1441}
1442
[email protected]fd4fe0b2010-02-08 23:02:151443TEST_F(ClientSocketPoolBaseTest,
1444 ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
1445 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1446
1447 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1448
1449 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1450 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1451 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1452 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1453
1454 EXPECT_EQ(OK, requests_[0]->WaitForResult());
1455 EXPECT_EQ(OK, requests_[1]->WaitForResult());
1456 EXPECT_EQ(2u, completion_count_);
1457
1458 // Releases one connection.
1459 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1460 EXPECT_EQ(OK, requests_[2]->WaitForResult());
1461
1462 EXPECT_TRUE(ReleaseOneConnection(NO_KEEP_ALIVE));
1463 EXPECT_EQ(OK, requests_[3]->WaitForResult());
1464 EXPECT_EQ(4u, completion_count_);
1465
1466 EXPECT_EQ(1, GetOrderOfRequest(1));
1467 EXPECT_EQ(2, GetOrderOfRequest(2));
1468 EXPECT_EQ(3, GetOrderOfRequest(3));
1469 EXPECT_EQ(4, GetOrderOfRequest(4));
1470
1471 // Make sure we test order of all requests made.
1472 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(5));
1473}
1474
[email protected]4f1e4982010-03-02 18:31:041475class TestReleasingSocketRequest : public CallbackRunner< Tuple1<int> > {
1476 public:
1477 explicit TestReleasingSocketRequest(TestClientSocketPool* pool)
1478 : pool_(pool) {}
1479
1480 ClientSocketHandle* handle() { return &handle_; }
1481
1482 int WaitForResult() {
1483 return callback_.WaitForResult();
1484 }
1485
1486 virtual void RunWithParams(const Tuple1<int>& params) {
1487 callback_.RunWithParams(params);
1488 handle_.Reset();
[email protected]a796bcec2010-03-22 17:17:261489 EXPECT_EQ(ERR_IO_PENDING, InitHandle(&handle2_, "a", kDefaultPriority,
1490 &callback2_, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041491 }
1492
1493 private:
1494 TestClientSocketPool* const pool_;
1495 ClientSocketHandle handle_;
1496 ClientSocketHandle handle2_;
1497 TestCompletionCallback callback_;
1498 TestCompletionCallback callback2_;
1499};
1500
1501// This test covers the case where, within the same DoReleaseSocket() callback,
1502// we release the just acquired socket and start up a new request. See bug
1503// 36871 for details.
1504TEST_F(ClientSocketPoolBaseTest, ReleasedSocketReleasesToo) {
1505 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1506
1507 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1508
1509 // Complete one request and release the socket.
1510 ClientSocketHandle handle;
1511 TestCompletionCallback callback;
[email protected]a796bcec2010-03-22 17:17:261512 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
1513 NULL));
[email protected]4f1e4982010-03-02 18:31:041514 handle.Reset();
[email protected]6b624c62010-03-14 08:37:321515
[email protected]4f1e4982010-03-02 18:31:041516 // Before the DoReleaseSocket() task has run, start up a
1517 // TestReleasingSocketRequest. This one will be ERR_IO_PENDING since
1518 // num_releasing_sockets > 0 and there was no idle socket to use yet.
1519 TestReleasingSocketRequest request(pool_.get());
[email protected]a796bcec2010-03-22 17:17:261520 EXPECT_EQ(ERR_IO_PENDING, InitHandle(request.handle(), "a", kDefaultPriority,
1521 &request, pool_, NULL));
[email protected]4f1e4982010-03-02 18:31:041522
1523 EXPECT_EQ(OK, request.WaitForResult());
1524}
1525
[email protected]f6d1d6eb2009-06-24 20:16:091526} // namespace
1527
1528} // namespace net