blob: 1aa25c2710cb29fa44fc64cb34a71af6dd892a90 [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"
14#include "net/base/test_completion_callback.h"
15#include "net/socket/client_socket.h"
16#include "net/socket/client_socket_factory.h"
17#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1718#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0919#include "testing/gtest/include/gtest/gtest.h"
20
21namespace net {
22
23namespace {
24
[email protected]211d21722009-07-22 15:48:5325const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2026const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0127const int kDefaultPriority = 5;
28
[email protected]d80a4322009-08-14 07:07:4929typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase;
30
[email protected]f6d1d6eb2009-06-24 20:16:0931class MockClientSocket : public ClientSocket {
32 public:
33 MockClientSocket() : connected_(false) {}
34
[email protected]ab838892009-06-30 18:49:0535 // Socket methods:
36 virtual int Read(
37 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
38 return ERR_UNEXPECTED;
39 }
40
41 virtual int Write(
42 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
43 return ERR_UNEXPECTED;
44 }
[email protected]d3f66572009-09-09 22:38:0445 virtual bool SetReceiveBufferSize(int32 size) { return true; };
46 virtual bool SetSendBufferSize(int32 size) { return true; };
[email protected]ab838892009-06-30 18:49:0547
[email protected]f6d1d6eb2009-06-24 20:16:0948 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0549
[email protected]5a05c47a2009-11-02 23:25:1950 virtual int Connect(CompletionCallback* callback, LoadLog* load_log) {
[email protected]f6d1d6eb2009-06-24 20:16:0951 connected_ = true;
52 return OK;
53 }
[email protected]f6d1d6eb2009-06-24 20:16:0954
[email protected]ab838892009-06-30 18:49:0555 virtual void Disconnect() { connected_ = false; }
56 virtual bool IsConnected() const { return connected_; }
57 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0158
[email protected]ab838892009-06-30 18:49:0559#if defined(OS_LINUX)
60 virtual int GetPeerName(struct sockaddr* /* name */,
61 socklen_t* /* namelen */) {
62 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0963 }
[email protected]ab838892009-06-30 18:49:0564#endif
[email protected]f6d1d6eb2009-06-24 20:16:0965
66 private:
67 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0968
[email protected]ab838892009-06-30 18:49:0569 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0970};
71
[email protected]5fc08e32009-07-15 17:09:5772class TestConnectJob;
73
[email protected]f6d1d6eb2009-06-24 20:16:0974class MockClientSocketFactory : public ClientSocketFactory {
75 public:
[email protected]ab838892009-06-30 18:49:0576 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0977
78 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
79 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0580 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0981 }
82
83 virtual SSLClientSocket* CreateSSLClientSocket(
84 ClientSocket* transport_socket,
85 const std::string& hostname,
86 const SSLConfig& ssl_config) {
87 NOTIMPLEMENTED();
88 return NULL;
89 }
90
[email protected]5fc08e32009-07-15 17:09:5791 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
92 void SignalJobs();
93
[email protected]f6d1d6eb2009-06-24 20:16:0994 int allocation_count() const { return allocation_count_; }
95
[email protected]f6d1d6eb2009-06-24 20:16:0996 private:
97 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5798 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0999};
100
[email protected]ab838892009-06-30 18:49:05101class TestConnectJob : public ConnectJob {
102 public:
103 enum JobType {
104 kMockJob,
105 kMockFailingJob,
106 kMockPendingJob,
107 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57108 kMockWaitingJob,
109 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05110 };
111
112 TestConnectJob(JobType job_type,
113 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49114 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34115 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05116 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30117 MockClientSocketFactory* client_socket_factory,
118 LoadLog* load_log)
119 : ConnectJob(group_name, request.handle(), timeout_duration,
120 delegate, load_log),
[email protected]2ab05b52009-07-01 23:57:58121 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05122 client_socket_factory_(client_socket_factory),
[email protected]46451352009-09-01 14:54:21123 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
124 load_state_(LOAD_STATE_IDLE) {}
[email protected]ab838892009-06-30 18:49:05125
[email protected]974ebd62009-08-03 23:14:34126 void Signal() {
127 DoConnect(waiting_success_, true /* async */);
128 }
129
[email protected]46451352009-09-01 14:54:21130 virtual LoadState GetLoadState() const { return load_state_; }
131
[email protected]974ebd62009-08-03 23:14:34132 private:
[email protected]ab838892009-06-30 18:49:05133 // ConnectJob methods:
134
[email protected]974ebd62009-08-03 23:14:34135 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05136 AddressList ignored;
137 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40138 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05139 switch (job_type_) {
140 case kMockJob:
141 return DoConnect(true /* successful */, false /* sync */);
142 case kMockFailingJob:
143 return DoConnect(false /* error */, false /* sync */);
144 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57145 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47146
147 // Depending on execution timings, posting a delayed task can result
148 // in the task getting executed the at the earliest possible
149 // opportunity or only after returning once from the message loop and
150 // then a second call into the message loop. In order to make behavior
151 // more deterministic, we change the default delay to 2ms. This should
152 // always require us to wait for the second call into the message loop.
153 //
154 // N.B. The correct fix for this and similar timing problems is to
155 // abstract time for the purpose of unittests. Unfortunately, we have
156 // a lot of third-party components that directly call the various
157 // time functions, so this change would be rather invasive.
158 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05159 FROM_HERE,
160 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47161 &TestConnectJob::DoConnect,
162 true /* successful */,
163 true /* async */),
164 2);
[email protected]ab838892009-06-30 18:49:05165 return ERR_IO_PENDING;
166 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57167 set_load_state(LOAD_STATE_CONNECTING);
[email protected]6b175382009-10-13 06:47:47168 MessageLoop::current()->PostDelayedTask(
[email protected]ab838892009-06-30 18:49:05169 FROM_HERE,
170 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47171 &TestConnectJob::DoConnect,
172 false /* error */,
173 true /* async */),
174 2);
[email protected]ab838892009-06-30 18:49:05175 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57176 case kMockWaitingJob:
177 client_socket_factory_->WaitForSignal(this);
178 waiting_success_ = true;
179 return ERR_IO_PENDING;
180 case kMockAdvancingLoadStateJob:
[email protected]6b175382009-10-13 06:47:47181 MessageLoop::current()->PostDelayedTask(
[email protected]5fc08e32009-07-15 17:09:57182 FROM_HERE,
183 method_factory_.NewRunnableMethod(
[email protected]6b175382009-10-13 06:47:47184 &TestConnectJob::AdvanceLoadState, load_state_),
185 2);
[email protected]5fc08e32009-07-15 17:09:57186 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05187 default:
188 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40189 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05190 return ERR_FAILED;
191 }
192 }
193
[email protected]46451352009-09-01 14:54:21194 void set_load_state(LoadState load_state) { load_state_ = load_state; }
195
[email protected]ab838892009-06-30 18:49:05196 int DoConnect(bool succeed, bool was_async) {
197 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05198 if (succeed) {
199 result = OK;
[email protected]5a05c47a2009-11-02 23:25:19200 socket()->Connect(NULL, NULL);
[email protected]6e713f02009-08-06 02:56:40201 } else {
202 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05203 }
[email protected]2ab05b52009-07-01 23:57:58204
205 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30206 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05207 return result;
208 }
209
[email protected]5fc08e32009-07-15 17:09:57210 void AdvanceLoadState(LoadState state) {
211 int tmp = state;
212 tmp++;
213 state = static_cast<LoadState>(tmp);
214 set_load_state(state);
215 // Post a delayed task so RunAllPending() won't run it.
216 MessageLoop::current()->PostDelayedTask(
217 FROM_HERE,
218 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
219 state),
220 1 /* 1ms delay */);
221 }
222
223 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05224 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57225 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05226 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
[email protected]46451352009-09-01 14:54:21227 LoadState load_state_;
[email protected]ab838892009-06-30 18:49:05228
229 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
230};
231
[email protected]d80a4322009-08-14 07:07:49232class TestConnectJobFactory
233 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05234 public:
[email protected]5fc08e32009-07-15 17:09:57235 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05236 : job_type_(TestConnectJob::kMockJob),
237 client_socket_factory_(client_socket_factory) {}
238
239 virtual ~TestConnectJobFactory() {}
240
241 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
242
[email protected]974ebd62009-08-03 23:14:34243 void set_timeout_duration(base::TimeDelta timeout_duration) {
244 timeout_duration_ = timeout_duration;
245 }
246
[email protected]ab838892009-06-30 18:49:05247 // ConnectJobFactory methods:
248
249 virtual ConnectJob* NewConnectJob(
250 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49251 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30252 ConnectJob::Delegate* delegate,
253 LoadLog* load_log) const {
[email protected]ab838892009-06-30 18:49:05254 return new TestConnectJob(job_type_,
255 group_name,
256 request,
[email protected]974ebd62009-08-03 23:14:34257 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05258 delegate,
[email protected]fd7b7c92009-08-20 19:38:30259 client_socket_factory_,
260 load_log);
[email protected]ab838892009-06-30 18:49:05261 }
262
263 private:
264 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34265 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57266 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05267
268 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
269};
270
271class TestClientSocketPool : public ClientSocketPool {
272 public:
273 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53274 int max_sockets,
[email protected]ab838892009-06-30 18:49:05275 int max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16276 base::TimeDelta unused_idle_socket_timeout,
277 base::TimeDelta used_idle_socket_timeout,
[email protected]d80a4322009-08-14 07:07:49278 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
[email protected]9bf28db2009-08-29 01:35:16279 : base_(max_sockets, max_sockets_per_group,
280 unused_idle_socket_timeout, used_idle_socket_timeout,
281 connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05282
283 virtual int RequestSocket(
284 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49285 const void* params,
[email protected]ab838892009-06-30 18:49:05286 int priority,
287 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46288 CompletionCallback* callback,
289 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49290 return base_.RequestSocket(
291 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05292 }
293
294 virtual void CancelRequest(
295 const std::string& group_name,
296 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49297 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05298 }
299
300 virtual void ReleaseSocket(
301 const std::string& group_name,
302 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49303 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05304 }
305
306 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49307 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05308 }
309
[email protected]d80a4322009-08-14 07:07:49310 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05311
312 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49313 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05314 }
315
316 virtual LoadState GetLoadState(const std::string& group_name,
317 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49318 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05319 }
320
[email protected]d80a4322009-08-14 07:07:49321 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20322
[email protected]974ebd62009-08-03 23:14:34323 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49324 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34325 }
326
[email protected]9bf28db2009-08-29 01:35:16327 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
328
[email protected]ab838892009-06-30 18:49:05329 private:
[email protected]5389bc72009-11-05 23:34:24330 ~TestClientSocketPool() {}
331
[email protected]d80a4322009-08-14 07:07:49332 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05333
334 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
335};
336
[email protected]a937a06d2009-08-19 21:19:24337} // namespace
338
339REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, const void*);
340
341namespace {
342
[email protected]5fc08e32009-07-15 17:09:57343void MockClientSocketFactory::SignalJobs() {
344 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
345 it != waiting_jobs_.end(); ++it) {
346 (*it)->Signal();
347 }
348 waiting_jobs_.clear();
349}
350
[email protected]974ebd62009-08-03 23:14:34351class TestConnectJobDelegate : public ConnectJob::Delegate {
352 public:
353 TestConnectJobDelegate()
354 : have_result_(false), waiting_for_result_(false), result_(OK) {}
355 virtual ~TestConnectJobDelegate() {}
356
357 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
358 result_ = result;
[email protected]6e713f02009-08-06 02:56:40359 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
[email protected]9b6fee12009-09-29 18:13:07360 // socket.get() should be NULL iff result != OK
361 EXPECT_EQ(socket.get() == NULL, result != OK);
[email protected]974ebd62009-08-03 23:14:34362 delete job;
363 have_result_ = true;
364 if (waiting_for_result_)
365 MessageLoop::current()->Quit();
366 }
367
368 int WaitForResult() {
369 DCHECK(!waiting_for_result_);
370 while (!have_result_) {
371 waiting_for_result_ = true;
372 MessageLoop::current()->Run();
373 waiting_for_result_ = false;
374 }
375 have_result_ = false; // auto-reset for next callback
376 return result_;
377 }
378
379 private:
380 bool have_result_;
381 bool waiting_for_result_;
382 int result_;
383};
384
[email protected]75439d3b2009-07-23 22:11:17385class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09386 protected:
[email protected]17a0c6c2009-08-04 00:07:04387 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20388
[email protected]211d21722009-07-22 15:48:53389 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]9bf28db2009-08-29 01:35:16390 CreatePoolWithIdleTimeouts(
391 max_sockets,
392 max_sockets_per_group,
393 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout),
394 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout));
395 }
396
397 void CreatePoolWithIdleTimeouts(
398 int max_sockets, int max_sockets_per_group,
399 base::TimeDelta unused_idle_socket_timeout,
400 base::TimeDelta used_idle_socket_timeout) {
[email protected]c9d6a1d2009-07-14 16:15:20401 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04402 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53403 pool_ = new TestClientSocketPool(max_sockets,
404 max_sockets_per_group,
[email protected]9bf28db2009-08-29 01:35:16405 unused_idle_socket_timeout,
406 used_idle_socket_timeout,
[email protected]c9d6a1d2009-07-14 16:15:20407 connect_job_factory_);
408 }
[email protected]f6d1d6eb2009-06-24 20:16:09409
[email protected]75439d3b2009-07-23 22:11:17410 int StartRequest(const std::string& group_name, int priority) {
[email protected]a937a06d2009-08-19 21:19:24411 return StartRequestUsingPool<TestClientSocketPool, const void*>(
412 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09413 }
414
415 virtual void TearDown() {
[email protected]6b175382009-10-13 06:47:47416 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
417 // actually become pending until 2ms after they have been created. In order
418 // to flush all tasks, we need to wait so that we know there are no
419 // soon-to-be-pending tasks waiting.
420 PlatformThread::Sleep(10);
421 MessageLoop::current()->RunAllPending();
422
[email protected]211d21722009-07-22 15:48:53423 // Need to delete |pool_| before we turn late binding back off. We also need
424 // to delete |requests_| because the pool is reference counted and requests
425 // keep reference to it.
426 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57427 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53428 requests_.reset();
429
[email protected]d80a4322009-08-14 07:07:49430 EnableLateBindingOfSockets(false);
[email protected]75439d3b2009-07-23 22:11:17431
432 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09433 }
434
[email protected]f6d1d6eb2009-06-24 20:16:09435 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04436 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20437 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09438};
439
[email protected]a937a06d2009-08-19 21:19:24440// Helper function which explicitly specifies the template parameters, since
441// the compiler will infer (in this case, incorrectly) that NULL is of type int.
442int InitHandle(ClientSocketHandle* handle,
443 const std::string& group_name,
444 int priority,
445 CompletionCallback* callback,
446 TestClientSocketPool* pool,
447 LoadLog* load_log) {
448 return handle->Init<const void*, TestClientSocketPool>(
449 group_name, NULL, priority, callback, pool, load_log);
450}
451
[email protected]974ebd62009-08-03 23:14:34452// Even though a timeout is specified, it doesn't time out on a synchronous
453// completion.
454TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
455 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06456 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49457 TestClientSocketPoolBase::Request request(
458 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34459 scoped_ptr<TestConnectJob> job(
460 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12461 "a",
[email protected]974ebd62009-08-03 23:14:34462 request,
463 base::TimeDelta::FromMicroseconds(1),
464 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30465 &client_socket_factory_,
466 NULL));
[email protected]974ebd62009-08-03 23:14:34467 EXPECT_EQ(OK, job->Connect());
468}
469
470TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
471 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06472 ClientSocketHandle ignored;
[email protected]60c4c412009-11-06 19:59:36473 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]d80a4322009-08-14 07:07:49474 TestClientSocketPoolBase::Request request(
475 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34476 // Deleted by TestConnectJobDelegate.
477 TestConnectJob* job =
478 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12479 "a",
[email protected]974ebd62009-08-03 23:14:34480 request,
481 base::TimeDelta::FromMicroseconds(1),
482 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30483 &client_socket_factory_,
484 log);
[email protected]974ebd62009-08-03 23:14:34485 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
486 PlatformThread::Sleep(1);
487 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30488
489 EXPECT_EQ(3u, log->events().size());
490 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
491 LoadLog::PHASE_BEGIN);
492 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
493 LoadLog::PHASE_NONE);
494 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
495 LoadLog::PHASE_END);
[email protected]974ebd62009-08-03 23:14:34496}
497
[email protected]5fc08e32009-07-15 17:09:57498TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53499 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20500
[email protected]f6d1d6eb2009-06-24 20:16:09501 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06502 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:36503 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:24504 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]fd7b7c92009-08-20 19:38:30505 &callback, pool_.get(), log));
[email protected]f6d1d6eb2009-06-24 20:16:09506 EXPECT_TRUE(handle.is_initialized());
507 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09508 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30509
510 EXPECT_EQ(4u, log->events().size());
511 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
512 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
513 LoadLog::PHASE_BEGIN);
514 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
515 LoadLog::PHASE_END);
516 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09517}
518
[email protected]5fc08e32009-07-15 17:09:57519TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53520 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57521
522 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]60c4c412009-11-06 19:59:36523 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06524 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:30525 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:57526 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:33527 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57528 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33529 EXPECT_TRUE(req.handle()->is_initialized());
530 EXPECT_TRUE(req.handle()->socket());
531 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:30532
533 EXPECT_EQ(4u, log->events().size());
534 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
535 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
536 LoadLog::PHASE_BEGIN);
537 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
538 LoadLog::PHASE_END);
539 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57540}
541
[email protected]ab838892009-06-30 18:49:05542TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53543 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20544
[email protected]ab838892009-06-30 18:49:05545 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]60c4c412009-11-06 19:59:36546 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06547 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21548 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24549 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30550 pool_.get(), log));
551
552 EXPECT_EQ(4u, log->events().size());
553 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
554 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
555 LoadLog::PHASE_BEGIN);
556 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
557 LoadLog::PHASE_END);
558 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09559}
560
[email protected]5fc08e32009-07-15 17:09:57561TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53562 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57563
564 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]60c4c412009-11-06 19:59:36565 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a512f5982009-08-18 16:01:06566 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:57567 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24568 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30569 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:33570 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57571 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30572
573 EXPECT_EQ(4u, log->events().size());
574 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
575 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
576 LoadLog::PHASE_BEGIN);
577 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
578 LoadLog::PHASE_END);
579 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57580}
581
[email protected]211d21722009-07-22 15:48:53582TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
583 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
584
[email protected]fd7b7c92009-08-20 19:38:30585 // TODO(eroman): Check that the LoadLog contains this event.
586
[email protected]211d21722009-07-22 15:48:53587 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
588 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
589 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
590 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
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(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
597 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
598 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
599
600 ReleaseAllConnections(KEEP_ALIVE);
601
602 EXPECT_EQ(static_cast<int>(requests_.size()),
603 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17604 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53605
606 EXPECT_EQ(1, GetOrderOfRequest(1));
607 EXPECT_EQ(2, GetOrderOfRequest(2));
608 EXPECT_EQ(3, GetOrderOfRequest(3));
609 EXPECT_EQ(4, GetOrderOfRequest(4));
610 EXPECT_EQ(5, GetOrderOfRequest(5));
611 EXPECT_EQ(6, GetOrderOfRequest(6));
612 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17613
614 // Make sure we test order of all requests made.
615 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53616}
617
618TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
619 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
620
[email protected]fd7b7c92009-08-20 19:38:30621 // TODO(eroman): Check that the LoadLog contains this event.
622
[email protected]211d21722009-07-22 15:48:53623 // Reach all limits: max total sockets, and max sockets per group.
624 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
625 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
626 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
627 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
628
629 EXPECT_EQ(static_cast<int>(requests_.size()),
630 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17631 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53632
633 // Now create a new group and verify that we don't starve it.
634 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
635
636 ReleaseAllConnections(KEEP_ALIVE);
637
638 EXPECT_EQ(static_cast<int>(requests_.size()),
639 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17640 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53641
642 EXPECT_EQ(1, GetOrderOfRequest(1));
643 EXPECT_EQ(2, GetOrderOfRequest(2));
644 EXPECT_EQ(3, GetOrderOfRequest(3));
645 EXPECT_EQ(4, GetOrderOfRequest(4));
646 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17647
648 // Make sure we test order of all requests made.
649 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53650}
651
652TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
653 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
654
655 EXPECT_EQ(OK, StartRequest("b", 3));
656 EXPECT_EQ(OK, StartRequest("a", 3));
657 EXPECT_EQ(OK, StartRequest("b", 6));
658 EXPECT_EQ(OK, StartRequest("a", 6));
659
660 EXPECT_EQ(static_cast<int>(requests_.size()),
661 client_socket_factory_.allocation_count());
662
663 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 4));
664 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
665 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
666
667 ReleaseAllConnections(KEEP_ALIVE);
668
669 // We're re-using one socket for group "a", and one for "b".
670 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
671 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17672 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53673
674 // First 4 requests don't have to wait, and finish in order.
675 EXPECT_EQ(1, GetOrderOfRequest(1));
676 EXPECT_EQ(2, GetOrderOfRequest(2));
677 EXPECT_EQ(3, GetOrderOfRequest(3));
678 EXPECT_EQ(4, GetOrderOfRequest(4));
679
680 // Request ("b", 7) has the highest priority, then ("a", 5),
681 // and then ("c", 4).
682 EXPECT_EQ(7, GetOrderOfRequest(5));
683 EXPECT_EQ(6, GetOrderOfRequest(6));
684 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17685
686 // Make sure we test order of all requests made.
687 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53688}
689
690TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
691 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
692
693 EXPECT_EQ(OK, StartRequest("a", 3));
694 EXPECT_EQ(OK, StartRequest("a", 6));
695 EXPECT_EQ(OK, StartRequest("b", 3));
696 EXPECT_EQ(OK, StartRequest("b", 6));
697
698 EXPECT_EQ(static_cast<int>(requests_.size()),
699 client_socket_factory_.allocation_count());
700
701 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 6));
702 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
703 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
704
705 ReleaseAllConnections(KEEP_ALIVE);
706
707 // We're re-using one socket for group "a", and one for "b".
708 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
709 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17710 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53711
712 // First 4 requests don't have to wait, and finish in order.
713 EXPECT_EQ(1, GetOrderOfRequest(1));
714 EXPECT_EQ(2, GetOrderOfRequest(2));
715 EXPECT_EQ(3, GetOrderOfRequest(3));
716 EXPECT_EQ(4, GetOrderOfRequest(4));
717
718 // Request ("b", 7) has the highest priority, but we can't make new socket for
719 // group "b", because it has reached the per-group limit. Then we make
720 // socket for ("c", 6), because it has higher priority than ("a", 4),
721 // and we still can't make a socket for group "b".
722 EXPECT_EQ(5, GetOrderOfRequest(5));
723 EXPECT_EQ(6, GetOrderOfRequest(6));
724 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17725
726 // Make sure we test order of all requests made.
727 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53728}
729
730// Make sure that we count connecting sockets against the total limit.
731TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
732 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
733
734 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
735 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
736 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
737
738 // Create one asynchronous request.
739 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
740 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
741
[email protected]6b175382009-10-13 06:47:47742 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
743 // actually become pending until 2ms after they have been created. In order
744 // to flush all tasks, we need to wait so that we know there are no
745 // soon-to-be-pending tasks waiting.
746 PlatformThread::Sleep(10);
747 MessageLoop::current()->RunAllPending();
748
[email protected]211d21722009-07-22 15:48:53749 // The next synchronous request should wait for its turn.
750 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
751 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
752
753 ReleaseAllConnections(KEEP_ALIVE);
754
755 EXPECT_EQ(static_cast<int>(requests_.size()),
756 client_socket_factory_.allocation_count());
757
758 EXPECT_EQ(1, GetOrderOfRequest(1));
759 EXPECT_EQ(2, GetOrderOfRequest(2));
760 EXPECT_EQ(3, GetOrderOfRequest(3));
761 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17762 EXPECT_EQ(5, GetOrderOfRequest(5));
763
764 // Make sure we test order of all requests made.
765 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53766}
767
768// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
769// which tells it to use more expensive, but accurate, group selection
770// algorithm. Make sure it doesn't get stuck in the "on" state.
771TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
772 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
773
774 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
775
776 // Reach group socket limit.
777 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
778 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
779 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
780
781 // Reach total limit, but don't request more sockets.
782 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
783 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
784 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
785
786 // Request one more socket while we are at the maximum sockets limit.
787 // This should flip the may_have_stalled_group flag.
788 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
789 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
790
791 // After releasing first connection for "a", we're still at the
792 // maximum sockets limit, but every group's pending queue is empty,
793 // so we reset the flag.
794 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
795 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
796
797 // Requesting additional socket while at the total limit should
798 // flip the flag back to "on".
799 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
800 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
801
802 // We'll request one more socket to verify that we don't reset the flag
803 // too eagerly.
804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
805 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
806
807 // We're at the maximum socket limit, and still have one request pending
808 // for "d". Flag should be "on".
809 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
810 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
811
812 // Now every group's pending queue should be empty again.
813 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
814 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
815
816 ReleaseAllConnections(KEEP_ALIVE);
817 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
818}
819
[email protected]ab838892009-06-30 18:49:05820TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53821 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09822
[email protected]c9d6a1d2009-07-14 16:15:20823 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
824 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
825 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
826 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
827 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
828 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
829 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09830
[email protected]c9d6a1d2009-07-14 16:15:20831 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09832
[email protected]c9d6a1d2009-07-14 16:15:20833 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
834 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17835 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09836
[email protected]c9d6a1d2009-07-14 16:15:20837 EXPECT_EQ(1, GetOrderOfRequest(1));
838 EXPECT_EQ(2, GetOrderOfRequest(2));
839 EXPECT_EQ(6, GetOrderOfRequest(3));
840 EXPECT_EQ(4, GetOrderOfRequest(4));
841 EXPECT_EQ(3, GetOrderOfRequest(5));
842 EXPECT_EQ(5, GetOrderOfRequest(6));
843 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17844
845 // Make sure we test order of all requests made.
846 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09847}
848
[email protected]ab838892009-06-30 18:49:05849TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09851
[email protected]c9d6a1d2009-07-14 16:15:20852 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
853 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
854 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
855 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
856 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
857 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
858 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09859
[email protected]c9d6a1d2009-07-14 16:15:20860 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09861
[email protected]c9d6a1d2009-07-14 16:15:20862 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
863 EXPECT_EQ(OK, requests_[i]->WaitForResult());
864
865 EXPECT_EQ(static_cast<int>(requests_.size()),
866 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17867 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09868}
869
870// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05871// The pending connect job will be cancelled and should not call back into
872// ClientSocketPoolBase.
873TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53874 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20875
[email protected]ab838892009-06-30 18:49:05876 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06877 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05878 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24879 InitHandle(req.handle(), "a", kDefaultPriority, &req,
880 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33881 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09882}
883
[email protected]ab838892009-06-30 18:49:05884TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53885 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20886
[email protected]ab838892009-06-30 18:49:05887 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06888 TestSocketRequest req(&request_order_, &completion_count_);
889 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09890
[email protected]ab838892009-06-30 18:49:05891 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24892 InitHandle(req.handle(), "a", kDefaultPriority, &req,
893 pool_.get(), NULL));
[email protected]ab838892009-06-30 18:49:05894 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24895 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
896 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09897
[email protected]a6c59f62009-07-29 16:33:33898 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09899
900 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33901 req2.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09902}
903
[email protected]ab838892009-06-30 18:49:05904TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53905 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20906
[email protected]ab838892009-06-30 18:49:05907 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06908 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09909 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06910 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09911
[email protected]ab838892009-06-30 18:49:05912 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24913 InitHandle(&handle, "a", kDefaultPriority, &callback,
914 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09915
916 handle.Reset();
917
918 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05919 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24920 InitHandle(&handle, "a", kDefaultPriority, &callback2,
921 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09922
923 EXPECT_EQ(OK, callback2.WaitForResult());
924 EXPECT_FALSE(callback.have_result());
925
926 handle.Reset();
927}
928
[email protected]ab838892009-06-30 18:49:05929TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53930 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09931
[email protected]c9d6a1d2009-07-14 16:15:20932 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
933 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
934 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
937 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
938 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09939
940 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20941 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33942 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
943 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09944
[email protected]c9d6a1d2009-07-14 16:15:20945 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09946
[email protected]c9d6a1d2009-07-14 16:15:20947 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
948 client_socket_factory_.allocation_count());
949 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17950 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09951
[email protected]c9d6a1d2009-07-14 16:15:20952 EXPECT_EQ(1, GetOrderOfRequest(1));
953 EXPECT_EQ(2, GetOrderOfRequest(2));
954 EXPECT_EQ(5, GetOrderOfRequest(3));
955 EXPECT_EQ(3, GetOrderOfRequest(4));
956 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
957 EXPECT_EQ(4, GetOrderOfRequest(6));
958 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17959
960 // Make sure we test order of all requests made.
961 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09962}
963
964class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
965 public:
[email protected]2ab05b52009-07-01 23:57:58966 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24967 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58968 TestConnectJobFactory* test_connect_job_factory,
969 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09970 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06971 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58972 within_callback_(false),
973 test_connect_job_factory_(test_connect_job_factory),
974 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09975
976 virtual void RunWithParams(const Tuple1<int>& params) {
977 callback_.RunWithParams(params);
978 ASSERT_EQ(OK, params.a);
979
980 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58981 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09982 handle_->Reset();
983 within_callback_ = true;
[email protected]6b175382009-10-13 06:47:47984 TestCompletionCallback next_job_callback;
[email protected]a937a06d2009-08-19 21:19:24985 int rv = InitHandle(
[email protected]6b175382009-10-13 06:47:47986 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
987 NULL);
[email protected]2ab05b52009-07-01 23:57:58988 switch (next_job_type_) {
989 case TestConnectJob::kMockJob:
990 EXPECT_EQ(OK, rv);
991 break;
992 case TestConnectJob::kMockPendingJob:
993 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]6b175382009-10-13 06:47:47994
995 // For pending jobs, wait for new socket to be created. This makes
996 // sure there are no more pending operations nor any unclosed sockets
997 // when the test finishes.
998 // We need to give it a little bit of time to run, so that all the
999 // operations that happen on timers (e.g. cleanup of idle
1000 // connections) can execute.
1001 MessageLoop::current()->SetNestableTasksAllowed(true);
1002 PlatformThread::Sleep(10);
1003 EXPECT_EQ(OK, next_job_callback.WaitForResult());
[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]a937a06d2009-08-19 21:19:241033 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1034 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:091035 ASSERT_EQ(ERR_IO_PENDING, rv);
1036
1037 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:581038 handle.Reset();
1039}
[email protected]f6d1d6eb2009-06-24 20:16:091040
[email protected]2ab05b52009-07-01 23:57:581041TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531042 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201043
[email protected]0b7648c2009-07-06 20:14:011044 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061045 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:581046 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061047 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241048 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
1049 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581050 ASSERT_EQ(ERR_IO_PENDING, rv);
1051
1052 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091053 handle.Reset();
1054}
1055
1056// Make sure that pending requests get serviced after active requests get
1057// cancelled.
[email protected]ab838892009-06-30 18:49:051058TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531059 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201060
[email protected]0b7648c2009-07-06 20:14:011061 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091062
[email protected]c9d6a1d2009-07-14 16:15:201063 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));
1066 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1067 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1068 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1069 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091070
[email protected]c9d6a1d2009-07-14 16:15:201071 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1072 // Let's cancel them.
1073 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331074 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1075 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091076 }
1077
[email protected]f6d1d6eb2009-06-24 20:16:091078 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201079 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1080 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331081 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091082 }
1083
[email protected]75439d3b2009-07-23 22:11:171084 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091085}
1086
1087// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051088TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531089 const size_t kMaxSockets = 5;
1090 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201091
[email protected]0b7648c2009-07-06 20:14:011092 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091093
[email protected]211d21722009-07-22 15:48:531094 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1095 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091096
1097 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531098 for (size_t i = 0; i < kNumberOfRequests; ++i)
1099 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091100
[email protected]211d21722009-07-22 15:48:531101 for (size_t i = 0; i < kNumberOfRequests; ++i)
1102 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091103}
1104
[email protected]5fc08e32009-07-15 17:09:571105TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531106 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571107
1108 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1109
[email protected]a512f5982009-08-18 16:01:061110 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241111 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1112 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571113 EXPECT_EQ(ERR_IO_PENDING, rv);
1114
1115 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331116 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571117
[email protected]a937a06d2009-08-19 21:19:241118 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1119 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571120 EXPECT_EQ(ERR_IO_PENDING, rv);
1121 EXPECT_EQ(OK, req.WaitForResult());
1122
[email protected]a6c59f62009-07-29 16:33:331123 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171124 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571125 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1126}
1127
[email protected]2ab05b52009-07-01 23:57:581128// A pending asynchronous job completes, which will free up a socket slot. The
1129// next job finishes synchronously. The callback for the asynchronous job
1130// should be first though.
1131TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531132 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201133
[email protected]2ab05b52009-07-01 23:57:581134 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:011135 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:581136
1137 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:061138 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241139 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1140 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581141 EXPECT_EQ(ERR_IO_PENDING, rv);
1142
1143 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061144 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241145 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1146 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581147 EXPECT_EQ(ERR_IO_PENDING, rv);
1148
1149 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011150 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581151
1152 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061153 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241154 rv = InitHandle(
1155 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581156 EXPECT_EQ(ERR_IO_PENDING, rv);
1157
1158 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1159 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1160 EXPECT_EQ(OK, req3.WaitForResult());
1161
1162 ASSERT_EQ(3U, request_order_.size());
1163
1164 // After job 1 finishes unsuccessfully, it will try to process the pending
1165 // requests queue, so it starts up job 3 for request 3. This job
1166 // synchronously succeeds, so the request order is 1, 3, 2.
1167 EXPECT_EQ(&req1, request_order_[0]);
1168 EXPECT_EQ(&req2, request_order_[2]);
1169 EXPECT_EQ(&req3, request_order_[1]);
1170}
1171
[email protected]5fc08e32009-07-15 17:09:571172// When a ConnectJob is coupled to a request, even if a free socket becomes
1173// available, the request will be serviced by the ConnectJob.
1174TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531175 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491176 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571177
1178 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321179 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571180
[email protected]a512f5982009-08-18 16:01:061181 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241182 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1183 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571184 EXPECT_EQ(ERR_IO_PENDING, rv);
1185 EXPECT_EQ(OK, req1.WaitForResult());
1186
1187 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1188 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1189
[email protected]a512f5982009-08-18 16:01:061190 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241191 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1192 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571193 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331194 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571195 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1196
1197 // Job 2 is pending. Start request 3 (which has no associated job since it
1198 // will use the idle socket).
1199
[email protected]a512f5982009-08-18 16:01:061200 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241201 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3,
1202 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571203 EXPECT_EQ(OK, rv);
1204
[email protected]a6c59f62009-07-29 16:33:331205 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571206 client_socket_factory_.SignalJobs();
1207 EXPECT_EQ(OK, req2.WaitForResult());
1208
1209 ASSERT_EQ(2U, request_order_.size());
1210 EXPECT_EQ(&req1, request_order_[0]);
1211 EXPECT_EQ(&req2, request_order_[1]);
1212 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1213}
1214
[email protected]2b7523d2009-07-29 20:29:231215// Regression test for http://crbug.com/17985.
1216TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1217 const int kMaxSockets = 3;
1218 const int kMaxSocketsPerGroup = 2;
1219 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1220
1221 const int kHighPriority = kDefaultPriority + 100;
1222
1223 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1224 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1225
1226 // This is going to be a pending request in an otherwise empty group.
1227 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1228
1229 // Reach the maximum socket limit.
1230 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1231
1232 // Create a stalled group with high priorities.
1233 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1234 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1235 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1236
1237 // Release the first two sockets from "a", which will make room
1238 // for requests from "c". After that "a" will have no active sockets
1239 // and one pending request.
1240 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1241 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1242
1243 // Closing idle sockets should not get us into trouble, but in the bug
1244 // we were hitting a CHECK here.
1245 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1246 pool_->CloseIdleSockets();
1247 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1248}
1249
[email protected]5fc08e32009-07-15 17:09:571250class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1251 protected:
1252 virtual void SetUp() {
1253 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491254 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571255 }
1256};
1257
[email protected]6e713f02009-08-06 02:56:401258// Even though a timeout is specified, it doesn't time out on a synchronous
1259// completion.
1260TEST_F(ClientSocketPoolBaseTest_LateBinding,
1261 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1262 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061263 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491264 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401265 scoped_ptr<TestConnectJob> job(
1266 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121267 "a",
[email protected]6e713f02009-08-06 02:56:401268 request,
1269 base::TimeDelta::FromMicroseconds(1),
1270 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301271 &client_socket_factory_,
1272 NULL));
[email protected]6e713f02009-08-06 02:56:401273 EXPECT_EQ(OK, job->Connect());
1274}
1275
1276TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1277 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061278 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491279 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401280 // Deleted by TestConnectJobDelegate.
1281 TestConnectJob* job =
1282 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121283 "a",
[email protected]6e713f02009-08-06 02:56:401284 request,
1285 base::TimeDelta::FromMicroseconds(1),
1286 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301287 &client_socket_factory_,
1288 NULL);
[email protected]6e713f02009-08-06 02:56:401289 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1290 PlatformThread::Sleep(1);
1291 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1292}
1293
[email protected]5fc08e32009-07-15 17:09:571294TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531295 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571296
1297 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061298 ClientSocketHandle handle;
[email protected]60c4c412009-11-06 19:59:361299 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]a937a06d2009-08-19 21:19:241300 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback,
[email protected]fd7b7c92009-08-20 19:38:301301 pool_.get(), log));
[email protected]5fc08e32009-07-15 17:09:571302 EXPECT_TRUE(handle.is_initialized());
1303 EXPECT_TRUE(handle.socket());
1304 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301305
1306 EXPECT_EQ(4u, log->events().size());
1307 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1308 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1309 LoadLog::PHASE_BEGIN);
1310 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1311 LoadLog::PHASE_END);
1312 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571313}
1314
1315TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531316 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571317
1318 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061319 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361320 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]fd7b7c92009-08-20 19:38:301321 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571322 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331323 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571324 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331325 EXPECT_TRUE(req.handle()->is_initialized());
1326 EXPECT_TRUE(req.handle()->socket());
1327 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301328
1329 EXPECT_EQ(6u, log->events().size());
1330 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1331 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1332 LoadLog::PHASE_BEGIN);
1333 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1334 LoadLog::PHASE_END);
1335 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1336 LoadLog::PHASE_BEGIN);
1337 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1338 LoadLog::PHASE_END);
1339 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571340}
1341
1342TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531343 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571344
1345 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061346 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361347 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571348 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:241349 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301350 pool_.get(), log));
1351
1352 EXPECT_EQ(4u, log->events().size());
1353 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1354 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1355 LoadLog::PHASE_BEGIN);
1356 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1357 LoadLog::PHASE_END);
1358 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571359}
1360
1361TEST_F(ClientSocketPoolBaseTest_LateBinding,
1362 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531363 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571364
1365 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061366 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]60c4c412009-11-06 19:59:361367 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571368 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241369 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301370 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331371 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571372 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301373
1374 EXPECT_EQ(6u, log->events().size());
1375 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1376 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1377 LoadLog::PHASE_BEGIN);
1378 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1379 LoadLog::PHASE_END);
1380 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1381 LoadLog::PHASE_BEGIN);
1382 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1383 LoadLog::PHASE_END);
1384 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571385}
1386
1387TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531388 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571389
1390 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1391 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1392 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1393 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1394 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1395 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1396 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1397
1398 ReleaseAllConnections(KEEP_ALIVE);
1399
1400 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1401 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171402 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571403
1404 EXPECT_EQ(1, GetOrderOfRequest(1));
1405 EXPECT_EQ(2, GetOrderOfRequest(2));
1406 EXPECT_EQ(6, GetOrderOfRequest(3));
1407 EXPECT_EQ(4, GetOrderOfRequest(4));
1408 EXPECT_EQ(3, GetOrderOfRequest(5));
1409 EXPECT_EQ(5, GetOrderOfRequest(6));
1410 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171411
1412 // Make sure we test order of all requests made.
1413 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571414}
1415
1416TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531417 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571418
1419 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1420 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1421 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1422 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1423 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1424 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1425 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1426
1427 ReleaseAllConnections(NO_KEEP_ALIVE);
1428
1429 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1430 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1431
1432 EXPECT_EQ(static_cast<int>(requests_.size()),
1433 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171434 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571435}
1436
1437// This test will start up a RequestSocket() and then immediately Cancel() it.
1438// The pending connect job will be cancelled and should not call back into
1439// ClientSocketPoolBase.
1440TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531441 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571442
1443 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061444 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571445 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241446 InitHandle(req.handle(), "a", kDefaultPriority, &req,
1447 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331448 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571449}
1450
1451TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531452 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571453
1454 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061455 TestSocketRequest req(&request_order_, &completion_count_);
1456 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571457
[email protected]60c4c412009-11-06 19:59:361458 scoped_refptr<LoadLog> log1(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571459 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241460 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301461 pool_.get(), log1));
[email protected]60c4c412009-11-06 19:59:361462 scoped_refptr<LoadLog> log2(new LoadLog(LoadLog::kUnbounded));
[email protected]5fc08e32009-07-15 17:09:571463 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241464 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301465 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571466
[email protected]a6c59f62009-07-29 16:33:331467 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571468
[email protected]fd7b7c92009-08-20 19:38:301469 EXPECT_EQ(5u, log1->events().size());
1470 ExpectLogContains(log1, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1471 ExpectLogContains(log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1472 LoadLog::PHASE_BEGIN);
1473 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1474 LoadLog::PHASE_END);
1475 ExpectLogContains(log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
1476 ExpectLogContains(log1, 4, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1477
1478 // At this point, request 2 is just waiting for the connect job to finish.
1479 EXPECT_EQ(2u, log2->events().size());
1480 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1481 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1482 LoadLog::PHASE_BEGIN);
1483
[email protected]5fc08e32009-07-15 17:09:571484 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331485 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301486
1487 // Now request 2 has actually finished.
1488 EXPECT_EQ(6u, log2->events().size());
1489 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1490 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1491 LoadLog::PHASE_BEGIN);
1492 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1493 LoadLog::PHASE_END);
1494 ExpectLogContains(log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1495 LoadLog::PHASE_BEGIN);
1496 ExpectLogContains(log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1497 LoadLog::PHASE_END);
1498 ExpectLogContains(log2, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1499
[email protected]5fc08e32009-07-15 17:09:571500}
1501
1502TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531503 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571504
1505 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061506 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571507 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061508 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571509
1510 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241511 InitHandle(&handle, "a", kDefaultPriority, &callback,
1512 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571513
1514 handle.Reset();
1515
1516 TestCompletionCallback callback2;
1517 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241518 InitHandle(&handle, "a", kDefaultPriority, &callback2,
1519 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571520
1521 EXPECT_EQ(OK, callback2.WaitForResult());
1522 EXPECT_FALSE(callback.have_result());
1523
1524 handle.Reset();
1525}
1526
1527TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531528 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571529
1530 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1531 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1532 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1533 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1534 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1535 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1536 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1537
1538 // Cancel a request.
1539 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331540 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1541 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571542
1543 ReleaseAllConnections(KEEP_ALIVE);
1544
1545 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1546 client_socket_factory_.allocation_count());
1547 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171548 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571549
1550 EXPECT_EQ(1, GetOrderOfRequest(1));
1551 EXPECT_EQ(2, GetOrderOfRequest(2));
1552 EXPECT_EQ(5, GetOrderOfRequest(3));
1553 EXPECT_EQ(3, GetOrderOfRequest(4));
1554 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1555 EXPECT_EQ(4, GetOrderOfRequest(6));
1556 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171557
1558 // Make sure we test order of all requests made.
1559 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571560}
1561
[email protected]974ebd62009-08-03 23:14:341562TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341563 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1564
[email protected]17a0c6c2009-08-04 00:07:041565 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1566
[email protected]974ebd62009-08-03 23:14:341567 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1568 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1569 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1570 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1571
1572 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1573 requests_[2]->handle()->Reset();
1574 requests_[3]->handle()->Reset();
1575 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1576
1577 requests_[1]->handle()->Reset();
1578 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1579
1580 requests_[0]->handle()->Reset();
1581 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1582}
1583
[email protected]5fc08e32009-07-15 17:09:571584TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531585 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571586
1587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061588 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571589 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061590 &handle, pool_.get(), connect_job_factory_,
1591 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241592 int rv = InitHandle(
1593 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571594 ASSERT_EQ(ERR_IO_PENDING, rv);
1595
1596 EXPECT_EQ(OK, callback.WaitForResult());
1597 handle.Reset();
1598}
1599
1600TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531601 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571602
1603 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061604 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571605 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061606 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241607 int rv = InitHandle(
1608 &handle, "a", kDefaultPriority, &callback,
[email protected]a512f5982009-08-18 16:01:061609 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571610 ASSERT_EQ(ERR_IO_PENDING, rv);
1611
1612 EXPECT_EQ(OK, callback.WaitForResult());
1613 handle.Reset();
1614}
1615
1616// Make sure that pending requests get serviced after active requests get
1617// cancelled.
1618TEST_F(ClientSocketPoolBaseTest_LateBinding,
1619 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531620 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571621
1622 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1623
1624 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1625 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1626 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1627 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1628 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1629 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1630 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1631
1632 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1633 // Let's cancel them.
1634 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331635 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1636 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571637 }
1638
1639 // Let's wait for the rest to complete now.
1640 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1641 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331642 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571643 }
1644
[email protected]75439d3b2009-07-23 22:11:171645 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571646}
1647
1648// Make sure that pending requests get serviced after active requests fail.
1649TEST_F(ClientSocketPoolBaseTest_LateBinding,
1650 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531651 const int kMaxSockets = 5;
1652 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571653
1654 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1655
[email protected]211d21722009-07-22 15:48:531656 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1657 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571658
1659 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531660 for (int i = 0; i < kNumberOfRequests; ++i)
1661 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571662
[email protected]211d21722009-07-22 15:48:531663 for (int i = 0; i < kNumberOfRequests; ++i)
1664 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571665}
1666
1667TEST_F(ClientSocketPoolBaseTest_LateBinding,
1668 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531669 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571670
1671 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1672
[email protected]a512f5982009-08-18 16:01:061673 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241674 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1675 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571676 EXPECT_EQ(ERR_IO_PENDING, rv);
1677
1678 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331679 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571680
[email protected]a937a06d2009-08-19 21:19:241681 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1682 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571683 EXPECT_EQ(ERR_IO_PENDING, rv);
1684 EXPECT_EQ(OK, req.WaitForResult());
1685
[email protected]a6c59f62009-07-29 16:33:331686 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171687 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571688 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1689}
1690
1691// When requests and ConnectJobs are not coupled, the request will get serviced
1692// by whatever comes first.
1693TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531694 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571695
1696 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321697 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571698
[email protected]a512f5982009-08-18 16:01:061699 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241700 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1701 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571702 EXPECT_EQ(ERR_IO_PENDING, rv);
1703 EXPECT_EQ(OK, req1.WaitForResult());
1704
1705 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1706 // without a job.
1707 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1708
[email protected]a512f5982009-08-18 16:01:061709 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241710 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1711 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571712 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061713 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241714 rv = InitHandle(
1715 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571716 EXPECT_EQ(ERR_IO_PENDING, rv);
1717
1718 // Both Requests 2 and 3 are pending. We release socket 1 which should
1719 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331720 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571721 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331722 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571723 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331724 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571725
1726 // Signal job 2, which should service request 3.
1727
1728 client_socket_factory_.SignalJobs();
1729 EXPECT_EQ(OK, req3.WaitForResult());
1730
1731 ASSERT_EQ(3U, request_order_.size());
1732 EXPECT_EQ(&req1, request_order_[0]);
1733 EXPECT_EQ(&req2, request_order_[1]);
1734 EXPECT_EQ(&req3, request_order_[2]);
1735 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1736}
1737
1738// The requests are not coupled to the jobs. So, the requests should finish in
1739// their priority / insertion order.
1740TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531741 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571742 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321743 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571744
[email protected]a512f5982009-08-18 16:01:061745 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241746 int rv = InitHandle(
1747 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571748 EXPECT_EQ(ERR_IO_PENDING, rv);
1749
[email protected]a512f5982009-08-18 16:01:061750 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241751 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1752 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571753 EXPECT_EQ(ERR_IO_PENDING, rv);
1754
1755 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321756 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571757
[email protected]a512f5982009-08-18 16:01:061758 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241759 rv = InitHandle(
1760 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571761 EXPECT_EQ(ERR_IO_PENDING, rv);
1762
1763 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1764 EXPECT_EQ(OK, req2.WaitForResult());
1765 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1766
1767 ASSERT_EQ(3U, request_order_.size());
1768 EXPECT_EQ(&req1, request_order_[0]);
1769 EXPECT_EQ(&req2, request_order_[1]);
1770 EXPECT_EQ(&req3, request_order_[2]);
1771}
1772
[email protected]f0109a7d2009-07-16 00:09:521773TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531774 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571775 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321776 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571777
[email protected]a512f5982009-08-18 16:01:061778 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241779 int rv = InitHandle(
1780 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571781 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331782 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571783
1784 MessageLoop::current()->RunAllPending();
1785
[email protected]a512f5982009-08-18 16:01:061786 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241787 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1788 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331790 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1791 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571792}
1793
[email protected]2b7523d2009-07-29 20:29:231794// Regression test for http://crbug.com/17985.
1795TEST_F(ClientSocketPoolBaseTest_LateBinding,
1796 GroupWithPendingRequestsIsNotEmpty) {
1797 const int kMaxSockets = 3;
1798 const int kMaxSocketsPerGroup = 2;
1799 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1800
1801 const int kHighPriority = kDefaultPriority + 100;
1802
1803 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1804 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1805
1806 // This is going to be a pending request in an otherwise empty group.
1807 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1808
1809 // Reach the maximum socket limit.
1810 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1811
1812 // Create a stalled group with high priorities.
1813 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1814 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1815 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1816
1817 // Release the first two sockets from "a", which will make room
1818 // for requests from "c". After that "a" will have no active sockets
1819 // and one pending request.
1820 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1821 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1822
1823 // Closing idle sockets should not get us into trouble, but in the bug
1824 // we were hitting a CHECK here.
1825 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1826 pool_->CloseIdleSockets();
1827 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1828}
1829
[email protected]9bf28db2009-08-29 01:35:161830TEST_F(ClientSocketPoolBaseTest_LateBinding, CleanupTimedOutIdleSockets) {
1831 CreatePoolWithIdleTimeouts(
1832 kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
1833 base::TimeDelta(), // Time out unused sockets immediately.
1834 base::TimeDelta::FromDays(1)); // Don't time out used sockets.
1835
1836 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1837
1838 // Startup two mock pending connect jobs, which will sit in the MessageLoop.
1839
1840 TestSocketRequest req(&request_order_, &completion_count_);
1841 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL);
1842 EXPECT_EQ(ERR_IO_PENDING, rv);
1843 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
1844
1845 TestSocketRequest req2(&request_order_, &completion_count_);
1846 rv = InitHandle(req2.handle(), "a", 0, &req2, pool_.get(), NULL);
1847 EXPECT_EQ(ERR_IO_PENDING, rv);
1848 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle()));
1849
1850 // Cancel one of the requests. Wait for the other, which will get the first
1851 // job. Release the socket. Run the loop again to make sure the second
1852 // socket is sitting idle and the first one is released (since ReleaseSocket()
1853 // just posts a DoReleaseSocket() task).
1854
1855 req.handle()->Reset();
1856 EXPECT_EQ(OK, req2.WaitForResult());
1857 req2.handle()->Reset();
[email protected]6b175382009-10-13 06:47:471858
1859 // We post all of our delayed tasks with a 2ms delay. I.e. they don't
1860 // actually become pending until 2ms after they have been created. In order
1861 // to flush all tasks, we need to wait so that we know there are no
1862 // soon-to-be-pending tasks waiting.
1863 PlatformThread::Sleep(10);
[email protected]9bf28db2009-08-29 01:35:161864 MessageLoop::current()->RunAllPending();
1865
1866 ASSERT_EQ(2, pool_->IdleSocketCount());
[email protected]d3f66572009-09-09 22:38:041867
[email protected]9bf28db2009-08-29 01:35:161868 // Invoke the idle socket cleanup check. Only one socket should be left, the
1869 // used socket. Request it to make sure that it's used.
1870
1871 pool_->CleanupTimedOutIdleSockets();
1872 rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL);
1873 EXPECT_EQ(OK, rv);
1874 EXPECT_TRUE(req.handle()->is_reused());
1875}
1876
[email protected]f6d1d6eb2009-06-24 20:16:091877} // namespace
1878
1879} // namespace net