blob: 9f875ad7faa91a47d2a88d5c96058ddd17d20618 [file] [log] [blame]
[email protected]9b6fee12009-09-29 18:13:071// Copyright (c) 2009 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
7#include "base/compiler_specific.h"
8#include "base/message_loop.h"
[email protected]974ebd62009-08-03 23:14:349#include "base/platform_thread.h"
[email protected]c9d6a1d2009-07-14 16:15:2010#include "base/scoped_vector.h"
[email protected]fd7b7c92009-08-20 19:38:3011#include "net/base/load_log.h"
12#include "net/base/load_log_unittest.h"
[email protected]f6d1d6eb2009-06-24 20:16:0913#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3114#include "net/base/request_priority.h"
[email protected]f6d1d6eb2009-06-24 20:16:0915#include "net/base/test_completion_callback.h"
16#include "net/socket/client_socket.h"
17#include "net/socket/client_socket_factory.h"
18#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1719#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0920#include "testing/gtest/include/gtest/gtest.h"
21
22namespace net {
23
24namespace {
25
[email protected]211d21722009-07-22 15:48:5326const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2027const int kDefaultMaxSocketsPerGroup = 2;
[email protected]ac790b42009-12-02 04:31:3128const net::RequestPriority kDefaultPriority = MEDIUM;
[email protected]0b7648c2009-07-06 20:14:0129
[email protected]d80a4322009-08-14 07:07:4930typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase;
31
[email protected]f6d1d6eb2009-06-24 20:16:0932class MockClientSocket : public ClientSocket {
33 public:
34 MockClientSocket() : connected_(false) {}
35
[email protected]ab838892009-06-30 18:49:0536 // Socket methods:
37 virtual int Read(
38 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
39 return ERR_UNEXPECTED;
40 }
41
42 virtual int Write(
43 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
44 return ERR_UNEXPECTED;
45 }
[email protected]d3f66572009-09-09 22:38:0446 virtual bool SetReceiveBufferSize(int32 size) { return true; };
47 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0548
[email protected]f6d1d6eb2009-06-24 20:16:0949 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0550
[email protected]5a05c47a2009-11-02 23:25:1951 virtual int Connect(CompletionCallback* callback, LoadLog* load_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0952 connected_ = true;
53 return OK;
54 }
[email protected]f6d1d6eb2009-06-24 20:16:0955
[email protected]ab838892009-06-30 18:49:0556 virtual void Disconnect() { connected_ = false; }
57 virtual bool IsConnected() const { return connected_; }
58 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0159
[email protected]ab838892009-06-30 18:49:0560 virtual int GetPeerName(struct sockaddr* /* name */,
61 socklen_t* /* namelen */) {
[email protected]9f864b32010-01-20 15:01:1662 return ERR_UNEXPECTED;
[email protected]f6d1d6eb2009-06-24 20:16:0963 }
[email protected]f6d1d6eb2009-06-24 20:16:0964
65 private:
66 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0967
[email protected]ab838892009-06-30 18:49:0568 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0969};
70
[email protected]5fc08e32009-07-15 17:09:5771class TestConnectJob;
72
[email protected]f6d1d6eb2009-06-24 20:16:0973class MockClientSocketFactory : public ClientSocketFactory {
74 public:
[email protected]ab838892009-06-30 18:49:0575 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0976
77 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
78 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0579 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0980 }
81
82 virtual SSLClientSocket* CreateSSLClientSocket(
83 ClientSocket* transport_socket,
84 const std::string& hostname,
85 const SSLConfig& ssl_config) {
86 NOTIMPLEMENTED();
87 return NULL;
88 }
89
[email protected]5fc08e32009-07-15 17:09:5790 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
91 void SignalJobs();
92
[email protected]f6d1d6eb2009-06-24 20:16:0993 int allocation_count() const { return allocation_count_; }
94
[email protected]f6d1d6eb2009-06-24 20:16:0995 private:
96 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5797 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0998};
99
[email protected]ab838892009-06-30 18:49:05100class TestConnectJob : public ConnectJob {
101 public:
102 enum JobType {
103 kMockJob,
104 kMockFailingJob,
105 kMockPendingJob,
106 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57107 kMockWaitingJob,
108 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05109 };
110
111 TestConnectJob(JobType job_type,
112 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49113 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34114 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05115 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30116 MockClientSocketFactory* client_socket_factory,
117 LoadLog* load_log)
[email protected]4d3b05d2010-01-27 21:27:29118 : ConnectJob(group_name, timeout_duration, delegate, load_log),
[email protected]2ab05b52009-07-01 23:57:58119 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05120 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21121 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
122 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05123
[email protected]974ebd62009-08-03 23:14:34124 void Signal() {
125 DoConnect(waiting_success_, true /* async */);
126 }
127
[email protected]46451352009-09-01 14:54:21128 virtual LoadState GetLoadState() const { return load_state_; }
129
[email protected]974ebd62009-08-03 23:14:34130 private:
[email protected]ab838892009-06-30 18:49:05131 // ConnectJob methods:
132
[email protected]974ebd62009-08-03 23:14:34133 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05134 AddressList ignored;
135 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40136 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05137 switch (job_type_) {
138 case kMockJob:
139 return DoConnect(true /* successful */, false /* sync */);
140 case kMockFailingJob:
141 return DoConnect(false /* error */, false /* sync */);
142 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57143 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47144
145 // Depending on execution timings, posting a delayed task can result
146 // in the task getting executed the at the earliest possible
147 // opportunity or only after returning once from the message loop and
148 // then a second call into the message loop. In order to make behavior
149 // more deterministic, we change the default delay to 2ms. This should
150 // always require us to wait for the second call into the message loop.
151 //
152 // N.B. The correct fix for this and similar timing problems is to
153 // abstract time for the purpose of unittests. Unfortunately, we have
154 // a lot of third-party components that directly call the various
155 // time functions, so this change would be rather invasive.
156 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05157 FROM_HERE,
158 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47159 &TestConnectJob::DoConnect,
160 true /* successful */,
161 true /* async */),
162 2);
[email protected]ab838892009-06-30 18:49:05163 return ERR_IO_PENDING;
164 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57165 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47166 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05167 FROM_HERE,
168 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47169 &TestConnectJob::DoConnect,
170 false /* error */,
171 true /* async */),
172 2);
[email protected]ab838892009-06-30 18:49:05173 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57174 case kMockWaitingJob:
175 client_socket_factory_->WaitForSignal(this);
176 waiting_success_ = true;
177 return ERR_IO_PENDING;
178 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47179 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57180 FROM_HERE,
181 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47182 &TestConnectJob::AdvanceLoadState, load_state_),
183 2);
[email protected]5fc08e32009-07-15 17:09:57184 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05185 default:
186 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40187 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05188 return ERR_FAILED;
189 }
190 }
191
[email protected]46451352009-09-01 14:54:21192 void set_load_state(LoadState load_state) { load_state_ = load_state; }
193
[email protected]ab838892009-06-30 18:49:05194 int DoConnect(bool succeed, bool was_async) {
195 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05196 if (succeed) {
197 result = OK;
[email protected]5a05c47a2009-11-02 23:25:19198 socket()->Connect(NULL, NULL);
[email protected]6e713f02009-08-06 02:56:40199 } else {
200 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05201 }
[email protected]2ab05b52009-07-01 23:57:58202
203 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30204 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05205 return result;
206 }
207
[email protected]5fc08e32009-07-15 17:09:57208 void AdvanceLoadState(LoadState state) {
209 int tmp = state;
210 tmp++;
211 state = static_cast<LoadState>(tmp);
212 set_load_state(state);
213 // Post a delayed task so RunAllPending() won't run it.
214 MessageLoop::current()->PostDelayedTask(
215 FROM_HERE,
216 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
217 state),
218 1 /* 1ms delay */);
219 }
220
221 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05222 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57223 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05224 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21225 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05226
227 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
228};
229
[email protected]d80a4322009-08-14 07:07:49230class TestConnectJobFactory
231 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05232 public:
[email protected]5fc08e32009-07-15 17:09:57233 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05234 : job_type_(TestConnectJob::kMockJob),
235 client_socket_factory_(client_socket_factory) {}
236
237 virtual ~TestConnectJobFactory() {}
238
239 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
240
[email protected]974ebd62009-08-03 23:14:34241 void set_timeout_duration(base::TimeDelta timeout_duration) {
242 timeout_duration_ = timeout_duration;
243 }
244
[email protected]ab838892009-06-30 18:49:05245 // ConnectJobFactory methods:
246
247 virtual ConnectJob* NewConnectJob(
248 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49249 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30250 ConnectJob::Delegate* delegate,
251 LoadLog* load_log) const {
[email protected]ab838892009-06-30 18:49:05252 return new TestConnectJob(job_type_,
253 group_name,
254 request,
[email protected]974ebd62009-08-03 23:14:34255 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05256 delegate,
[email protected]fd7b7c92009-08-20 19:38:30257 client_socket_factory_,
258 load_log);
[email protected]ab838892009-06-30 18:49:05259 }
260
261 private:
262 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34263 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57264 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05265
266 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
267};
268
269class TestClientSocketPool : public ClientSocketPool {
270 public:
271 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53272 int max_sockets,
[email protected]ab838892009-06-30 18:49:05273 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16274 base::TimeDelta unused_idle_socket_timeout,
275 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49276 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]9bf28db2009-08-29 01:35:16277 : base_(max_sockets, max_sockets_per_group,
278 unused_idle_socket_timeout, used_idle_socket_timeout,
[email protected]100d5fb92009-12-21 21:08:35279 connect_job_factory, NULL) {}
[email protected]ab838892009-06-30 18:49:05280
281 virtual int RequestSocket(
282 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49283 const void* params,
[email protected]ac790b42009-12-02 04:31:31284 net::RequestPriority priority,
[email protected]ab838892009-06-30 18:49:05285 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46286 CompletionCallback* callback,
287 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49288 return base_.RequestSocket(
289 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05290 }
291
292 virtual void CancelRequest(
293 const std::string& group_name,
294 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49295 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05296 }
297
298 virtual void ReleaseSocket(
299 const std::string& group_name,
300 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49301 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05302 }
303
304 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49305 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05306 }
307
[email protected]d80a4322009-08-14 07:07:49308 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05309
310 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49311 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05312 }
313
314 virtual LoadState GetLoadState(const std::string& group_name,
315 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49316 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05317 }
318
[email protected]d80a4322009-08-14 07:07:49319 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20320
[email protected]974ebd62009-08-03 23:14:34321 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49322 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34323 }
324
[email protected]9bf28db2009-08-29 01:35:16325 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
326
[email protected]ab838892009-06-30 18:49:05327 private:
[email protected]5389bc72009-11-05 23:34:24328 ~TestClientSocketPool() {}
329
[email protected]d80a4322009-08-14 07:07:49330 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05331
332 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
333};
334
[email protected]a937a06d2009-08-19 21:19:24335} // namespace
336
337REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, const void*);
338
339namespace {
340
[email protected]5fc08e32009-07-15 17:09:57341void MockClientSocketFactory::SignalJobs() {
342 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
343 it != waiting_jobs_.end(); ++it) {
344 (*it)->Signal();
345 }
346 waiting_jobs_.clear();
347}
348
[email protected]974ebd62009-08-03 23:14:34349class TestConnectJobDelegate : public ConnectJob::Delegate {
350 public:
351 TestConnectJobDelegate()
352 : have_result_(false), waiting_for_result_(false), result_(OK) {}
353 virtual ~TestConnectJobDelegate() {}
354
355 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
356 result_ = result;
[email protected]6e713f02009-08-06 02:56:40357 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07358 // socket.get() should be NULL iff result != OK
359 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34360 delete job;
361 have_result_ = true;
362 if (waiting_for_result_)
363 MessageLoop::current()->Quit();
364 }
365
366 int WaitForResult() {
367 DCHECK(!waiting_for_result_);
368 while (!have_result_) {
369 waiting_for_result_ = true;
370 MessageLoop::current()->Run();
371 waiting_for_result_ = false;
372 }
373 have_result_ = false; // auto-reset for next callback
374 return result_;
375 }
376
377 private:
378 bool have_result_;
379 bool waiting_for_result_;
380 int result_;
381};
382
[email protected]75439d3b2009-07-23 22:11:17383class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09384 protected:
[email protected]17a0c6c2009-08-04 00:07:04385 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20386
[email protected]211d21722009-07-22 15:48:53387 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16388 CreatePoolWithIdleTimeouts(
389 max_sockets,
390 max_sockets_per_group,
391 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
392 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
393 }
394
395 void CreatePoolWithIdleTimeouts(
396 int max_sockets, int max_sockets_per_group,
397 base::TimeDelta unused_idle_socket_timeout,
398 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20399 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04400 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53401 pool_ = new TestClientSocketPool(max_sockets,
402 max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16403 unused_idle_socket_timeout,
404 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20405 connect_job_factory_);
406 }
[email protected]f6d1d6eb2009-06-24 20:16:09407
[email protected]ac790b42009-12-02 04:31:31408 int StartRequest(const std::string& group_name,
409 net::RequestPriority priority) {
[email protected]a937a06d2009-08-19 21:19:24410 return StartRequestUsingPool<TestClientSocketPool, const void*>(
411 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09412 }
413
414 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47415 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
416 // actually become pending until 2ms after they have been created. In order
417 // to flush all tasks, we need to wait so that we know there are no
418 // soon-to-be-pending tasks waiting.
419 PlatformThread::Sleep(10);
420 MessageLoop::current()->RunAllPending();
421
[email protected]211d21722009-07-22 15:48:53422 // Need to delete |pool_| before we turn late binding back off. We also need
423 // to delete |requests_| because the pool is reference counted and requests
424 // keep reference to it.
425 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57426 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53427 requests_.reset();
428
[email protected]75439d3b2009-07-23 22:11:17429 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09430 }
431
[email protected]f6d1d6eb2009-06-24 20:16:09432 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04433 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20434 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09435};
436
[email protected]a937a06d2009-08-19 21:19:24437// Helper function which explicitly specifies the template parameters, since
438// the compiler will infer (in this case, incorrectly) that NULL is of type int.
439int InitHandle(ClientSocketHandle* handle,
440 const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:31441 net::RequestPriority priority,
[email protected]a937a06d2009-08-19 21:19:24442 CompletionCallback* callback,
443 TestClientSocketPool* pool,
444 LoadLog* load_log) {
445 return handle->Init<const void*, TestClientSocketPool>(
446 group_name, NULL, priority, callback, pool, load_log);
447}
448
[email protected]974ebd62009-08-03 23:14:34449// Even though a timeout is specified, it doesn't time out on a synchronous
450// completion.
451TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
452 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06453 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49454 TestClientSocketPoolBase::Request request(
455 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34456 scoped_ptr<TestConnectJob> job(
457 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12458 "a",
[email protected]974ebd62009-08-03 23:14:34459 request,
460 base::TimeDelta::FromMicroseconds(1),
461 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30462 &client_socket_factory_,
463 NULL));
[email protected]974ebd62009-08-03 23:14:34464 EXPECT_EQ(OK, job->Connect());
465}
466
467TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
468 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06469 ClientSocketHandle ignored;
[email protected]60c4c412009-11-06 19:59:36470 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]d80a4322009-08-14 07:07:49471 TestClientSocketPoolBase::Request request(
472 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34473 // Deleted by TestConnectJobDelegate.
474 TestConnectJob* job =
475 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12476 "a",
[email protected]974ebd62009-08-03 23:14:34477 request,
478 base::TimeDelta::FromMicroseconds(1),
479 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30480 &client_socket_factory_,
481 log);
[email protected]974ebd62009-08-03 23:14:34482 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
483 PlatformThread::Sleep(1);
484 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30485
[email protected]bf6c087a2009-12-21 20:45:10486 EXPECT_EQ(3u, log->entries().size());
[email protected]e9002a92010-01-29 07:10:46487 EXPECT_TRUE(LogContainsBeginEvent(
488 *log, 0, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
489 EXPECT_TRUE(LogContainsEvent(
490 *log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
491 LoadLog::PHASE_NONE));
492 EXPECT_TRUE(LogContainsEndEvent(
493 *log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
[email protected]974ebd62009-08-03 23:14:34494}
495
[email protected]5fc08e32009-07-15 17:09:57496TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53497 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20498
[email protected]f6d1d6eb2009-06-24 20:16:09499 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06500 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:36501 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:24502 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]fd7b7c92009-08-20 19:38:30503 &callback, pool_.get(), log));
[email protected]f6d1d6eb2009-06-24 20:16:09504 EXPECT_TRUE(handle.is_initialized());
505 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09506 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30507
[email protected]bf6c087a2009-12-21 20:45:10508 EXPECT_EQ(4u, log->entries().size());
[email protected]e9002a92010-01-29 07:10:46509 EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_SOCKET_POOL));
510 EXPECT_TRUE(LogContainsBeginEvent(
511 *log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
512 EXPECT_TRUE(LogContainsEndEvent(
513 *log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
514 EXPECT_TRUE(LogContainsEndEvent(*log, 3, LoadLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09515}
516
[email protected]ab838892009-06-30 18:49:05517TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20519
[email protected]ab838892009-06-30 18:49:05520 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]60c4c412009-11-06 19:59:36521 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06522 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21523 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24524 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30525 pool_.get(), log));
526
[email protected]bf6c087a2009-12-21 20:45:10527 EXPECT_EQ(4u, log->entries().size());
[email protected]e9002a92010-01-29 07:10:46528 EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_SOCKET_POOL));
529 EXPECT_TRUE(LogContainsBeginEvent(
530 *log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
531 EXPECT_TRUE(LogContainsEndEvent(
532 *log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
533 EXPECT_TRUE(LogContainsEndEvent(*log, 3, LoadLog::TYPE_SOCKET_POOL));
[email protected]f6d1d6eb2009-06-24 20:16:09534}
535
[email protected]211d21722009-07-22 15:48:53536TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
537 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
538
[email protected]fd7b7c92009-08-20 19:38:30539 // TODO(eroman): Check that the LoadLog contains this event.
540
[email protected]211d21722009-07-22 15:48:53541 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
542 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
543 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
544 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
545
546 EXPECT_EQ(static_cast<int>(requests_.size()),
547 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17548 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53549
550 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
551 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
552 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
553
554 ReleaseAllConnections(KEEP_ALIVE);
555
556 EXPECT_EQ(static_cast<int>(requests_.size()),
557 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17558 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53559
560 EXPECT_EQ(1, GetOrderOfRequest(1));
561 EXPECT_EQ(2, GetOrderOfRequest(2));
562 EXPECT_EQ(3, GetOrderOfRequest(3));
563 EXPECT_EQ(4, GetOrderOfRequest(4));
564 EXPECT_EQ(5, GetOrderOfRequest(5));
565 EXPECT_EQ(6, GetOrderOfRequest(6));
566 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17567
568 // Make sure we test order of all requests made.
569 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53570}
571
572TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
573 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
574
[email protected]fd7b7c92009-08-20 19:38:30575 // TODO(eroman): Check that the LoadLog contains this event.
576
[email protected]211d21722009-07-22 15:48:53577 // Reach all limits: max total sockets, and max sockets per group.
578 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
579 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
580 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
581 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
582
583 EXPECT_EQ(static_cast<int>(requests_.size()),
584 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17585 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53586
587 // Now create a new group and verify that we don't starve it.
588 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
589
590 ReleaseAllConnections(KEEP_ALIVE);
591
592 EXPECT_EQ(static_cast<int>(requests_.size()),
593 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17594 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53595
596 EXPECT_EQ(1, GetOrderOfRequest(1));
597 EXPECT_EQ(2, GetOrderOfRequest(2));
598 EXPECT_EQ(3, GetOrderOfRequest(3));
599 EXPECT_EQ(4, GetOrderOfRequest(4));
600 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17601
602 // Make sure we test order of all requests made.
603 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53604}
605
606TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
607 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
608
[email protected]ac790b42009-12-02 04:31:31609 EXPECT_EQ(OK, StartRequest("b", LOWEST));
610 EXPECT_EQ(OK, StartRequest("a", MEDIUM));
611 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
612 EXPECT_EQ(OK, StartRequest("a", LOWEST));
[email protected]211d21722009-07-22 15:48:53613
614 EXPECT_EQ(static_cast<int>(requests_.size()),
615 client_socket_factory_.allocation_count());
616
[email protected]ac790b42009-12-02 04:31:31617 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", LOWEST));
618 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
619 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53620
621 ReleaseAllConnections(KEEP_ALIVE);
622
623 // We're re-using one socket for group "a", and one for "b".
624 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
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 // First 4 requests don't have to wait, and finish in order.
629 EXPECT_EQ(1, GetOrderOfRequest(1));
630 EXPECT_EQ(2, GetOrderOfRequest(2));
631 EXPECT_EQ(3, GetOrderOfRequest(3));
632 EXPECT_EQ(4, GetOrderOfRequest(4));
633
[email protected]ac790b42009-12-02 04:31:31634 // Request ("b", HIGHEST) has the highest priority, then ("a", MEDIUM),
635 // and then ("c", LOWEST).
[email protected]211d21722009-07-22 15:48:53636 EXPECT_EQ(7, GetOrderOfRequest(5));
637 EXPECT_EQ(6, GetOrderOfRequest(6));
638 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17639
640 // Make sure we test order of all requests made.
641 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53642}
643
644TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
645 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
646
[email protected]ac790b42009-12-02 04:31:31647 EXPECT_EQ(OK, StartRequest("a", LOWEST));
648 EXPECT_EQ(OK, StartRequest("a", LOW));
649 EXPECT_EQ(OK, StartRequest("b", HIGHEST));
650 EXPECT_EQ(OK, StartRequest("b", MEDIUM));
[email protected]211d21722009-07-22 15:48:53651
652 EXPECT_EQ(static_cast<int>(requests_.size()),
653 client_socket_factory_.allocation_count());
654
[email protected]ac790b42009-12-02 04:31:31655 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", MEDIUM));
656 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
657 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", HIGHEST));
[email protected]211d21722009-07-22 15:48:53658
659 ReleaseAllConnections(KEEP_ALIVE);
660
661 // We're re-using one socket for group "a", and one for "b".
662 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
663 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17664 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53665
666 // First 4 requests don't have to wait, and finish in order.
667 EXPECT_EQ(1, GetOrderOfRequest(1));
668 EXPECT_EQ(2, GetOrderOfRequest(2));
669 EXPECT_EQ(3, GetOrderOfRequest(3));
670 EXPECT_EQ(4, GetOrderOfRequest(4));
671
672 // Request ("b", 7) has the highest priority, but we can't make new socket for
673 // group "b", because it has reached the per-group limit. Then we make
674 // socket for ("c", 6), because it has higher priority than ("a", 4),
675 // and we still can't make a socket for group "b".
676 EXPECT_EQ(5, GetOrderOfRequest(5));
677 EXPECT_EQ(6, GetOrderOfRequest(6));
678 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17679
680 // Make sure we test order of all requests made.
681 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53682}
683
684// Make sure that we count connecting sockets against the total limit.
685TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
686 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
687
688 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
689 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
690 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
691
692 // Create one asynchronous request.
693 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
694 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
695
[email protected]6b175382009-10-13 06:47:47696 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
697 // actually become pending until 2ms after they have been created. In order
698 // to flush all tasks, we need to wait so that we know there are no
699 // soon-to-be-pending tasks waiting.
700 PlatformThread::Sleep(10);
701 MessageLoop::current()->RunAllPending();
702
[email protected]211d21722009-07-22 15:48:53703 // The next synchronous request should wait for its turn.
704 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
705 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
706
707 ReleaseAllConnections(KEEP_ALIVE);
708
709 EXPECT_EQ(static_cast<int>(requests_.size()),
710 client_socket_factory_.allocation_count());
711
712 EXPECT_EQ(1, GetOrderOfRequest(1));
713 EXPECT_EQ(2, GetOrderOfRequest(2));
714 EXPECT_EQ(3, GetOrderOfRequest(3));
715 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17716 EXPECT_EQ(5, GetOrderOfRequest(5));
717
718 // Make sure we test order of all requests made.
719 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53720}
721
722// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
723// which tells it to use more expensive, but accurate, group selection
724// algorithm. Make sure it doesn't get stuck in the "on" state.
725TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
726 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
727
728 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
729
730 // Reach group socket limit.
731 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
732 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
733 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
734
735 // Reach total limit, but don't request more sockets.
736 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
737 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
738 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
739
740 // Request one more socket while we are at the maximum sockets limit.
741 // This should flip the may_have_stalled_group flag.
742 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
743 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
744
745 // After releasing first connection for "a", we're still at the
746 // maximum sockets limit, but every group's pending queue is empty,
747 // so we reset the flag.
748 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
749 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
750
751 // Requesting additional socket while at the total limit should
752 // flip the flag back to "on".
753 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
754 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
755
756 // We'll request one more socket to verify that we don't reset the flag
757 // too eagerly.
758 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
759 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
760
761 // We're at the maximum socket limit, and still have one request pending
762 // for "d". Flag should be "on".
763 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
764 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
765
766 // Now every group's pending queue should be empty again.
767 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
768 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
769
770 ReleaseAllConnections(KEEP_ALIVE);
771 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
772}
773
[email protected]ab838892009-06-30 18:49:05774TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53775 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09776
[email protected]c9d6a1d2009-07-14 16:15:20777 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
778 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31779 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
780 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
781 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
782 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
783 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09784
[email protected]c9d6a1d2009-07-14 16:15:20785 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09786
[email protected]c9d6a1d2009-07-14 16:15:20787 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
788 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17789 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09790
[email protected]c9d6a1d2009-07-14 16:15:20791 EXPECT_EQ(1, GetOrderOfRequest(1));
792 EXPECT_EQ(2, GetOrderOfRequest(2));
793 EXPECT_EQ(6, GetOrderOfRequest(3));
794 EXPECT_EQ(4, GetOrderOfRequest(4));
795 EXPECT_EQ(3, GetOrderOfRequest(5));
796 EXPECT_EQ(5, GetOrderOfRequest(6));
797 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17798
799 // Make sure we test order of all requests made.
800 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09801}
802
[email protected]ab838892009-06-30 18:49:05803TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53804 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09805
[email protected]c9d6a1d2009-07-14 16:15:20806 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
807 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
809 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
810 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
811 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
812 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09813
[email protected]c9d6a1d2009-07-14 16:15:20814 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09815
[email protected]c9d6a1d2009-07-14 16:15:20816 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
817 EXPECT_EQ(OK, requests_[i]->WaitForResult());
818
819 EXPECT_EQ(static_cast<int>(requests_.size()),
820 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17821 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09822}
823
824// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05825// The pending connect job will be cancelled and should not call back into
826// ClientSocketPoolBase.
827TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53828 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20829
[email protected]ab838892009-06-30 18:49:05830 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06831 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05832 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24833 InitHandle(req.handle(), "a", kDefaultPriority, &req,
834 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33835 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09836}
837
[email protected]ab838892009-06-30 18:49:05838TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53839 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20840
[email protected]ab838892009-06-30 18:49:05841 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06842 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09843 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06844 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09845
[email protected]ab838892009-06-30 18:49:05846 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24847 InitHandle(&handle, "a", kDefaultPriority, &callback,
848 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09849
850 handle.Reset();
851
852 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05853 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24854 InitHandle(&handle, "a", kDefaultPriority, &callback2,
855 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09856
857 EXPECT_EQ(OK, callback2.WaitForResult());
858 EXPECT_FALSE(callback.have_result());
859
860 handle.Reset();
861}
862
[email protected]ab838892009-06-30 18:49:05863TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53864 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09865
[email protected]c9d6a1d2009-07-14 16:15:20866 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
867 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
[email protected]ac790b42009-12-02 04:31:31868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
871 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
872 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
[email protected]f6d1d6eb2009-06-24 20:16:09873
874 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20875 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33876 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
877 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09878
[email protected]c9d6a1d2009-07-14 16:15:20879 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09880
[email protected]c9d6a1d2009-07-14 16:15:20881 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
882 client_socket_factory_.allocation_count());
883 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17884 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09885
[email protected]c9d6a1d2009-07-14 16:15:20886 EXPECT_EQ(1, GetOrderOfRequest(1));
887 EXPECT_EQ(2, GetOrderOfRequest(2));
888 EXPECT_EQ(5, GetOrderOfRequest(3));
889 EXPECT_EQ(3, GetOrderOfRequest(4));
890 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
891 EXPECT_EQ(4, GetOrderOfRequest(6));
892 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17893
894 // Make sure we test order of all requests made.
895 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09896}
897
898class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
899 public:
[email protected]2ab05b52009-07-01 23:57:58900 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24901 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58902 TestConnectJobFactory* test_connect_job_factory,
903 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09904 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06905 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58906 within_callback_(false),
907 test_connect_job_factory_(test_connect_job_factory),
908 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09909
910 virtual void RunWithParams(const Tuple1<int>& params) {
911 callback_.RunWithParams(params);
912 ASSERT_EQ(OK, params.a);
913
914 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58915 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]5edbf8d2010-01-13 18:44:11916
917 // Don't allow reuse of the socket. Disconnect it and then release it and
918 // run through the MessageLoop once to get it completely released.
919 handle_->socket()->Disconnect();
[email protected]f6d1d6eb2009-06-24 20:16:09920 handle_->Reset();
[email protected]5edbf8d2010-01-13 18:44:11921 {
922 MessageLoop::ScopedNestableTaskAllower nestable(
923 MessageLoop::current());
924 MessageLoop::current()->RunAllPending();
925 }
[email protected]f6d1d6eb2009-06-24 20:16:09926 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47927 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24928 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47929 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
930 NULL);
[email protected]2ab05b52009-07-01 23:57:58931 switch (next_job_type_) {
932 case TestConnectJob::kMockJob:
933 EXPECT_EQ(OK, rv);
934 break;
935 case TestConnectJob::kMockPendingJob:
936 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47937
938 // For pending jobs, wait for new socket to be created. This makes
939 // sure there are no more pending operations nor any unclosed sockets
940 // when the test finishes.
941 // We need to give it a little bit of time to run, so that all the
942 // operations that happen on timers (e.g. cleanup of idle
943 // connections) can execute.
[email protected]5edbf8d2010-01-13 18:44:11944 {
945 MessageLoop::ScopedNestableTaskAllower nestable(
946 MessageLoop::current());
947 PlatformThread::Sleep(10);
948 EXPECT_EQ(OK, next_job_callback.WaitForResult());
949 }
[email protected]2ab05b52009-07-01 23:57:58950 break;
951 default:
952 FAIL() << "Unexpected job type: " << next_job_type_;
953 break;
954 }
[email protected]f6d1d6eb2009-06-24 20:16:09955 }
956 }
957
958 int WaitForResult() {
959 return callback_.WaitForResult();
960 }
961
962 private:
963 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:24964 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09965 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58966 TestConnectJobFactory* const test_connect_job_factory_;
967 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09968 TestCompletionCallback callback_;
969};
970
[email protected]2ab05b52009-07-01 23:57:58971TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53972 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20973
[email protected]0b7648c2009-07-06 20:14:01974 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06975 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58976 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06977 &handle, pool_.get(), connect_job_factory_,
978 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:24979 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
980 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09981 ASSERT_EQ(ERR_IO_PENDING, rv);
982
983 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:58984}
[email protected]f6d1d6eb2009-06-24 20:16:09985
[email protected]2ab05b52009-07-01 23:57:58986TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:53987 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20988
[email protected]0b7648c2009-07-06 20:14:01989 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06990 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58991 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06992 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:24993 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
994 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:58995 ASSERT_EQ(ERR_IO_PENDING, rv);
996
997 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09998}
999
1000// Make sure that pending requests get serviced after active requests get
1001// cancelled.
[email protected]ab838892009-06-30 18:49:051002TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531003 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201004
[email protected]0b7648c2009-07-06 20:14:011005 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091006
[email protected]c9d6a1d2009-07-14 16:15:201007 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1008 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1009 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1010 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1011 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1012 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1013 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091014
[email protected]c9d6a1d2009-07-14 16:15:201015 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1016 // Let's cancel them.
1017 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331018 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1019 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091020 }
1021
[email protected]f6d1d6eb2009-06-24 20:16:091022 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201023 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1024 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331025 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091026 }
1027
[email protected]75439d3b2009-07-23 22:11:171028 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091029}
1030
1031// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051032TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531033 const size_t kMaxSockets = 5;
1034 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201035
[email protected]0b7648c2009-07-06 20:14:011036 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091037
[email protected]211d21722009-07-22 15:48:531038 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1039 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091040
1041 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531042 for (size_t i = 0; i < kNumberOfRequests; ++i)
1043 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091044
[email protected]211d21722009-07-22 15:48:531045 for (size_t i = 0; i < kNumberOfRequests; ++i)
1046 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091047}
1048
[email protected]5fc08e32009-07-15 17:09:571049TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531050 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571051
1052 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1053
[email protected]a512f5982009-08-18 16:01:061054 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241055 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1056 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571057 EXPECT_EQ(ERR_IO_PENDING, rv);
1058
1059 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331060 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571061
[email protected]a937a06d2009-08-19 21:19:241062 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1063 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571064 EXPECT_EQ(ERR_IO_PENDING, rv);
1065 EXPECT_EQ(OK, req.WaitForResult());
1066
[email protected]a6c59f62009-07-29 16:33:331067 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171068 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571069 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1070}
1071
[email protected]2b7523d2009-07-29 20:29:231072// Regression test for http://crbug.com/17985.
1073TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1074 const int kMaxSockets = 3;
1075 const int kMaxSocketsPerGroup = 2;
1076 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1077
[email protected]ac790b42009-12-02 04:31:311078 const RequestPriority kHighPriority = HIGHEST;
[email protected]2b7523d2009-07-29 20:29:231079
1080 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1081 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1082
1083 // This is going to be a pending request in an otherwise empty group.
1084 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1085
1086 // Reach the maximum socket limit.
1087 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1088
1089 // Create a stalled group with high priorities.
1090 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1091 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1092 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1093
1094 // Release the first two sockets from "a", which will make room
1095 // for requests from "c". After that "a" will have no active sockets
1096 // and one pending request.
1097 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1098 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1099
1100 // Closing idle sockets should not get us into trouble, but in the bug
1101 // we were hitting a CHECK here.
1102 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1103 pool_->CloseIdleSockets();
1104 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1105}
1106
[email protected]5fc08e32009-07-15 17:09:571107class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1108 protected:
1109 virtual void SetUp() {
1110 ClientSocketPoolBaseTest::SetUp();
[email protected]5fc08e32009-07-15 17:09:571111 }
1112};
1113
[email protected]4d3b05d2010-01-27 21:27:291114TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531115 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571116
1117 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061118 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361119 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]ac790b42009-12-02 04:31:311120 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571121 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331122 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571123 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331124 EXPECT_TRUE(req.handle()->is_initialized());
1125 EXPECT_TRUE(req.handle()->socket());
1126 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301127
[email protected]bf6c087a2009-12-21 20:45:101128 EXPECT_EQ(6u, log->entries().size());
[email protected]e9002a92010-01-29 07:10:461129 EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_SOCKET_POOL));
1130 EXPECT_TRUE(LogContainsBeginEvent(
1131 *log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1132 EXPECT_TRUE(LogContainsEndEvent(
1133 *log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1134 EXPECT_TRUE(LogContainsBeginEvent(
1135 *log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1136 EXPECT_TRUE(LogContainsEndEvent(
1137 *log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1138 EXPECT_TRUE(LogContainsEndEvent(
1139 *log, 5, LoadLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571140}
1141
[email protected]4d3b05d2010-01-27 21:27:291142TEST_F(ClientSocketPoolBaseTest,
[email protected]5fc08e32009-07-15 17:09:571143 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531144 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571145
1146 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061147 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361148 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571149 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241150 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301151 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331152 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571153 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301154
[email protected]bf6c087a2009-12-21 20:45:101155 EXPECT_EQ(6u, log->entries().size());
[email protected]e9002a92010-01-29 07:10:461156 EXPECT_TRUE(LogContainsBeginEvent(*log, 0, LoadLog::TYPE_SOCKET_POOL));
1157 EXPECT_TRUE(LogContainsBeginEvent(
1158 *log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1159 EXPECT_TRUE(LogContainsEndEvent(
1160 *log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1161 EXPECT_TRUE(LogContainsBeginEvent(
1162 *log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1163 EXPECT_TRUE(LogContainsEndEvent(
1164 *log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1165 EXPECT_TRUE(LogContainsEndEvent(*log, 5, LoadLog::TYPE_SOCKET_POOL));
[email protected]5fc08e32009-07-15 17:09:571166}
1167
[email protected]4d3b05d2010-01-27 21:27:291168TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531169 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571170
1171 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061172 TestSocketRequest req(&request_order_, &completion_count_);
1173 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571174
[email protected]60c4c412009-11-06 19:59:361175 scoped_refptr<LoadLog> log1(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571176 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241177 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301178 pool_.get(), log1));
[email protected]60c4c412009-11-06 19:59:361179 scoped_refptr<LoadLog> log2(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571180 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241181 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301182 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571183
[email protected]a6c59f62009-07-29 16:33:331184 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571185
[email protected]bf6c087a2009-12-21 20:45:101186 EXPECT_EQ(5u, log1->entries().size());
[email protected]e9002a92010-01-29 07:10:461187 EXPECT_TRUE(LogContainsBeginEvent(*log1, 0, LoadLog::TYPE_SOCKET_POOL));
1188 EXPECT_TRUE(LogContainsBeginEvent(
1189 *log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1190 EXPECT_TRUE(LogContainsEndEvent(
1191 *log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1192 EXPECT_TRUE(LogContainsEvent(
1193 *log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE));
1194 EXPECT_TRUE(LogContainsEndEvent(*log1, 4, LoadLog::TYPE_SOCKET_POOL));
[email protected]fd7b7c92009-08-20 19:38:301195
1196 // At this point, request 2 is just waiting for the connect job to finish.
[email protected]bf6c087a2009-12-21 20:45:101197 EXPECT_EQ(2u, log2->entries().size());
[email protected]e9002a92010-01-29 07:10:461198 EXPECT_TRUE(LogContainsBeginEvent(*log2, 0, LoadLog::TYPE_SOCKET_POOL));
1199 EXPECT_TRUE(LogContainsBeginEvent(
1200 *log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
[email protected]fd7b7c92009-08-20 19:38:301201
[email protected]5fc08e32009-07-15 17:09:571202 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331203 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301204
1205 // Now request 2 has actually finished.
[email protected]bf6c087a2009-12-21 20:45:101206 EXPECT_EQ(6u, log2->entries().size());
[email protected]e9002a92010-01-29 07:10:461207 EXPECT_TRUE(LogContainsBeginEvent(*log2, 0, LoadLog::TYPE_SOCKET_POOL));
1208 EXPECT_TRUE(LogContainsBeginEvent(
1209 *log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1210 EXPECT_TRUE(LogContainsEndEvent(
1211 *log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE));
1212 EXPECT_TRUE(LogContainsBeginEvent(
1213 *log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1214 EXPECT_TRUE(LogContainsEndEvent(
1215 *log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB));
1216 EXPECT_TRUE(LogContainsEndEvent(*log2, 5, LoadLog::TYPE_SOCKET_POOL));
[email protected]fd7b7c92009-08-20 19:38:301217
[email protected]5fc08e32009-07-15 17:09:571218}
1219
[email protected]4d3b05d2010-01-27 21:27:291220TEST_F(ClientSocketPoolBaseTest, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341221 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1222
[email protected]17a0c6c2009-08-04 00:07:041223 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1224
[email protected]ac790b42009-12-02 04:31:311225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
1227 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
1228 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
[email protected]974ebd62009-08-03 23:14:341229
1230 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1231 requests_[2]->handle()->Reset();
1232 requests_[3]->handle()->Reset();
1233 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1234
1235 requests_[1]->handle()->Reset();
1236 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1237
1238 requests_[0]->handle()->Reset();
1239 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1240}
1241
[email protected]5fc08e32009-07-15 17:09:571242// When requests and ConnectJobs are not coupled, the request will get serviced
1243// by whatever comes first.
[email protected]4d3b05d2010-01-27 21:27:291244TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531245 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571246
1247 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321248 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571249
[email protected]a512f5982009-08-18 16:01:061250 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241251 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1252 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571253 EXPECT_EQ(ERR_IO_PENDING, rv);
1254 EXPECT_EQ(OK, req1.WaitForResult());
1255
1256 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1257 // without a job.
1258 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1259
[email protected]a512f5982009-08-18 16:01:061260 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241261 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1262 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571263 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061264 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241265 rv = InitHandle(
1266 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571267 EXPECT_EQ(ERR_IO_PENDING, rv);
1268
1269 // Both Requests 2 and 3 are pending. We release socket 1 which should
1270 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331271 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571272 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331273 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571274 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331275 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571276
1277 // Signal job 2, which should service request 3.
1278
1279 client_socket_factory_.SignalJobs();
1280 EXPECT_EQ(OK, req3.WaitForResult());
1281
1282 ASSERT_EQ(3U, request_order_.size());
1283 EXPECT_EQ(&req1, request_order_[0]);
1284 EXPECT_EQ(&req2, request_order_[1]);
1285 EXPECT_EQ(&req3, request_order_[2]);
1286 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1287}
1288
1289// The requests are not coupled to the jobs. So, the requests should finish in
1290// their priority / insertion order.
[email protected]4d3b05d2010-01-27 21:27:291291TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531292 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571293 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321294 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571295
[email protected]a512f5982009-08-18 16:01:061296 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241297 int rv = InitHandle(
1298 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571299 EXPECT_EQ(ERR_IO_PENDING, rv);
1300
[email protected]a512f5982009-08-18 16:01:061301 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241302 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1303 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571304 EXPECT_EQ(ERR_IO_PENDING, rv);
1305
1306 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321307 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571308
[email protected]a512f5982009-08-18 16:01:061309 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241310 rv = InitHandle(
1311 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571312 EXPECT_EQ(ERR_IO_PENDING, rv);
1313
1314 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1315 EXPECT_EQ(OK, req2.WaitForResult());
1316 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1317
1318 ASSERT_EQ(3U, request_order_.size());
1319 EXPECT_EQ(&req1, request_order_[0]);
1320 EXPECT_EQ(&req2, request_order_[1]);
1321 EXPECT_EQ(&req3, request_order_[2]);
1322}
1323
[email protected]4d3b05d2010-01-27 21:27:291324TEST_F(ClientSocketPoolBaseTest, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531325 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571326 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321327 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571328
[email protected]a512f5982009-08-18 16:01:061329 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241330 int rv = InitHandle(
1331 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571332 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331333 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571334
1335 MessageLoop::current()->RunAllPending();
1336
[email protected]a512f5982009-08-18 16:01:061337 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241338 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1339 pool_.get(), 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_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1342 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571343}
1344
[email protected]4d3b05d2010-01-27 21:27:291345TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
[email protected]9bf28db2009-08-29 01:35:161346 CreatePoolWithIdleTimeouts(
1347 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1348 base::TimeDelta(), // Time out unused sockets immediately.
1349 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1350
1351 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1352
1353 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1354
1355 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311356 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161357 EXPECT_EQ(ERR_IO_PENDING, rv);
1358 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1359
1360 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ac790b42009-12-02 04:31:311361 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161362 EXPECT_EQ(ERR_IO_PENDING, rv);
1363 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1364
1365 // Cancel one of the requests. Wait for the other, which will get the first
1366 // job. Release the socket. Run the loop again to make sure the second
1367 // socket is sitting idle and the first one is released (since ReleaseSocket()
1368 // just posts a DoReleaseSocket() task).
1369
1370 req.handle()->Reset();
1371 EXPECT_EQ(OK, req2.WaitForResult());
1372 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471373
1374 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1375 // actually become pending until 2ms after they have been created. In order
1376 // to flush all tasks, we need to wait so that we know there are no
1377 // soon-to-be-pending tasks waiting.
1378 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161379 MessageLoop::current()->RunAllPending();
1380
1381 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041382
[email protected]9bf28db2009-08-29 01:35:161383 // Invoke the idle socket cleanup check. Only one socket should be left, the
1384 // used socket. Request it to make sure that it's used.
1385
1386 pool_->CleanupTimedOutIdleSockets();
[email protected]ac790b42009-12-02 04:31:311387 rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
[email protected]9bf28db2009-08-29 01:35:161388 EXPECT_EQ(OK, rv);
1389 EXPECT_TRUE(req.handle()->is_reused());
1390}
1391
[email protected]4f2abec2010-02-03 18:10:161392// Make sure that we process all pending requests even when we're stalling
1393// because of multiple releasing disconnected sockets.
1394TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
1395 CreatePoolWithIdleTimeouts(
1396 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1397 base::TimeDelta(), // Time out unused sockets immediately.
1398 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1399
1400 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1401
1402 // Startup 4 connect jobs. Two of them will be pending.
1403
1404 TestSocketRequest req(&request_order_, &completion_count_);
1405 int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
1406 EXPECT_EQ(OK, rv);
1407
1408 TestSocketRequest req2(&request_order_, &completion_count_);
1409 rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
1410 EXPECT_EQ(OK, rv);
1411
1412 TestSocketRequest req3(&request_order_, &completion_count_);
1413 rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_.get(), NULL);
1414 EXPECT_EQ(ERR_IO_PENDING, rv);
1415
1416 TestSocketRequest req4(&request_order_, &completion_count_);
1417 rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_.get(), NULL);
1418 EXPECT_EQ(ERR_IO_PENDING, rv);
1419
1420 // Release two disconnected sockets.
1421
1422 req.handle()->socket()->Disconnect();
1423 req.handle()->Reset();
1424 req2.handle()->socket()->Disconnect();
1425 req2.handle()->Reset();
1426
1427 EXPECT_EQ(OK, req3.WaitForResult());
1428 EXPECT_FALSE(req3.handle()->is_reused());
1429 EXPECT_EQ(OK, req4.WaitForResult());
1430 EXPECT_FALSE(req4.handle()->is_reused());
1431}
1432
[email protected]f6d1d6eb2009-06-24 20:16:091433} // namespace
1434
1435} // namespace net