blob: fff686957972f739011d3701fab86a268bf0126b [file] [log] [blame]
[email protected]f6d1d6eb2009-06-24 20:16:091// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// 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 }
45
[email protected]f6d1d6eb2009-06-24 20:16:0946 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0547
[email protected]f6d1d6eb2009-06-24 20:16:0948 virtual int Connect(CompletionCallback* callback) {
49 connected_ = true;
50 return OK;
51 }
[email protected]f6d1d6eb2009-06-24 20:16:0952
[email protected]ab838892009-06-30 18:49:0553 virtual void Disconnect() { connected_ = false; }
54 virtual bool IsConnected() const { return connected_; }
55 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0156
[email protected]ab838892009-06-30 18:49:0557#if defined(OS_LINUX)
58 virtual int GetPeerName(struct sockaddr* /* name */,
59 socklen_t* /* namelen */) {
60 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0961 }
[email protected]ab838892009-06-30 18:49:0562#endif
[email protected]f6d1d6eb2009-06-24 20:16:0963
64 private:
65 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0966
[email protected]ab838892009-06-30 18:49:0567 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0968};
69
[email protected]5fc08e32009-07-15 17:09:5770class TestConnectJob;
71
[email protected]f6d1d6eb2009-06-24 20:16:0972class MockClientSocketFactory : public ClientSocketFactory {
73 public:
[email protected]ab838892009-06-30 18:49:0574 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0975
76 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
77 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0578 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0979 }
80
81 virtual SSLClientSocket* CreateSSLClientSocket(
82 ClientSocket* transport_socket,
83 const std::string& hostname,
84 const SSLConfig& ssl_config) {
85 NOTIMPLEMENTED();
86 return NULL;
87 }
88
[email protected]5fc08e32009-07-15 17:09:5789 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
90 void SignalJobs();
91
[email protected]f6d1d6eb2009-06-24 20:16:0992 int allocation_count() const { return allocation_count_; }
93
[email protected]f6d1d6eb2009-06-24 20:16:0994 private:
95 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5796 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0997};
98
[email protected]ab838892009-06-30 18:49:0599class TestConnectJob : public ConnectJob {
100 public:
101 enum JobType {
102 kMockJob,
103 kMockFailingJob,
104 kMockPendingJob,
105 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57106 kMockWaitingJob,
107 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05108 };
109
110 TestConnectJob(JobType job_type,
111 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49112 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34113 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05114 ConnectJob::Delegate* delegate,
[email protected]fd7b7c92009-08-20 19:38:30115 MockClientSocketFactory* client_socket_factory,
116 LoadLog* load_log)
117 : ConnectJob(group_name, request.handle(), timeout_duration,
118 delegate, load_log),
[email protected]2ab05b52009-07-01 23:57:58119 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05120 client_socket_factory_(client_socket_factory),
[email protected]ab838892009-06-30 18:49:05121 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
122
[email protected]974ebd62009-08-03 23:14:34123 void Signal() {
124 DoConnect(waiting_success_, true /* async */);
125 }
126
127 private:
[email protected]ab838892009-06-30 18:49:05128 // ConnectJob methods:
129
[email protected]974ebd62009-08-03 23:14:34130 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05131 AddressList ignored;
132 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40133 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05134 switch (job_type_) {
135 case kMockJob:
136 return DoConnect(true /* successful */, false /* sync */);
137 case kMockFailingJob:
138 return DoConnect(false /* error */, false /* sync */);
139 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57140 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05141 MessageLoop::current()->PostTask(
142 FROM_HERE,
143 method_factory_.NewRunnableMethod(
144 &TestConnectJob::DoConnect,
145 true /* successful */,
146 true /* async */));
147 return ERR_IO_PENDING;
148 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57149 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05150 MessageLoop::current()->PostTask(
151 FROM_HERE,
152 method_factory_.NewRunnableMethod(
153 &TestConnectJob::DoConnect,
154 false /* error */,
155 true /* async */));
156 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57157 case kMockWaitingJob:
158 client_socket_factory_->WaitForSignal(this);
159 waiting_success_ = true;
160 return ERR_IO_PENDING;
161 case kMockAdvancingLoadStateJob:
162 MessageLoop::current()->PostTask(
163 FROM_HERE,
164 method_factory_.NewRunnableMethod(
165 &TestConnectJob::AdvanceLoadState, load_state()));
166 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05167 default:
168 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40169 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05170 return ERR_FAILED;
171 }
172 }
173
[email protected]ab838892009-06-30 18:49:05174 int DoConnect(bool succeed, bool was_async) {
175 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05176 if (succeed) {
177 result = OK;
[email protected]2ab05b52009-07-01 23:57:58178 socket()->Connect(NULL);
[email protected]6e713f02009-08-06 02:56:40179 } else {
180 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05181 }
[email protected]2ab05b52009-07-01 23:57:58182
183 if (was_async)
[email protected]fd7b7c92009-08-20 19:38:30184 NotifyDelegateOfCompletion(result);
[email protected]ab838892009-06-30 18:49:05185 return result;
186 }
187
[email protected]5fc08e32009-07-15 17:09:57188 void AdvanceLoadState(LoadState state) {
189 int tmp = state;
190 tmp++;
191 state = static_cast<LoadState>(tmp);
192 set_load_state(state);
193 // Post a delayed task so RunAllPending() won't run it.
194 MessageLoop::current()->PostDelayedTask(
195 FROM_HERE,
196 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
197 state),
198 1 /* 1ms delay */);
199 }
200
201 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05202 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57203 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05204 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
205
206 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
207};
208
[email protected]d80a4322009-08-14 07:07:49209class TestConnectJobFactory
210 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05211 public:
[email protected]5fc08e32009-07-15 17:09:57212 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05213 : job_type_(TestConnectJob::kMockJob),
214 client_socket_factory_(client_socket_factory) {}
215
216 virtual ~TestConnectJobFactory() {}
217
218 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
219
[email protected]974ebd62009-08-03 23:14:34220 void set_timeout_duration(base::TimeDelta timeout_duration) {
221 timeout_duration_ = timeout_duration;
222 }
223
[email protected]ab838892009-06-30 18:49:05224 // ConnectJobFactory methods:
225
226 virtual ConnectJob* NewConnectJob(
227 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49228 const TestClientSocketPoolBase::Request& request,
[email protected]fd7b7c92009-08-20 19:38:30229 ConnectJob::Delegate* delegate,
230 LoadLog* load_log) const {
[email protected]ab838892009-06-30 18:49:05231 return new TestConnectJob(job_type_,
232 group_name,
233 request,
[email protected]974ebd62009-08-03 23:14:34234 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05235 delegate,
[email protected]fd7b7c92009-08-20 19:38:30236 client_socket_factory_,
237 load_log);
[email protected]ab838892009-06-30 18:49:05238 }
239
240 private:
241 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34242 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57243 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05244
245 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
246};
247
248class TestClientSocketPool : public ClientSocketPool {
249 public:
250 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53251 int max_sockets,
[email protected]ab838892009-06-30 18:49:05252 int max_sockets_per_group,
[email protected]d80a4322009-08-14 07:07:49253 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
254 : base_(max_sockets, max_sockets_per_group, connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05255
256 virtual int RequestSocket(
257 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49258 const void* params,
[email protected]ab838892009-06-30 18:49:05259 int priority,
260 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46261 CompletionCallback* callback,
262 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49263 return base_.RequestSocket(
264 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05265 }
266
267 virtual void CancelRequest(
268 const std::string& group_name,
269 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49270 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05271 }
272
273 virtual void ReleaseSocket(
274 const std::string& group_name,
275 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49276 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05277 }
278
279 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49280 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05281 }
282
[email protected]d80a4322009-08-14 07:07:49283 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05284
285 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49286 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05287 }
288
289 virtual LoadState GetLoadState(const std::string& group_name,
290 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49291 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05292 }
293
[email protected]d80a4322009-08-14 07:07:49294 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20295
[email protected]974ebd62009-08-03 23:14:34296 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49297 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34298 }
299
[email protected]ab838892009-06-30 18:49:05300 private:
[email protected]d80a4322009-08-14 07:07:49301 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05302
303 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
304};
305
[email protected]a937a06d2009-08-19 21:19:24306} // namespace
307
308REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, const void*);
309
310namespace {
311
[email protected]5fc08e32009-07-15 17:09:57312void MockClientSocketFactory::SignalJobs() {
313 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
314 it != waiting_jobs_.end(); ++it) {
315 (*it)->Signal();
316 }
317 waiting_jobs_.clear();
318}
319
[email protected]974ebd62009-08-03 23:14:34320class TestConnectJobDelegate : public ConnectJob::Delegate {
321 public:
322 TestConnectJobDelegate()
323 : have_result_(false), waiting_for_result_(false), result_(OK) {}
324 virtual ~TestConnectJobDelegate() {}
325
326 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
327 result_ = result;
[email protected]6e713f02009-08-06 02:56:40328 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
329 if (result == OK) {
330 EXPECT_TRUE(socket.get() != NULL);
331 } else {
332 EXPECT_EQ(NULL, socket.get());
333 }
[email protected]974ebd62009-08-03 23:14:34334 delete job;
335 have_result_ = true;
336 if (waiting_for_result_)
337 MessageLoop::current()->Quit();
338 }
339
340 int WaitForResult() {
341 DCHECK(!waiting_for_result_);
342 while (!have_result_) {
343 waiting_for_result_ = true;
344 MessageLoop::current()->Run();
345 waiting_for_result_ = false;
346 }
347 have_result_ = false; // auto-reset for next callback
348 return result_;
349 }
350
351 private:
352 bool have_result_;
353 bool waiting_for_result_;
354 int result_;
355};
356
[email protected]75439d3b2009-07-23 22:11:17357class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09358 protected:
[email protected]17a0c6c2009-08-04 00:07:04359 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20360
[email protected]211d21722009-07-22 15:48:53361 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]c9d6a1d2009-07-14 16:15:20362 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04363 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53364 pool_ = new TestClientSocketPool(max_sockets,
365 max_sockets_per_group,
[email protected]c9d6a1d2009-07-14 16:15:20366 connect_job_factory_);
367 }
[email protected]f6d1d6eb2009-06-24 20:16:09368
[email protected]75439d3b2009-07-23 22:11:17369 int StartRequest(const std::string& group_name, int priority) {
[email protected]a937a06d2009-08-19 21:19:24370 return StartRequestUsingPool<TestClientSocketPool, const void*>(
371 pool_.get(), group_name, priority, NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09372 }
373
374 virtual void TearDown() {
[email protected]211d21722009-07-22 15:48:53375 // Need to delete |pool_| before we turn late binding back off. We also need
376 // to delete |requests_| because the pool is reference counted and requests
377 // keep reference to it.
378 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57379 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53380 requests_.reset();
381
[email protected]d80a4322009-08-14 07:07:49382 EnableLateBindingOfSockets(false);
[email protected]75439d3b2009-07-23 22:11:17383
384 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09385 }
386
[email protected]f6d1d6eb2009-06-24 20:16:09387 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04388 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20389 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09390};
391
[email protected]a937a06d2009-08-19 21:19:24392// Helper function which explicitly specifies the template parameters, since
393// the compiler will infer (in this case, incorrectly) that NULL is of type int.
394int InitHandle(ClientSocketHandle* handle,
395 const std::string& group_name,
396 int priority,
397 CompletionCallback* callback,
398 TestClientSocketPool* pool,
399 LoadLog* load_log) {
400 return handle->Init<const void*, TestClientSocketPool>(
401 group_name, NULL, priority, callback, pool, load_log);
402}
403
[email protected]974ebd62009-08-03 23:14:34404// Even though a timeout is specified, it doesn't time out on a synchronous
405// completion.
406TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
407 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06408 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49409 TestClientSocketPoolBase::Request request(
410 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34411 scoped_ptr<TestConnectJob> job(
412 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12413 "a",
[email protected]974ebd62009-08-03 23:14:34414 request,
415 base::TimeDelta::FromMicroseconds(1),
416 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30417 &client_socket_factory_,
418 NULL));
[email protected]974ebd62009-08-03 23:14:34419 EXPECT_EQ(OK, job->Connect());
420}
421
422TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
423 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06424 ClientSocketHandle ignored;
[email protected]fd7b7c92009-08-20 19:38:30425 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]d80a4322009-08-14 07:07:49426 TestClientSocketPoolBase::Request request(
427 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34428 // Deleted by TestConnectJobDelegate.
429 TestConnectJob* job =
430 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12431 "a",
[email protected]974ebd62009-08-03 23:14:34432 request,
433 base::TimeDelta::FromMicroseconds(1),
434 &delegate,
[email protected]fd7b7c92009-08-20 19:38:30435 &client_socket_factory_,
436 log);
[email protected]974ebd62009-08-03 23:14:34437 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
438 PlatformThread::Sleep(1);
439 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30440
441 EXPECT_EQ(3u, log->events().size());
442 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
443 LoadLog::PHASE_BEGIN);
444 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT,
445 LoadLog::PHASE_NONE);
446 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
447 LoadLog::PHASE_END);
[email protected]974ebd62009-08-03 23:14:34448}
449
[email protected]5fc08e32009-07-15 17:09:57450TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53451 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20452
[email protected]f6d1d6eb2009-06-24 20:16:09453 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06454 ClientSocketHandle handle;
[email protected]fd7b7c92009-08-20 19:38:30455 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a937a06d2009-08-19 21:19:24456 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority,
[email protected]fd7b7c92009-08-20 19:38:30457 &callback, pool_.get(), log));
[email protected]f6d1d6eb2009-06-24 20:16:09458 EXPECT_TRUE(handle.is_initialized());
459 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09460 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:30461
462 EXPECT_EQ(4u, log->events().size());
463 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
464 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
465 LoadLog::PHASE_BEGIN);
466 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
467 LoadLog::PHASE_END);
468 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09469}
470
[email protected]5fc08e32009-07-15 17:09:57471TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53472 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57473
474 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]fd7b7c92009-08-20 19:38:30475 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06476 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:30477 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:57478 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:33479 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57480 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33481 EXPECT_TRUE(req.handle()->is_initialized());
482 EXPECT_TRUE(req.handle()->socket());
483 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:30484
485 EXPECT_EQ(4u, log->events().size());
486 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
487 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
488 LoadLog::PHASE_BEGIN);
489 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
490 LoadLog::PHASE_END);
491 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57492}
493
[email protected]ab838892009-06-30 18:49:05494TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53495 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20496
[email protected]ab838892009-06-30 18:49:05497 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]fd7b7c92009-08-20 19:38:30498 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06499 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21500 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:24501 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30502 pool_.get(), log));
503
504 EXPECT_EQ(4u, log->events().size());
505 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
506 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
507 LoadLog::PHASE_BEGIN);
508 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
509 LoadLog::PHASE_END);
510 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]f6d1d6eb2009-06-24 20:16:09511}
512
[email protected]5fc08e32009-07-15 17:09:57513TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53514 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57515
516 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]fd7b7c92009-08-20 19:38:30517 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a512f5982009-08-18 16:01:06518 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:57519 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24520 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:30521 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:33522 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57523 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:30524
525 EXPECT_EQ(4u, log->events().size());
526 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
527 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
528 LoadLog::PHASE_BEGIN);
529 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
530 LoadLog::PHASE_END);
531 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:57532}
533
[email protected]211d21722009-07-22 15:48:53534TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
535 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
536
[email protected]fd7b7c92009-08-20 19:38:30537 // TODO(eroman): Check that the LoadLog contains this event.
538
[email protected]211d21722009-07-22 15:48:53539 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
540 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
541 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
542 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
543
544 EXPECT_EQ(static_cast<int>(requests_.size()),
545 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17546 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53547
548 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
549 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
550 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
551
552 ReleaseAllConnections(KEEP_ALIVE);
553
554 EXPECT_EQ(static_cast<int>(requests_.size()),
555 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17556 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53557
558 EXPECT_EQ(1, GetOrderOfRequest(1));
559 EXPECT_EQ(2, GetOrderOfRequest(2));
560 EXPECT_EQ(3, GetOrderOfRequest(3));
561 EXPECT_EQ(4, GetOrderOfRequest(4));
562 EXPECT_EQ(5, GetOrderOfRequest(5));
563 EXPECT_EQ(6, GetOrderOfRequest(6));
564 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17565
566 // Make sure we test order of all requests made.
567 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53568}
569
570TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
571 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
572
[email protected]fd7b7c92009-08-20 19:38:30573 // TODO(eroman): Check that the LoadLog contains this event.
574
[email protected]211d21722009-07-22 15:48:53575 // Reach all limits: max total sockets, and max sockets per group.
576 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
577 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
578 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
579 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
580
581 EXPECT_EQ(static_cast<int>(requests_.size()),
582 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17583 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53584
585 // Now create a new group and verify that we don't starve it.
586 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
587
588 ReleaseAllConnections(KEEP_ALIVE);
589
590 EXPECT_EQ(static_cast<int>(requests_.size()),
591 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17592 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53593
594 EXPECT_EQ(1, GetOrderOfRequest(1));
595 EXPECT_EQ(2, GetOrderOfRequest(2));
596 EXPECT_EQ(3, GetOrderOfRequest(3));
597 EXPECT_EQ(4, GetOrderOfRequest(4));
598 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17599
600 // Make sure we test order of all requests made.
601 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53602}
603
604TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
605 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
606
607 EXPECT_EQ(OK, StartRequest("b", 3));
608 EXPECT_EQ(OK, StartRequest("a", 3));
609 EXPECT_EQ(OK, StartRequest("b", 6));
610 EXPECT_EQ(OK, StartRequest("a", 6));
611
612 EXPECT_EQ(static_cast<int>(requests_.size()),
613 client_socket_factory_.allocation_count());
614
615 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 4));
616 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
617 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
618
619 ReleaseAllConnections(KEEP_ALIVE);
620
621 // We're re-using one socket for group "a", and one for "b".
622 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
623 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17624 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53625
626 // First 4 requests don't have to wait, and finish in order.
627 EXPECT_EQ(1, GetOrderOfRequest(1));
628 EXPECT_EQ(2, GetOrderOfRequest(2));
629 EXPECT_EQ(3, GetOrderOfRequest(3));
630 EXPECT_EQ(4, GetOrderOfRequest(4));
631
632 // Request ("b", 7) has the highest priority, then ("a", 5),
633 // and then ("c", 4).
634 EXPECT_EQ(7, GetOrderOfRequest(5));
635 EXPECT_EQ(6, GetOrderOfRequest(6));
636 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17637
638 // Make sure we test order of all requests made.
639 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53640}
641
642TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
643 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
644
645 EXPECT_EQ(OK, StartRequest("a", 3));
646 EXPECT_EQ(OK, StartRequest("a", 6));
647 EXPECT_EQ(OK, StartRequest("b", 3));
648 EXPECT_EQ(OK, StartRequest("b", 6));
649
650 EXPECT_EQ(static_cast<int>(requests_.size()),
651 client_socket_factory_.allocation_count());
652
653 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 6));
654 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
655 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
656
657 ReleaseAllConnections(KEEP_ALIVE);
658
659 // We're re-using one socket for group "a", and one for "b".
660 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
661 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17662 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53663
664 // First 4 requests don't have to wait, and finish in order.
665 EXPECT_EQ(1, GetOrderOfRequest(1));
666 EXPECT_EQ(2, GetOrderOfRequest(2));
667 EXPECT_EQ(3, GetOrderOfRequest(3));
668 EXPECT_EQ(4, GetOrderOfRequest(4));
669
670 // Request ("b", 7) has the highest priority, but we can't make new socket for
671 // group "b", because it has reached the per-group limit. Then we make
672 // socket for ("c", 6), because it has higher priority than ("a", 4),
673 // and we still can't make a socket for group "b".
674 EXPECT_EQ(5, GetOrderOfRequest(5));
675 EXPECT_EQ(6, GetOrderOfRequest(6));
676 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17677
678 // Make sure we test order of all requests made.
679 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53680}
681
682// Make sure that we count connecting sockets against the total limit.
683TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
684 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
685
686 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
687 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
688 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
689
690 // Create one asynchronous request.
691 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
692 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
693
694 // The next synchronous request should wait for its turn.
695 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
696 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
697
698 ReleaseAllConnections(KEEP_ALIVE);
699
700 EXPECT_EQ(static_cast<int>(requests_.size()),
701 client_socket_factory_.allocation_count());
702
703 EXPECT_EQ(1, GetOrderOfRequest(1));
704 EXPECT_EQ(2, GetOrderOfRequest(2));
705 EXPECT_EQ(3, GetOrderOfRequest(3));
706 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17707 EXPECT_EQ(5, GetOrderOfRequest(5));
708
709 // Make sure we test order of all requests made.
710 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53711}
712
713// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
714// which tells it to use more expensive, but accurate, group selection
715// algorithm. Make sure it doesn't get stuck in the "on" state.
716TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
717 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
718
719 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
720
721 // Reach group socket limit.
722 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
723 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
724 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
725
726 // Reach total limit, but don't request more sockets.
727 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
728 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
729 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
730
731 // Request one more socket while we are at the maximum sockets limit.
732 // This should flip the may_have_stalled_group flag.
733 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
734 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
735
736 // After releasing first connection for "a", we're still at the
737 // maximum sockets limit, but every group's pending queue is empty,
738 // so we reset the flag.
739 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
740 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
741
742 // Requesting additional socket while at the total limit should
743 // flip the flag back to "on".
744 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
745 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
746
747 // We'll request one more socket to verify that we don't reset the flag
748 // too eagerly.
749 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
750 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
751
752 // We're at the maximum socket limit, and still have one request pending
753 // for "d". Flag should be "on".
754 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
755 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
756
757 // Now every group's pending queue should be empty again.
758 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
759 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
760
761 ReleaseAllConnections(KEEP_ALIVE);
762 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
763}
764
[email protected]ab838892009-06-30 18:49:05765TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53766 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09767
[email protected]c9d6a1d2009-07-14 16:15:20768 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
769 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
770 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
771 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
772 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
773 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
774 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09775
[email protected]c9d6a1d2009-07-14 16:15:20776 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09777
[email protected]c9d6a1d2009-07-14 16:15:20778 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
779 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17780 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09781
[email protected]c9d6a1d2009-07-14 16:15:20782 EXPECT_EQ(1, GetOrderOfRequest(1));
783 EXPECT_EQ(2, GetOrderOfRequest(2));
784 EXPECT_EQ(6, GetOrderOfRequest(3));
785 EXPECT_EQ(4, GetOrderOfRequest(4));
786 EXPECT_EQ(3, GetOrderOfRequest(5));
787 EXPECT_EQ(5, GetOrderOfRequest(6));
788 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17789
790 // Make sure we test order of all requests made.
791 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09792}
793
[email protected]ab838892009-06-30 18:49:05794TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53795 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09796
[email protected]c9d6a1d2009-07-14 16:15:20797 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
798 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
799 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
800 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
801 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
802 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
803 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09804
[email protected]c9d6a1d2009-07-14 16:15:20805 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09806
[email protected]c9d6a1d2009-07-14 16:15:20807 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
808 EXPECT_EQ(OK, requests_[i]->WaitForResult());
809
810 EXPECT_EQ(static_cast<int>(requests_.size()),
811 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17812 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09813}
814
815// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05816// The pending connect job will be cancelled and should not call back into
817// ClientSocketPoolBase.
818TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53819 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20820
[email protected]ab838892009-06-30 18:49:05821 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06822 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05823 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24824 InitHandle(req.handle(), "a", kDefaultPriority, &req,
825 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33826 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09827}
828
[email protected]ab838892009-06-30 18:49:05829TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53830 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20831
[email protected]ab838892009-06-30 18:49:05832 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06833 TestSocketRequest req(&request_order_, &completion_count_);
834 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09835
[email protected]ab838892009-06-30 18:49:05836 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24837 InitHandle(req.handle(), "a", kDefaultPriority, &req,
838 pool_.get(), NULL));
[email protected]ab838892009-06-30 18:49:05839 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24840 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
841 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09842
[email protected]a6c59f62009-07-29 16:33:33843 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09844
845 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33846 req2.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09847}
848
[email protected]ab838892009-06-30 18:49:05849TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53850 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20851
[email protected]ab838892009-06-30 18:49:05852 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06853 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09854 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06855 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09856
[email protected]ab838892009-06-30 18:49:05857 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24858 InitHandle(&handle, "a", kDefaultPriority, &callback,
859 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09860
861 handle.Reset();
862
863 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05864 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:24865 InitHandle(&handle, "a", kDefaultPriority, &callback2,
866 pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09867
868 EXPECT_EQ(OK, callback2.WaitForResult());
869 EXPECT_FALSE(callback.have_result());
870
871 handle.Reset();
872}
873
[email protected]ab838892009-06-30 18:49:05874TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53875 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09876
[email protected]c9d6a1d2009-07-14 16:15:20877 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
878 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
879 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
880 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
881 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
882 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
883 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09884
885 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20886 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33887 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
888 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09889
[email protected]c9d6a1d2009-07-14 16:15:20890 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09891
[email protected]c9d6a1d2009-07-14 16:15:20892 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
893 client_socket_factory_.allocation_count());
894 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17895 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09896
[email protected]c9d6a1d2009-07-14 16:15:20897 EXPECT_EQ(1, GetOrderOfRequest(1));
898 EXPECT_EQ(2, GetOrderOfRequest(2));
899 EXPECT_EQ(5, GetOrderOfRequest(3));
900 EXPECT_EQ(3, GetOrderOfRequest(4));
901 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
902 EXPECT_EQ(4, GetOrderOfRequest(6));
903 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17904
905 // Make sure we test order of all requests made.
906 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09907}
908
909class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
910 public:
[email protected]2ab05b52009-07-01 23:57:58911 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a937a06d2009-08-19 21:19:24912 TestClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58913 TestConnectJobFactory* test_connect_job_factory,
914 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09915 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06916 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58917 within_callback_(false),
918 test_connect_job_factory_(test_connect_job_factory),
919 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09920
921 virtual void RunWithParams(const Tuple1<int>& params) {
922 callback_.RunWithParams(params);
923 ASSERT_EQ(OK, params.a);
924
925 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58926 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09927 handle_->Reset();
928 within_callback_ = true;
[email protected]a937a06d2009-08-19 21:19:24929 int rv = InitHandle(
930 handle_, "a", kDefaultPriority, this, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:58931 switch (next_job_type_) {
932 case TestConnectJob::kMockJob:
933 EXPECT_EQ(OK, rv);
934 break;
935 case TestConnectJob::kMockPendingJob:
936 EXPECT_EQ(ERR_IO_PENDING, rv);
937 break;
938 default:
939 FAIL() << "Unexpected job type: " << next_job_type_;
940 break;
941 }
[email protected]f6d1d6eb2009-06-24 20:16:09942 }
943 }
944
945 int WaitForResult() {
946 return callback_.WaitForResult();
947 }
948
949 private:
950 ClientSocketHandle* const handle_;
[email protected]a937a06d2009-08-19 21:19:24951 const scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09952 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58953 TestConnectJobFactory* const test_connect_job_factory_;
954 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09955 TestCompletionCallback callback_;
956};
957
[email protected]2ab05b52009-07-01 23:57:58958TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53959 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20960
[email protected]0b7648c2009-07-06 20:14:01961 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06962 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58963 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06964 &handle, pool_.get(), connect_job_factory_,
965 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:24966 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
967 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09968 ASSERT_EQ(ERR_IO_PENDING, rv);
969
970 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:58971 handle.Reset();
972}
[email protected]f6d1d6eb2009-06-24 20:16:09973
[email protected]2ab05b52009-07-01 23:57:58974TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:53975 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20976
[email protected]0b7648c2009-07-06 20:14:01977 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06978 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58979 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06980 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:24981 int rv = InitHandle(&handle, "a", kDefaultPriority, &callback,
982 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:58983 ASSERT_EQ(ERR_IO_PENDING, rv);
984
985 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09986 handle.Reset();
987}
988
989// Make sure that pending requests get serviced after active requests get
990// cancelled.
[email protected]ab838892009-06-30 18:49:05991TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:53992 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20993
[email protected]0b7648c2009-07-06 20:14:01994 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09995
[email protected]c9d6a1d2009-07-14 16:15:20996 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
997 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
998 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
999 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1000 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1001 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1002 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091003
[email protected]c9d6a1d2009-07-14 16:15:201004 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1005 // Let's cancel them.
1006 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331007 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1008 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091009 }
1010
[email protected]f6d1d6eb2009-06-24 20:16:091011 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:201012 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1013 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331014 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:091015 }
1016
[email protected]75439d3b2009-07-23 22:11:171017 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:091018}
1019
1020// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:051021TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531022 const size_t kMaxSockets = 5;
1023 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201024
[email protected]0b7648c2009-07-06 20:14:011025 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:091026
[email protected]211d21722009-07-22 15:48:531027 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1028 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:091029
1030 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531031 for (size_t i = 0; i < kNumberOfRequests; ++i)
1032 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:091033
[email protected]211d21722009-07-22 15:48:531034 for (size_t i = 0; i < kNumberOfRequests; ++i)
1035 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:091036}
1037
[email protected]5fc08e32009-07-15 17:09:571038TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531039 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571040
1041 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1042
[email protected]a512f5982009-08-18 16:01:061043 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241044 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1045 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571046 EXPECT_EQ(ERR_IO_PENDING, rv);
1047
1048 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331049 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571050
[email protected]a937a06d2009-08-19 21:19:241051 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1052 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571053 EXPECT_EQ(ERR_IO_PENDING, rv);
1054 EXPECT_EQ(OK, req.WaitForResult());
1055
[email protected]a6c59f62009-07-29 16:33:331056 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171057 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571058 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1059}
1060
[email protected]2ab05b52009-07-01 23:57:581061// A pending asynchronous job completes, which will free up a socket slot. The
1062// next job finishes synchronously. The callback for the asynchronous job
1063// should be first though.
1064TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531065 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:201066
[email protected]2ab05b52009-07-01 23:57:581067 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:011068 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:581069
1070 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:061071 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241072 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1073 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581074 EXPECT_EQ(ERR_IO_PENDING, rv);
1075
1076 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061077 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241078 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1079 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581080 EXPECT_EQ(ERR_IO_PENDING, rv);
1081
1082 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011083 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581084
1085 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061086 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241087 rv = InitHandle(
1088 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581089 EXPECT_EQ(ERR_IO_PENDING, rv);
1090
1091 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1092 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1093 EXPECT_EQ(OK, req3.WaitForResult());
1094
1095 ASSERT_EQ(3U, request_order_.size());
1096
1097 // After job 1 finishes unsuccessfully, it will try to process the pending
1098 // requests queue, so it starts up job 3 for request 3. This job
1099 // synchronously succeeds, so the request order is 1, 3, 2.
1100 EXPECT_EQ(&req1, request_order_[0]);
1101 EXPECT_EQ(&req2, request_order_[2]);
1102 EXPECT_EQ(&req3, request_order_[1]);
1103}
1104
[email protected]5fc08e32009-07-15 17:09:571105// When a ConnectJob is coupled to a request, even if a free socket becomes
1106// available, the request will be serviced by the ConnectJob.
1107TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531108 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491109 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571110
1111 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321112 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571113
[email protected]a512f5982009-08-18 16:01:061114 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241115 int rv = InitHandle(req1.handle(), "a", kDefaultPriority, &req1,
1116 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571117 EXPECT_EQ(ERR_IO_PENDING, rv);
1118 EXPECT_EQ(OK, req1.WaitForResult());
1119
1120 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1121 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1122
[email protected]a512f5982009-08-18 16:01:061123 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241124 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1125 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571126 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331127 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571128 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1129
1130 // Job 2 is pending. Start request 3 (which has no associated job since it
1131 // will use the idle socket).
1132
[email protected]a512f5982009-08-18 16:01:061133 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241134 rv = InitHandle(req3.handle(), "a", kDefaultPriority, &req3,
1135 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571136 EXPECT_EQ(OK, rv);
1137
[email protected]a6c59f62009-07-29 16:33:331138 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571139 client_socket_factory_.SignalJobs();
1140 EXPECT_EQ(OK, req2.WaitForResult());
1141
1142 ASSERT_EQ(2U, request_order_.size());
1143 EXPECT_EQ(&req1, request_order_[0]);
1144 EXPECT_EQ(&req2, request_order_[1]);
1145 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1146}
1147
[email protected]2b7523d2009-07-29 20:29:231148// Regression test for http://crbug.com/17985.
1149TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1150 const int kMaxSockets = 3;
1151 const int kMaxSocketsPerGroup = 2;
1152 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1153
1154 const int kHighPriority = kDefaultPriority + 100;
1155
1156 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1157 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1158
1159 // This is going to be a pending request in an otherwise empty group.
1160 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1161
1162 // Reach the maximum socket limit.
1163 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1164
1165 // Create a stalled group with high priorities.
1166 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1167 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1168 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1169
1170 // Release the first two sockets from "a", which will make room
1171 // for requests from "c". After that "a" will have no active sockets
1172 // and one pending request.
1173 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1174 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1175
1176 // Closing idle sockets should not get us into trouble, but in the bug
1177 // we were hitting a CHECK here.
1178 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1179 pool_->CloseIdleSockets();
1180 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1181}
1182
[email protected]5fc08e32009-07-15 17:09:571183class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1184 protected:
1185 virtual void SetUp() {
1186 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491187 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571188 }
1189};
1190
[email protected]6e713f02009-08-06 02:56:401191// Even though a timeout is specified, it doesn't time out on a synchronous
1192// completion.
1193TEST_F(ClientSocketPoolBaseTest_LateBinding,
1194 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1195 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061196 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491197 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401198 scoped_ptr<TestConnectJob> job(
1199 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121200 "a",
[email protected]6e713f02009-08-06 02:56:401201 request,
1202 base::TimeDelta::FromMicroseconds(1),
1203 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301204 &client_socket_factory_,
1205 NULL));
[email protected]6e713f02009-08-06 02:56:401206 EXPECT_EQ(OK, job->Connect());
1207}
1208
1209TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1210 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061211 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491212 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401213 // Deleted by TestConnectJobDelegate.
1214 TestConnectJob* job =
1215 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121216 "a",
[email protected]6e713f02009-08-06 02:56:401217 request,
1218 base::TimeDelta::FromMicroseconds(1),
1219 &delegate,
[email protected]fd7b7c92009-08-20 19:38:301220 &client_socket_factory_,
1221 NULL);
[email protected]6e713f02009-08-06 02:56:401222 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1223 PlatformThread::Sleep(1);
1224 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1225}
1226
[email protected]5fc08e32009-07-15 17:09:571227TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531228 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571229
1230 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061231 ClientSocketHandle handle;
[email protected]fd7b7c92009-08-20 19:38:301232 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]a937a06d2009-08-19 21:19:241233 EXPECT_EQ(OK, InitHandle(&handle, "a", kDefaultPriority, &callback,
[email protected]fd7b7c92009-08-20 19:38:301234 pool_.get(), log));
[email protected]5fc08e32009-07-15 17:09:571235 EXPECT_TRUE(handle.is_initialized());
1236 EXPECT_TRUE(handle.socket());
1237 handle.Reset();
[email protected]fd7b7c92009-08-20 19:38:301238
1239 EXPECT_EQ(4u, log->events().size());
1240 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1241 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1242 LoadLog::PHASE_BEGIN);
1243 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1244 LoadLog::PHASE_END);
1245 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571246}
1247
1248TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531249 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571250
1251 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061252 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301253 scoped_refptr<LoadLog> log(new LoadLog);
1254 int rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), log);
[email protected]5fc08e32009-07-15 17:09:571255 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331256 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571257 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331258 EXPECT_TRUE(req.handle()->is_initialized());
1259 EXPECT_TRUE(req.handle()->socket());
1260 req.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301261
1262 EXPECT_EQ(6u, log->events().size());
1263 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1264 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1265 LoadLog::PHASE_BEGIN);
1266 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1267 LoadLog::PHASE_END);
1268 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1269 LoadLog::PHASE_BEGIN);
1270 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1271 LoadLog::PHASE_END);
1272 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571273}
1274
1275TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531276 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571277
1278 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061279 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301280 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571281 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]a937a06d2009-08-19 21:19:241282 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301283 pool_.get(), log));
1284
1285 EXPECT_EQ(4u, log->events().size());
1286 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1287 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1288 LoadLog::PHASE_BEGIN);
1289 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1290 LoadLog::PHASE_END);
1291 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571292}
1293
1294TEST_F(ClientSocketPoolBaseTest_LateBinding,
1295 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531296 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571297
1298 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061299 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]fd7b7c92009-08-20 19:38:301300 scoped_refptr<LoadLog> log(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571301 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241302 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301303 pool_.get(), log));
[email protected]a6c59f62009-07-29 16:33:331304 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571305 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
[email protected]fd7b7c92009-08-20 19:38:301306
1307 EXPECT_EQ(6u, log->events().size());
1308 ExpectLogContains(log, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1309 ExpectLogContains(log, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1310 LoadLog::PHASE_BEGIN);
1311 ExpectLogContains(log, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1312 LoadLog::PHASE_END);
1313 ExpectLogContains(log, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1314 LoadLog::PHASE_BEGIN);
1315 ExpectLogContains(log, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1316 LoadLog::PHASE_END);
1317 ExpectLogContains(log, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
[email protected]5fc08e32009-07-15 17:09:571318}
1319
1320TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531321 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571322
1323 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1324 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1325 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1326 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1327 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1328 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1329 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1330
1331 ReleaseAllConnections(KEEP_ALIVE);
1332
1333 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1334 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171335 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571336
1337 EXPECT_EQ(1, GetOrderOfRequest(1));
1338 EXPECT_EQ(2, GetOrderOfRequest(2));
1339 EXPECT_EQ(6, GetOrderOfRequest(3));
1340 EXPECT_EQ(4, GetOrderOfRequest(4));
1341 EXPECT_EQ(3, GetOrderOfRequest(5));
1342 EXPECT_EQ(5, GetOrderOfRequest(6));
1343 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171344
1345 // Make sure we test order of all requests made.
1346 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571347}
1348
1349TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531350 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571351
1352 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1353 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1354 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1355 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1356 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1357 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1358 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1359
1360 ReleaseAllConnections(NO_KEEP_ALIVE);
1361
1362 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1363 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1364
1365 EXPECT_EQ(static_cast<int>(requests_.size()),
1366 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171367 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571368}
1369
1370// This test will start up a RequestSocket() and then immediately Cancel() it.
1371// The pending connect job will be cancelled and should not call back into
1372// ClientSocketPoolBase.
1373TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531374 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571375
1376 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061377 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571378 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241379 InitHandle(req.handle(), "a", kDefaultPriority, &req,
1380 pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331381 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571382}
1383
1384TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531385 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571386
1387 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061388 TestSocketRequest req(&request_order_, &completion_count_);
1389 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571390
[email protected]fd7b7c92009-08-20 19:38:301391 scoped_refptr<LoadLog> log1(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571392 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241393 InitHandle(req.handle(), "a", kDefaultPriority, &req,
[email protected]fd7b7c92009-08-20 19:38:301394 pool_.get(), log1));
1395 scoped_refptr<LoadLog> log2(new LoadLog);
[email protected]5fc08e32009-07-15 17:09:571396 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241397 InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
[email protected]fd7b7c92009-08-20 19:38:301398 pool_.get(), log2));
[email protected]5fc08e32009-07-15 17:09:571399
[email protected]a6c59f62009-07-29 16:33:331400 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571401
[email protected]fd7b7c92009-08-20 19:38:301402 EXPECT_EQ(5u, log1->events().size());
1403 ExpectLogContains(log1, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1404 ExpectLogContains(log1, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1405 LoadLog::PHASE_BEGIN);
1406 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1407 LoadLog::PHASE_END);
1408 ExpectLogContains(log1, 3, LoadLog::TYPE_CANCELLED, LoadLog::PHASE_NONE);
1409 ExpectLogContains(log1, 4, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1410
1411 // At this point, request 2 is just waiting for the connect job to finish.
1412 EXPECT_EQ(2u, log2->events().size());
1413 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1414 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1415 LoadLog::PHASE_BEGIN);
1416
[email protected]5fc08e32009-07-15 17:09:571417 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331418 req2.handle()->Reset();
[email protected]fd7b7c92009-08-20 19:38:301419
1420 // Now request 2 has actually finished.
1421 EXPECT_EQ(6u, log2->events().size());
1422 ExpectLogContains(log2, 0, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_BEGIN);
1423 ExpectLogContains(log2, 1, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1424 LoadLog::PHASE_BEGIN);
1425 ExpectLogContains(log1, 2, LoadLog::TYPE_SOCKET_POOL_WAITING_IN_QUEUE,
1426 LoadLog::PHASE_END);
1427 ExpectLogContains(log2, 3, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1428 LoadLog::PHASE_BEGIN);
1429 ExpectLogContains(log2, 4, LoadLog::TYPE_SOCKET_POOL_CONNECT_JOB,
1430 LoadLog::PHASE_END);
1431 ExpectLogContains(log2, 5, LoadLog::TYPE_SOCKET_POOL, LoadLog::PHASE_END);
1432
[email protected]5fc08e32009-07-15 17:09:571433}
1434
1435TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531436 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571437
1438 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061439 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571440 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061441 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571442
1443 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241444 InitHandle(&handle, "a", kDefaultPriority, &callback,
1445 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571446
1447 handle.Reset();
1448
1449 TestCompletionCallback callback2;
1450 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a937a06d2009-08-19 21:19:241451 InitHandle(&handle, "a", kDefaultPriority, &callback2,
1452 pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571453
1454 EXPECT_EQ(OK, callback2.WaitForResult());
1455 EXPECT_FALSE(callback.have_result());
1456
1457 handle.Reset();
1458}
1459
1460TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531461 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571462
1463 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1464 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1465 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1466 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1467 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1468 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1469 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1470
1471 // Cancel a request.
1472 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331473 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1474 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571475
1476 ReleaseAllConnections(KEEP_ALIVE);
1477
1478 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1479 client_socket_factory_.allocation_count());
1480 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171481 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571482
1483 EXPECT_EQ(1, GetOrderOfRequest(1));
1484 EXPECT_EQ(2, GetOrderOfRequest(2));
1485 EXPECT_EQ(5, GetOrderOfRequest(3));
1486 EXPECT_EQ(3, GetOrderOfRequest(4));
1487 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1488 EXPECT_EQ(4, GetOrderOfRequest(6));
1489 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171490
1491 // Make sure we test order of all requests made.
1492 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571493}
1494
[email protected]974ebd62009-08-03 23:14:341495TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341496 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1497
[email protected]17a0c6c2009-08-04 00:07:041498 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1499
[email protected]974ebd62009-08-03 23:14:341500 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1501 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1502 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1503 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1504
1505 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1506 requests_[2]->handle()->Reset();
1507 requests_[3]->handle()->Reset();
1508 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1509
1510 requests_[1]->handle()->Reset();
1511 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1512
1513 requests_[0]->handle()->Reset();
1514 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1515}
1516
[email protected]5fc08e32009-07-15 17:09:571517TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531518 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571519
1520 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061521 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571522 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061523 &handle, pool_.get(), connect_job_factory_,
1524 TestConnectJob::kMockPendingJob);
[email protected]a937a06d2009-08-19 21:19:241525 int rv = InitHandle(
1526 &handle, "a", kDefaultPriority, &callback, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571527 ASSERT_EQ(ERR_IO_PENDING, rv);
1528
1529 EXPECT_EQ(OK, callback.WaitForResult());
1530 handle.Reset();
1531}
1532
1533TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531534 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571535
1536 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061537 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571538 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061539 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]a937a06d2009-08-19 21:19:241540 int rv = InitHandle(
1541 &handle, "a", kDefaultPriority, &callback,
[email protected]a512f5982009-08-18 16:01:061542 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571543 ASSERT_EQ(ERR_IO_PENDING, rv);
1544
1545 EXPECT_EQ(OK, callback.WaitForResult());
1546 handle.Reset();
1547}
1548
1549// Make sure that pending requests get serviced after active requests get
1550// cancelled.
1551TEST_F(ClientSocketPoolBaseTest_LateBinding,
1552 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531553 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571554
1555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1556
1557 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1558 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1559 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1560 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1561 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1562 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1563 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1564
1565 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1566 // Let's cancel them.
1567 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331568 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1569 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571570 }
1571
1572 // Let's wait for the rest to complete now.
1573 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1574 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331575 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571576 }
1577
[email protected]75439d3b2009-07-23 22:11:171578 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571579}
1580
1581// Make sure that pending requests get serviced after active requests fail.
1582TEST_F(ClientSocketPoolBaseTest_LateBinding,
1583 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531584 const int kMaxSockets = 5;
1585 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571586
1587 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1588
[email protected]211d21722009-07-22 15:48:531589 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1590 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571591
1592 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531593 for (int i = 0; i < kNumberOfRequests; ++i)
1594 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571595
[email protected]211d21722009-07-22 15:48:531596 for (int i = 0; i < kNumberOfRequests; ++i)
1597 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571598}
1599
1600TEST_F(ClientSocketPoolBaseTest_LateBinding,
1601 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531602 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571603
1604 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1605
[email protected]a512f5982009-08-18 16:01:061606 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241607 int rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1608 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571609 EXPECT_EQ(ERR_IO_PENDING, rv);
1610
1611 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331612 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571613
[email protected]a937a06d2009-08-19 21:19:241614 rv = InitHandle(req.handle(), "a", kDefaultPriority, &req,
1615 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571616 EXPECT_EQ(ERR_IO_PENDING, rv);
1617 EXPECT_EQ(OK, req.WaitForResult());
1618
[email protected]a6c59f62009-07-29 16:33:331619 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171620 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571621 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1622}
1623
1624// When requests and ConnectJobs are not coupled, the request will get serviced
1625// by whatever comes first.
1626TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531627 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571628
1629 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321630 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571631
[email protected]a512f5982009-08-18 16:01:061632 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241633 int rv = InitHandle(req1.handle(), "a", kDefaultPriority,
1634 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571635 EXPECT_EQ(ERR_IO_PENDING, rv);
1636 EXPECT_EQ(OK, req1.WaitForResult());
1637
1638 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1639 // without a job.
1640 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1641
[email protected]a512f5982009-08-18 16:01:061642 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241643 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1644 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571645 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061646 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241647 rv = InitHandle(
1648 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571649 EXPECT_EQ(ERR_IO_PENDING, rv);
1650
1651 // Both Requests 2 and 3 are pending. We release socket 1 which should
1652 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331653 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571654 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331655 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571656 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331657 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571658
1659 // Signal job 2, which should service request 3.
1660
1661 client_socket_factory_.SignalJobs();
1662 EXPECT_EQ(OK, req3.WaitForResult());
1663
1664 ASSERT_EQ(3U, request_order_.size());
1665 EXPECT_EQ(&req1, request_order_[0]);
1666 EXPECT_EQ(&req2, request_order_[1]);
1667 EXPECT_EQ(&req3, request_order_[2]);
1668 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1669}
1670
1671// The requests are not coupled to the jobs. So, the requests should finish in
1672// their priority / insertion order.
1673TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531674 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571675 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321676 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571677
[email protected]a512f5982009-08-18 16:01:061678 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241679 int rv = InitHandle(
1680 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571681 EXPECT_EQ(ERR_IO_PENDING, rv);
1682
[email protected]a512f5982009-08-18 16:01:061683 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241684 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1685 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571686 EXPECT_EQ(ERR_IO_PENDING, rv);
1687
1688 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321689 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571690
[email protected]a512f5982009-08-18 16:01:061691 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241692 rv = InitHandle(
1693 req3.handle(), "a", kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571694 EXPECT_EQ(ERR_IO_PENDING, rv);
1695
1696 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1697 EXPECT_EQ(OK, req2.WaitForResult());
1698 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1699
1700 ASSERT_EQ(3U, request_order_.size());
1701 EXPECT_EQ(&req1, request_order_[0]);
1702 EXPECT_EQ(&req2, request_order_[1]);
1703 EXPECT_EQ(&req3, request_order_[2]);
1704}
1705
[email protected]f0109a7d2009-07-16 00:09:521706TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531707 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571708 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321709 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571710
[email protected]a512f5982009-08-18 16:01:061711 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241712 int rv = InitHandle(
1713 req1.handle(), "a", kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331715 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571716
1717 MessageLoop::current()->RunAllPending();
1718
[email protected]a512f5982009-08-18 16:01:061719 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]a937a06d2009-08-19 21:19:241720 rv = InitHandle(req2.handle(), "a", kDefaultPriority, &req2,
1721 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571722 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331723 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1724 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571725}
1726
[email protected]2b7523d2009-07-29 20:29:231727// Regression test for http://crbug.com/17985.
1728TEST_F(ClientSocketPoolBaseTest_LateBinding,
1729 GroupWithPendingRequestsIsNotEmpty) {
1730 const int kMaxSockets = 3;
1731 const int kMaxSocketsPerGroup = 2;
1732 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1733
1734 const int kHighPriority = kDefaultPriority + 100;
1735
1736 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1737 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1738
1739 // This is going to be a pending request in an otherwise empty group.
1740 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1741
1742 // Reach the maximum socket limit.
1743 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1744
1745 // Create a stalled group with high priorities.
1746 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1747 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1748 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1749
1750 // Release the first two sockets from "a", which will make room
1751 // for requests from "c". After that "a" will have no active sockets
1752 // and one pending request.
1753 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1754 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1755
1756 // Closing idle sockets should not get us into trouble, but in the bug
1757 // we were hitting a CHECK here.
1758 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1759 pool_->CloseIdleSockets();
1760 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1761}
1762
[email protected]f6d1d6eb2009-06-24 20:16:091763} // namespace
1764
1765} // namespace net