blob: 840ca36b0334a86972846f268c01d3e6140f8c5c [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]f6d1d6eb2009-06-24 20:16:0911#include "net/base/net_errors.h"
12#include "net/base/test_completion_callback.h"
13#include "net/socket/client_socket.h"
14#include "net/socket/client_socket_factory.h"
15#include "net/socket/client_socket_handle.h"
[email protected]75439d3b2009-07-23 22:11:1716#include "net/socket/socket_test_util.h"
[email protected]f6d1d6eb2009-06-24 20:16:0917#include "testing/gtest/include/gtest/gtest.h"
18
19namespace net {
20
21namespace {
22
[email protected]211d21722009-07-22 15:48:5323const int kDefaultMaxSockets = 4;
[email protected]c9d6a1d2009-07-14 16:15:2024const int kDefaultMaxSocketsPerGroup = 2;
[email protected]0b7648c2009-07-06 20:14:0125const int kDefaultPriority = 5;
26
[email protected]d80a4322009-08-14 07:07:4927typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase;
28
[email protected]f6d1d6eb2009-06-24 20:16:0929class MockClientSocket : public ClientSocket {
30 public:
31 MockClientSocket() : connected_(false) {}
32
[email protected]ab838892009-06-30 18:49:0533 // Socket methods:
34 virtual int Read(
35 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
36 return ERR_UNEXPECTED;
37 }
38
39 virtual int Write(
40 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
41 return ERR_UNEXPECTED;
42 }
43
[email protected]f6d1d6eb2009-06-24 20:16:0944 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0545
[email protected]f6d1d6eb2009-06-24 20:16:0946 virtual int Connect(CompletionCallback* callback) {
47 connected_ = true;
48 return OK;
49 }
[email protected]f6d1d6eb2009-06-24 20:16:0950
[email protected]ab838892009-06-30 18:49:0551 virtual void Disconnect() { connected_ = false; }
52 virtual bool IsConnected() const { return connected_; }
53 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0154
[email protected]ab838892009-06-30 18:49:0555#if defined(OS_LINUX)
56 virtual int GetPeerName(struct sockaddr* /* name */,
57 socklen_t* /* namelen */) {
58 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0959 }
[email protected]ab838892009-06-30 18:49:0560#endif
[email protected]f6d1d6eb2009-06-24 20:16:0961
62 private:
63 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0964
[email protected]ab838892009-06-30 18:49:0565 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0966};
67
[email protected]5fc08e32009-07-15 17:09:5768class TestConnectJob;
69
[email protected]f6d1d6eb2009-06-24 20:16:0970class MockClientSocketFactory : public ClientSocketFactory {
71 public:
[email protected]ab838892009-06-30 18:49:0572 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0973
74 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
75 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0576 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0977 }
78
79 virtual SSLClientSocket* CreateSSLClientSocket(
80 ClientSocket* transport_socket,
81 const std::string& hostname,
82 const SSLConfig& ssl_config) {
83 NOTIMPLEMENTED();
84 return NULL;
85 }
86
[email protected]5fc08e32009-07-15 17:09:5787 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
88 void SignalJobs();
89
[email protected]f6d1d6eb2009-06-24 20:16:0990 int allocation_count() const { return allocation_count_; }
91
[email protected]f6d1d6eb2009-06-24 20:16:0992 private:
93 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5794 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0995};
96
[email protected]ab838892009-06-30 18:49:0597class TestConnectJob : public ConnectJob {
98 public:
99 enum JobType {
100 kMockJob,
101 kMockFailingJob,
102 kMockPendingJob,
103 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57104 kMockWaitingJob,
105 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05106 };
107
108 TestConnectJob(JobType job_type,
109 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49110 const TestClientSocketPoolBase::Request& request,
[email protected]974ebd62009-08-03 23:14:34111 base::TimeDelta timeout_duration,
[email protected]ab838892009-06-30 18:49:05112 ConnectJob::Delegate* delegate,
[email protected]5fc08e32009-07-15 17:09:57113 MockClientSocketFactory* client_socket_factory)
[email protected]d80a4322009-08-14 07:07:49114 : ConnectJob(group_name, request.handle(), timeout_duration, delegate),
[email protected]2ab05b52009-07-01 23:57:58115 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05116 client_socket_factory_(client_socket_factory),
[email protected]ab838892009-06-30 18:49:05117 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
118
[email protected]974ebd62009-08-03 23:14:34119 void Signal() {
120 DoConnect(waiting_success_, true /* async */);
121 }
122
123 private:
[email protected]ab838892009-06-30 18:49:05124 // ConnectJob methods:
125
[email protected]974ebd62009-08-03 23:14:34126 virtual int ConnectInternal() {
[email protected]ab838892009-06-30 18:49:05127 AddressList ignored;
128 client_socket_factory_->CreateTCPClientSocket(ignored);
[email protected]6e713f02009-08-06 02:56:40129 set_socket(new MockClientSocket());
[email protected]ab838892009-06-30 18:49:05130 switch (job_type_) {
131 case kMockJob:
132 return DoConnect(true /* successful */, false /* sync */);
133 case kMockFailingJob:
134 return DoConnect(false /* error */, false /* sync */);
135 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57136 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05137 MessageLoop::current()->PostTask(
138 FROM_HERE,
139 method_factory_.NewRunnableMethod(
140 &TestConnectJob::DoConnect,
141 true /* successful */,
142 true /* async */));
143 return ERR_IO_PENDING;
144 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57145 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05146 MessageLoop::current()->PostTask(
147 FROM_HERE,
148 method_factory_.NewRunnableMethod(
149 &TestConnectJob::DoConnect,
150 false /* error */,
151 true /* async */));
152 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57153 case kMockWaitingJob:
154 client_socket_factory_->WaitForSignal(this);
155 waiting_success_ = true;
156 return ERR_IO_PENDING;
157 case kMockAdvancingLoadStateJob:
158 MessageLoop::current()->PostTask(
159 FROM_HERE,
160 method_factory_.NewRunnableMethod(
161 &TestConnectJob::AdvanceLoadState, load_state()));
162 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05163 default:
164 NOTREACHED();
[email protected]6e713f02009-08-06 02:56:40165 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05166 return ERR_FAILED;
167 }
168 }
169
[email protected]ab838892009-06-30 18:49:05170 int DoConnect(bool succeed, bool was_async) {
171 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05172 if (succeed) {
173 result = OK;
[email protected]2ab05b52009-07-01 23:57:58174 socket()->Connect(NULL);
[email protected]6e713f02009-08-06 02:56:40175 } else {
176 set_socket(NULL);
[email protected]ab838892009-06-30 18:49:05177 }
[email protected]2ab05b52009-07-01 23:57:58178
179 if (was_async)
180 delegate()->OnConnectJobComplete(result, this);
[email protected]ab838892009-06-30 18:49:05181 return result;
182 }
183
[email protected]5fc08e32009-07-15 17:09:57184 void AdvanceLoadState(LoadState state) {
185 int tmp = state;
186 tmp++;
187 state = static_cast<LoadState>(tmp);
188 set_load_state(state);
189 // Post a delayed task so RunAllPending() won't run it.
190 MessageLoop::current()->PostDelayedTask(
191 FROM_HERE,
192 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
193 state),
194 1 /* 1ms delay */);
195 }
196
197 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05198 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57199 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05200 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
201
202 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
203};
204
[email protected]d80a4322009-08-14 07:07:49205class TestConnectJobFactory
206 : public TestClientSocketPoolBase::ConnectJobFactory {
[email protected]ab838892009-06-30 18:49:05207 public:
[email protected]5fc08e32009-07-15 17:09:57208 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05209 : job_type_(TestConnectJob::kMockJob),
210 client_socket_factory_(client_socket_factory) {}
211
212 virtual ~TestConnectJobFactory() {}
213
214 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
215
[email protected]974ebd62009-08-03 23:14:34216 void set_timeout_duration(base::TimeDelta timeout_duration) {
217 timeout_duration_ = timeout_duration;
218 }
219
[email protected]ab838892009-06-30 18:49:05220 // ConnectJobFactory methods:
221
222 virtual ConnectJob* NewConnectJob(
223 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49224 const TestClientSocketPoolBase::Request& request,
[email protected]ab838892009-06-30 18:49:05225 ConnectJob::Delegate* delegate) const {
226 return new TestConnectJob(job_type_,
227 group_name,
228 request,
[email protected]974ebd62009-08-03 23:14:34229 timeout_duration_,
[email protected]ab838892009-06-30 18:49:05230 delegate,
231 client_socket_factory_);
232 }
233
234 private:
235 TestConnectJob::JobType job_type_;
[email protected]974ebd62009-08-03 23:14:34236 base::TimeDelta timeout_duration_;
[email protected]5fc08e32009-07-15 17:09:57237 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05238
239 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
240};
241
242class TestClientSocketPool : public ClientSocketPool {
243 public:
244 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53245 int max_sockets,
[email protected]ab838892009-06-30 18:49:05246 int max_sockets_per_group,
[email protected]d80a4322009-08-14 07:07:49247 TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
248 : base_(max_sockets, max_sockets_per_group, connect_job_factory) {}
[email protected]ab838892009-06-30 18:49:05249
250 virtual int RequestSocket(
251 const std::string& group_name,
[email protected]d80a4322009-08-14 07:07:49252 const void* params,
[email protected]ab838892009-06-30 18:49:05253 int priority,
254 ClientSocketHandle* handle,
[email protected]684970b2009-08-14 04:54:46255 CompletionCallback* callback,
256 LoadLog* load_log) {
[email protected]d80a4322009-08-14 07:07:49257 return base_.RequestSocket(
258 group_name, params, priority, handle, callback, load_log);
[email protected]ab838892009-06-30 18:49:05259 }
260
261 virtual void CancelRequest(
262 const std::string& group_name,
263 const ClientSocketHandle* handle) {
[email protected]d80a4322009-08-14 07:07:49264 base_.CancelRequest(group_name, handle);
[email protected]ab838892009-06-30 18:49:05265 }
266
267 virtual void ReleaseSocket(
268 const std::string& group_name,
269 ClientSocket* socket) {
[email protected]d80a4322009-08-14 07:07:49270 base_.ReleaseSocket(group_name, socket);
[email protected]ab838892009-06-30 18:49:05271 }
272
273 virtual void CloseIdleSockets() {
[email protected]d80a4322009-08-14 07:07:49274 base_.CloseIdleSockets();
[email protected]ab838892009-06-30 18:49:05275 }
276
[email protected]d80a4322009-08-14 07:07:49277 virtual int IdleSocketCount() const { return base_.idle_socket_count(); }
[email protected]ab838892009-06-30 18:49:05278
279 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49280 return base_.IdleSocketCountInGroup(group_name);
[email protected]ab838892009-06-30 18:49:05281 }
282
283 virtual LoadState GetLoadState(const std::string& group_name,
284 const ClientSocketHandle* handle) const {
[email protected]d80a4322009-08-14 07:07:49285 return base_.GetLoadState(group_name, handle);
[email protected]ab838892009-06-30 18:49:05286 }
287
[email protected]d80a4322009-08-14 07:07:49288 const TestClientSocketPoolBase* base() const { return &base_; }
[email protected]c9d6a1d2009-07-14 16:15:20289
[email protected]974ebd62009-08-03 23:14:34290 int NumConnectJobsInGroup(const std::string& group_name) const {
[email protected]d80a4322009-08-14 07:07:49291 return base_.NumConnectJobsInGroup(group_name);
[email protected]974ebd62009-08-03 23:14:34292 }
293
[email protected]ab838892009-06-30 18:49:05294 private:
[email protected]d80a4322009-08-14 07:07:49295 TestClientSocketPoolBase base_;
[email protected]ab838892009-06-30 18:49:05296
297 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
298};
299
[email protected]5fc08e32009-07-15 17:09:57300void MockClientSocketFactory::SignalJobs() {
301 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
302 it != waiting_jobs_.end(); ++it) {
303 (*it)->Signal();
304 }
305 waiting_jobs_.clear();
306}
307
[email protected]974ebd62009-08-03 23:14:34308class TestConnectJobDelegate : public ConnectJob::Delegate {
309 public:
310 TestConnectJobDelegate()
311 : have_result_(false), waiting_for_result_(false), result_(OK) {}
312 virtual ~TestConnectJobDelegate() {}
313
314 virtual void OnConnectJobComplete(int result, ConnectJob* job) {
315 result_ = result;
[email protected]6e713f02009-08-06 02:56:40316 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
317 if (result == OK) {
318 EXPECT_TRUE(socket.get() != NULL);
319 } else {
320 EXPECT_EQ(NULL, socket.get());
321 }
[email protected]974ebd62009-08-03 23:14:34322 delete job;
323 have_result_ = true;
324 if (waiting_for_result_)
325 MessageLoop::current()->Quit();
326 }
327
328 int WaitForResult() {
329 DCHECK(!waiting_for_result_);
330 while (!have_result_) {
331 waiting_for_result_ = true;
332 MessageLoop::current()->Run();
333 waiting_for_result_ = false;
334 }
335 have_result_ = false; // auto-reset for next callback
336 return result_;
337 }
338
339 private:
340 bool have_result_;
341 bool waiting_for_result_;
342 int result_;
343};
344
[email protected]75439d3b2009-07-23 22:11:17345class ClientSocketPoolBaseTest : public ClientSocketPoolTest {
[email protected]f6d1d6eb2009-06-24 20:16:09346 protected:
[email protected]17a0c6c2009-08-04 00:07:04347 ClientSocketPoolBaseTest() {}
[email protected]c9d6a1d2009-07-14 16:15:20348
[email protected]211d21722009-07-22 15:48:53349 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]c9d6a1d2009-07-14 16:15:20350 DCHECK(!pool_.get());
[email protected]17a0c6c2009-08-04 00:07:04351 connect_job_factory_ = new TestConnectJobFactory(&client_socket_factory_);
[email protected]211d21722009-07-22 15:48:53352 pool_ = new TestClientSocketPool(max_sockets,
353 max_sockets_per_group,
[email protected]c9d6a1d2009-07-14 16:15:20354 connect_job_factory_);
355 }
[email protected]f6d1d6eb2009-06-24 20:16:09356
[email protected]75439d3b2009-07-23 22:11:17357 int StartRequest(const std::string& group_name, int priority) {
358 return StartRequestUsingPool(pool_.get(), group_name, priority);
[email protected]f6d1d6eb2009-06-24 20:16:09359 }
360
361 virtual void TearDown() {
[email protected]211d21722009-07-22 15:48:53362 // Need to delete |pool_| before we turn late binding back off. We also need
363 // to delete |requests_| because the pool is reference counted and requests
364 // keep reference to it.
365 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57366 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53367 requests_.reset();
368
[email protected]d80a4322009-08-14 07:07:49369 EnableLateBindingOfSockets(false);
[email protected]75439d3b2009-07-23 22:11:17370
371 ClientSocketPoolTest::TearDown();
[email protected]f6d1d6eb2009-06-24 20:16:09372 }
373
[email protected]f6d1d6eb2009-06-24 20:16:09374 MockClientSocketFactory client_socket_factory_;
[email protected]17a0c6c2009-08-04 00:07:04375 TestConnectJobFactory* connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20376 scoped_refptr<TestClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09377};
378
[email protected]974ebd62009-08-03 23:14:34379// Even though a timeout is specified, it doesn't time out on a synchronous
380// completion.
381TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) {
382 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06383 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49384 TestClientSocketPoolBase::Request request(
385 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34386 scoped_ptr<TestConnectJob> job(
387 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:12388 "a",
[email protected]974ebd62009-08-03 23:14:34389 request,
390 base::TimeDelta::FromMicroseconds(1),
391 &delegate,
392 &client_socket_factory_));
393 EXPECT_EQ(OK, job->Connect());
394}
395
396TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) {
397 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:06398 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:49399 TestClientSocketPoolBase::Request request(
400 &ignored, NULL, kDefaultPriority, NULL, NULL);
[email protected]974ebd62009-08-03 23:14:34401 // Deleted by TestConnectJobDelegate.
402 TestConnectJob* job =
403 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:12404 "a",
[email protected]974ebd62009-08-03 23:14:34405 request,
406 base::TimeDelta::FromMicroseconds(1),
407 &delegate,
408 &client_socket_factory_);
409 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
410 PlatformThread::Sleep(1);
411 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
412}
413
[email protected]5fc08e32009-07-15 17:09:57414TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53415 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20416
[email protected]f6d1d6eb2009-06-24 20:16:09417 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06418 ClientSocketHandle handle;
419 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority,
420 &callback, pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09421 EXPECT_TRUE(handle.is_initialized());
422 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09423 handle.Reset();
424}
425
[email protected]5fc08e32009-07-15 17:09:57426TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53427 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57428
429 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06430 TestSocketRequest req(&request_order_, &completion_count_);
431 int rv = req.handle()->Init(
432 "a", ignored_request_info_, 0, &req, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:57433 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:33434 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57435 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33436 EXPECT_TRUE(req.handle()->is_initialized());
437 EXPECT_TRUE(req.handle()->socket());
438 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:57439}
440
[email protected]ab838892009-06-30 18:49:05441TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53442 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20443
[email protected]ab838892009-06-30 18:49:05444 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:06445 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]3ae82302009-06-26 06:01:21446 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]684970b2009-08-14 04:54:46447 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06448 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09449}
450
[email protected]5fc08e32009-07-15 17:09:57451TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53452 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57453
454 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:06455 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:57456 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a512f5982009-08-18 16:01:06457 req.handle()->Init("a", ignored_request_info_, kDefaultPriority,
458 &req, pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33459 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:57460 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
461}
462
[email protected]211d21722009-07-22 15:48:53463TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
464 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
465
466 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
467 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
468 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
469 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
470
471 EXPECT_EQ(static_cast<int>(requests_.size()),
472 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17473 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53474
475 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
476 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
477 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
478
479 ReleaseAllConnections(KEEP_ALIVE);
480
481 EXPECT_EQ(static_cast<int>(requests_.size()),
482 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17483 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53484
485 EXPECT_EQ(1, GetOrderOfRequest(1));
486 EXPECT_EQ(2, GetOrderOfRequest(2));
487 EXPECT_EQ(3, GetOrderOfRequest(3));
488 EXPECT_EQ(4, GetOrderOfRequest(4));
489 EXPECT_EQ(5, GetOrderOfRequest(5));
490 EXPECT_EQ(6, GetOrderOfRequest(6));
491 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17492
493 // Make sure we test order of all requests made.
494 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53495}
496
497TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
498 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
499
500 // Reach all limits: max total sockets, and max sockets per group.
501 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
502 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
503 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
504 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
505
506 EXPECT_EQ(static_cast<int>(requests_.size()),
507 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17508 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53509
510 // Now create a new group and verify that we don't starve it.
511 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
512
513 ReleaseAllConnections(KEEP_ALIVE);
514
515 EXPECT_EQ(static_cast<int>(requests_.size()),
516 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17517 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53518
519 EXPECT_EQ(1, GetOrderOfRequest(1));
520 EXPECT_EQ(2, GetOrderOfRequest(2));
521 EXPECT_EQ(3, GetOrderOfRequest(3));
522 EXPECT_EQ(4, GetOrderOfRequest(4));
523 EXPECT_EQ(5, GetOrderOfRequest(5));
[email protected]75439d3b2009-07-23 22:11:17524
525 // Make sure we test order of all requests made.
526 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53527}
528
529TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
530 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
531
532 EXPECT_EQ(OK, StartRequest("b", 3));
533 EXPECT_EQ(OK, StartRequest("a", 3));
534 EXPECT_EQ(OK, StartRequest("b", 6));
535 EXPECT_EQ(OK, StartRequest("a", 6));
536
537 EXPECT_EQ(static_cast<int>(requests_.size()),
538 client_socket_factory_.allocation_count());
539
540 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 4));
541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
543
544 ReleaseAllConnections(KEEP_ALIVE);
545
546 // We're re-using one socket for group "a", and one for "b".
547 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
548 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17549 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53550
551 // First 4 requests don't have to wait, and finish in order.
552 EXPECT_EQ(1, GetOrderOfRequest(1));
553 EXPECT_EQ(2, GetOrderOfRequest(2));
554 EXPECT_EQ(3, GetOrderOfRequest(3));
555 EXPECT_EQ(4, GetOrderOfRequest(4));
556
557 // Request ("b", 7) has the highest priority, then ("a", 5),
558 // and then ("c", 4).
559 EXPECT_EQ(7, GetOrderOfRequest(5));
560 EXPECT_EQ(6, GetOrderOfRequest(6));
561 EXPECT_EQ(5, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17562
563 // Make sure we test order of all requests made.
564 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53565}
566
567TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
568 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
569
570 EXPECT_EQ(OK, StartRequest("a", 3));
571 EXPECT_EQ(OK, StartRequest("a", 6));
572 EXPECT_EQ(OK, StartRequest("b", 3));
573 EXPECT_EQ(OK, StartRequest("b", 6));
574
575 EXPECT_EQ(static_cast<int>(requests_.size()),
576 client_socket_factory_.allocation_count());
577
578 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 6));
579 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
580 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
581
582 ReleaseAllConnections(KEEP_ALIVE);
583
584 // We're re-using one socket for group "a", and one for "b".
585 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
586 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17587 EXPECT_EQ(requests_.size() - kDefaultMaxSockets, completion_count_);
[email protected]211d21722009-07-22 15:48:53588
589 // First 4 requests don't have to wait, and finish in order.
590 EXPECT_EQ(1, GetOrderOfRequest(1));
591 EXPECT_EQ(2, GetOrderOfRequest(2));
592 EXPECT_EQ(3, GetOrderOfRequest(3));
593 EXPECT_EQ(4, GetOrderOfRequest(4));
594
595 // Request ("b", 7) has the highest priority, but we can't make new socket for
596 // group "b", because it has reached the per-group limit. Then we make
597 // socket for ("c", 6), because it has higher priority than ("a", 4),
598 // and we still can't make a socket for group "b".
599 EXPECT_EQ(5, GetOrderOfRequest(5));
600 EXPECT_EQ(6, GetOrderOfRequest(6));
601 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17602
603 // Make sure we test order of all requests made.
604 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]211d21722009-07-22 15:48:53605}
606
607// Make sure that we count connecting sockets against the total limit.
608TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
609 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
610
611 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
612 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
613 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
614
615 // Create one asynchronous request.
616 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
617 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
618
619 // The next synchronous request should wait for its turn.
620 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
621 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
622
623 ReleaseAllConnections(KEEP_ALIVE);
624
625 EXPECT_EQ(static_cast<int>(requests_.size()),
626 client_socket_factory_.allocation_count());
627
628 EXPECT_EQ(1, GetOrderOfRequest(1));
629 EXPECT_EQ(2, GetOrderOfRequest(2));
630 EXPECT_EQ(3, GetOrderOfRequest(3));
631 EXPECT_EQ(4, GetOrderOfRequest(4));
[email protected]75439d3b2009-07-23 22:11:17632 EXPECT_EQ(5, GetOrderOfRequest(5));
633
634 // Make sure we test order of all requests made.
635 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(6));
[email protected]211d21722009-07-22 15:48:53636}
637
638// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
639// which tells it to use more expensive, but accurate, group selection
640// algorithm. Make sure it doesn't get stuck in the "on" state.
641TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
642 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
643
644 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
645
646 // Reach group socket limit.
647 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
648 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
649 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
650
651 // Reach total limit, but don't request more sockets.
652 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
653 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
654 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
655
656 // Request one more socket while we are at the maximum sockets limit.
657 // This should flip the may_have_stalled_group flag.
658 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
659 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
660
661 // After releasing first connection for "a", we're still at the
662 // maximum sockets limit, but every group's pending queue is empty,
663 // so we reset the flag.
664 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
665 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
666
667 // Requesting additional socket while at the total limit should
668 // flip the flag back to "on".
669 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
670 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
671
672 // We'll request one more socket to verify that we don't reset the flag
673 // too eagerly.
674 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
675 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
676
677 // We're at the maximum socket limit, and still have one request pending
678 // for "d". Flag should be "on".
679 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
680 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
681
682 // Now every group's pending queue should be empty again.
683 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
684 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
685
686 ReleaseAllConnections(KEEP_ALIVE);
687 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
688}
689
[email protected]ab838892009-06-30 18:49:05690TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53691 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09692
[email protected]c9d6a1d2009-07-14 16:15:20693 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
694 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
695 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
696 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
697 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
698 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
699 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09700
[email protected]c9d6a1d2009-07-14 16:15:20701 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09702
[email protected]c9d6a1d2009-07-14 16:15:20703 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
704 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17705 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09706
[email protected]c9d6a1d2009-07-14 16:15:20707 EXPECT_EQ(1, GetOrderOfRequest(1));
708 EXPECT_EQ(2, GetOrderOfRequest(2));
709 EXPECT_EQ(6, GetOrderOfRequest(3));
710 EXPECT_EQ(4, GetOrderOfRequest(4));
711 EXPECT_EQ(3, GetOrderOfRequest(5));
712 EXPECT_EQ(5, GetOrderOfRequest(6));
713 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17714
715 // Make sure we test order of all requests made.
716 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09717}
718
[email protected]ab838892009-06-30 18:49:05719TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53720 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09721
[email protected]c9d6a1d2009-07-14 16:15:20722 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
723 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
724 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
725 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
726 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
727 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
728 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09729
[email protected]c9d6a1d2009-07-14 16:15:20730 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09731
[email protected]c9d6a1d2009-07-14 16:15:20732 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
733 EXPECT_EQ(OK, requests_[i]->WaitForResult());
734
735 EXPECT_EQ(static_cast<int>(requests_.size()),
736 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:17737 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09738}
739
740// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05741// The pending connect job will be cancelled and should not call back into
742// ClientSocketPoolBase.
743TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53744 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20745
[email protected]ab838892009-06-30 18:49:05746 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06747 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]ab838892009-06-30 18:49:05748 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:46749 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06750 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:33751 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09752}
753
[email protected]ab838892009-06-30 18:49:05754TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53755 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20756
[email protected]ab838892009-06-30 18:49:05757 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06758 TestSocketRequest req(&request_order_, &completion_count_);
759 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09760
[email protected]ab838892009-06-30 18:49:05761 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:46762 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06763 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]ab838892009-06-30 18:49:05764 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:46765 req2.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06766 kDefaultPriority, &req2, pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09767
[email protected]a6c59f62009-07-29 16:33:33768 req.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09769
770 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33771 req2.handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09772}
773
[email protected]ab838892009-06-30 18:49:05774TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53775 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20776
[email protected]ab838892009-06-30 18:49:05777 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06778 ClientSocketHandle handle;
[email protected]f6d1d6eb2009-06-24 20:16:09779 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:06780 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09781
[email protected]ab838892009-06-30 18:49:05782 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:46783 handle.Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06784 kDefaultPriority, &callback, pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09785
786 handle.Reset();
787
788 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05789 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:46790 handle.Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:06791 kDefaultPriority, &callback2, pool_.get(), NULL));
[email protected]f6d1d6eb2009-06-24 20:16:09792
793 EXPECT_EQ(OK, callback2.WaitForResult());
794 EXPECT_FALSE(callback.have_result());
795
796 handle.Reset();
797}
798
[email protected]ab838892009-06-30 18:49:05799TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53800 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09801
[email protected]c9d6a1d2009-07-14 16:15:20802 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
803 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
804 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
805 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
806 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
807 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
808 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09809
810 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20811 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:33812 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
813 requests_[index_to_cancel]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09814
[email protected]c9d6a1d2009-07-14 16:15:20815 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09816
[email protected]c9d6a1d2009-07-14 16:15:20817 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
818 client_socket_factory_.allocation_count());
819 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:17820 completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09821
[email protected]c9d6a1d2009-07-14 16:15:20822 EXPECT_EQ(1, GetOrderOfRequest(1));
823 EXPECT_EQ(2, GetOrderOfRequest(2));
824 EXPECT_EQ(5, GetOrderOfRequest(3));
825 EXPECT_EQ(3, GetOrderOfRequest(4));
826 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
827 EXPECT_EQ(4, GetOrderOfRequest(6));
828 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:17829
830 // Make sure we test order of all requests made.
831 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]f6d1d6eb2009-06-24 20:16:09832}
833
834class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
835 public:
[email protected]2ab05b52009-07-01 23:57:58836 RequestSocketCallback(ClientSocketHandle* handle,
[email protected]a512f5982009-08-18 16:01:06837 ClientSocketPool* pool,
[email protected]2ab05b52009-07-01 23:57:58838 TestConnectJobFactory* test_connect_job_factory,
839 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09840 : handle_(handle),
[email protected]a512f5982009-08-18 16:01:06841 pool_(pool),
[email protected]2ab05b52009-07-01 23:57:58842 within_callback_(false),
843 test_connect_job_factory_(test_connect_job_factory),
844 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09845
846 virtual void RunWithParams(const Tuple1<int>& params) {
847 callback_.RunWithParams(params);
848 ASSERT_EQ(OK, params.a);
849
850 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58851 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09852 handle_->Reset();
853 within_callback_ = true;
854 int rv = handle_->Init(
[email protected]684970b2009-08-14 04:54:46855 "a", HostResolver::RequestInfo("www.google.com", 80),
[email protected]a512f5982009-08-18 16:01:06856 kDefaultPriority, this, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:58857 switch (next_job_type_) {
858 case TestConnectJob::kMockJob:
859 EXPECT_EQ(OK, rv);
860 break;
861 case TestConnectJob::kMockPendingJob:
862 EXPECT_EQ(ERR_IO_PENDING, rv);
863 break;
864 default:
865 FAIL() << "Unexpected job type: " << next_job_type_;
866 break;
867 }
[email protected]f6d1d6eb2009-06-24 20:16:09868 }
869 }
870
871 int WaitForResult() {
872 return callback_.WaitForResult();
873 }
874
875 private:
876 ClientSocketHandle* const handle_;
[email protected]a512f5982009-08-18 16:01:06877 const scoped_refptr<ClientSocketPool> pool_;
[email protected]f6d1d6eb2009-06-24 20:16:09878 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58879 TestConnectJobFactory* const test_connect_job_factory_;
880 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09881 TestCompletionCallback callback_;
882};
883
[email protected]2ab05b52009-07-01 23:57:58884TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53885 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20886
[email protected]0b7648c2009-07-06 20:14:01887 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06888 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58889 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06890 &handle, pool_.get(), connect_job_factory_,
891 TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09892 int rv = handle.Init(
[email protected]a512f5982009-08-18 16:01:06893 "a", ignored_request_info_, kDefaultPriority, &callback,
894 pool_.get(), NULL);
[email protected]f6d1d6eb2009-06-24 20:16:09895 ASSERT_EQ(ERR_IO_PENDING, rv);
896
897 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:58898 handle.Reset();
899}
[email protected]f6d1d6eb2009-06-24 20:16:09900
[email protected]2ab05b52009-07-01 23:57:58901TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:53902 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20903
[email protected]0b7648c2009-07-06 20:14:01904 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:06905 ClientSocketHandle handle;
[email protected]2ab05b52009-07-01 23:57:58906 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:06907 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:58908 int rv = handle.Init(
[email protected]a512f5982009-08-18 16:01:06909 "a", ignored_request_info_, kDefaultPriority, &callback,
910 pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:58911 ASSERT_EQ(ERR_IO_PENDING, rv);
912
913 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09914 handle.Reset();
915}
916
917// Make sure that pending requests get serviced after active requests get
918// cancelled.
[email protected]ab838892009-06-30 18:49:05919TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:53920 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20921
[email protected]0b7648c2009-07-06 20:14:01922 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09923
[email protected]c9d6a1d2009-07-14 16:15:20924 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
925 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
926 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
927 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
928 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
929 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
930 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:09931
[email protected]c9d6a1d2009-07-14 16:15:20932 // Now, kDefaultMaxSocketsPerGroup requests should be active.
933 // Let's cancel them.
934 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:33935 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
936 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09937 }
938
[email protected]f6d1d6eb2009-06-24 20:16:09939 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:20940 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
941 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:33942 requests_[i]->handle()->Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09943 }
944
[email protected]75439d3b2009-07-23 22:11:17945 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]f6d1d6eb2009-06-24 20:16:09946}
947
948// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:05949TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:53950 const size_t kMaxSockets = 5;
951 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20952
[email protected]0b7648c2009-07-06 20:14:01953 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09954
[email protected]211d21722009-07-22 15:48:53955 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
956 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:09957
958 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:53959 for (size_t i = 0; i < kNumberOfRequests; ++i)
960 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:09961
[email protected]211d21722009-07-22 15:48:53962 for (size_t i = 0; i < kNumberOfRequests; ++i)
963 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09964}
965
[email protected]5fc08e32009-07-15 17:09:57966TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:53967 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57968
969 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
970
[email protected]a512f5982009-08-18 16:01:06971 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a6c59f62009-07-29 16:33:33972 int rv = req.handle()->Init(
[email protected]a512f5982009-08-18 16:01:06973 "a", ignored_request_info_, kDefaultPriority, &req, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:57974 EXPECT_EQ(ERR_IO_PENDING, rv);
975
976 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:33977 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:57978
[email protected]ec08bb22009-08-12 00:25:12979 rv = req.handle()->Init(
[email protected]a512f5982009-08-18 16:01:06980 "a", ignored_request_info_, kDefaultPriority, &req, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:57981 EXPECT_EQ(ERR_IO_PENDING, rv);
982 EXPECT_EQ(OK, req.WaitForResult());
983
[email protected]a6c59f62009-07-29 16:33:33984 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:17985 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:57986 EXPECT_EQ(2, client_socket_factory_.allocation_count());
987}
988
[email protected]2ab05b52009-07-01 23:57:58989// A pending asynchronous job completes, which will free up a socket slot. The
990// next job finishes synchronously. The callback for the asynchronous job
991// should be first though.
992TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:53993 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20994
[email protected]2ab05b52009-07-01 23:57:58995 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:01996 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:58997
998 // Start job 1 (async error).
[email protected]a512f5982009-08-18 16:01:06999 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]684970b2009-08-14 04:54:461000 int rv = req1.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061001 kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581002 EXPECT_EQ(ERR_IO_PENDING, rv);
1003
1004 // Start job 2 (async error).
[email protected]a512f5982009-08-18 16:01:061005 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121006 rv = req2.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061007 "a", ignored_request_info_, kDefaultPriority, &req2, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581008 EXPECT_EQ(ERR_IO_PENDING, rv);
1009
1010 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:011011 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:581012
1013 // Request 3 does not have a ConnectJob yet. It's just pending.
[email protected]a512f5982009-08-18 16:01:061014 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121015 rv = req3.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061016 "a", ignored_request_info_, kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]2ab05b52009-07-01 23:57:581017 EXPECT_EQ(ERR_IO_PENDING, rv);
1018
1019 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1020 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1021 EXPECT_EQ(OK, req3.WaitForResult());
1022
1023 ASSERT_EQ(3U, request_order_.size());
1024
1025 // After job 1 finishes unsuccessfully, it will try to process the pending
1026 // requests queue, so it starts up job 3 for request 3. This job
1027 // synchronously succeeds, so the request order is 1, 3, 2.
1028 EXPECT_EQ(&req1, request_order_[0]);
1029 EXPECT_EQ(&req2, request_order_[2]);
1030 EXPECT_EQ(&req3, request_order_[1]);
1031}
1032
[email protected]5fc08e32009-07-15 17:09:571033// When a ConnectJob is coupled to a request, even if a free socket becomes
1034// available, the request will be serviced by the ConnectJob.
1035TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531036 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]d80a4322009-08-14 07:07:491037 EnableLateBindingOfSockets(false);
[email protected]5fc08e32009-07-15 17:09:571038
1039 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321040 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571041
[email protected]a512f5982009-08-18 16:01:061042 TestSocketRequest req1(&request_order_, &completion_count_);
1043 int rv = req1.handle()->Init("a", ignored_request_info_, kDefaultPriority,
1044 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571045 EXPECT_EQ(ERR_IO_PENDING, rv);
1046 EXPECT_EQ(OK, req1.WaitForResult());
1047
1048 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1049 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1050
[email protected]a512f5982009-08-18 16:01:061051 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121052 rv = req2.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061053 "a", ignored_request_info_, kDefaultPriority, &req2, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571054 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331055 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571056 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1057
1058 // Job 2 is pending. Start request 3 (which has no associated job since it
1059 // will use the idle socket).
1060
[email protected]a512f5982009-08-18 16:01:061061 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121062 rv = req3.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061063 "a", ignored_request_info_, kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571064 EXPECT_EQ(OK, rv);
1065
[email protected]a6c59f62009-07-29 16:33:331066 EXPECT_FALSE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571067 client_socket_factory_.SignalJobs();
1068 EXPECT_EQ(OK, req2.WaitForResult());
1069
1070 ASSERT_EQ(2U, request_order_.size());
1071 EXPECT_EQ(&req1, request_order_[0]);
1072 EXPECT_EQ(&req2, request_order_[1]);
1073 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1074}
1075
[email protected]2b7523d2009-07-29 20:29:231076// Regression test for http://crbug.com/17985.
1077TEST_F(ClientSocketPoolBaseTest, GroupWithPendingRequestsIsNotEmpty) {
1078 const int kMaxSockets = 3;
1079 const int kMaxSocketsPerGroup = 2;
1080 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1081
1082 const int kHighPriority = kDefaultPriority + 100;
1083
1084 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1085 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1086
1087 // This is going to be a pending request in an otherwise empty group.
1088 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1089
1090 // Reach the maximum socket limit.
1091 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1092
1093 // Create a stalled group with high priorities.
1094 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1095 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1096 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1097
1098 // Release the first two sockets from "a", which will make room
1099 // for requests from "c". After that "a" will have no active sockets
1100 // and one pending request.
1101 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1102 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1103
1104 // Closing idle sockets should not get us into trouble, but in the bug
1105 // we were hitting a CHECK here.
1106 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1107 pool_->CloseIdleSockets();
1108 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1109}
1110
[email protected]5fc08e32009-07-15 17:09:571111class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1112 protected:
1113 virtual void SetUp() {
1114 ClientSocketPoolBaseTest::SetUp();
[email protected]d80a4322009-08-14 07:07:491115 EnableLateBindingOfSockets(true);
[email protected]5fc08e32009-07-15 17:09:571116 }
1117};
1118
[email protected]6e713f02009-08-06 02:56:401119// Even though a timeout is specified, it doesn't time out on a synchronous
1120// completion.
1121TEST_F(ClientSocketPoolBaseTest_LateBinding,
1122 ConnectJob_NoTimeoutOnSynchronousCompletion) {
1123 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061124 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491125 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401126 scoped_ptr<TestConnectJob> job(
1127 new TestConnectJob(TestConnectJob::kMockJob,
[email protected]ec08bb22009-08-12 00:25:121128 "a",
[email protected]6e713f02009-08-06 02:56:401129 request,
1130 base::TimeDelta::FromMicroseconds(1),
1131 &delegate,
1132 &client_socket_factory_));
1133 EXPECT_EQ(OK, job->Connect());
1134}
1135
1136TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) {
1137 TestConnectJobDelegate delegate;
[email protected]a512f5982009-08-18 16:01:061138 ClientSocketHandle ignored;
[email protected]d80a4322009-08-14 07:07:491139 TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL);
[email protected]6e713f02009-08-06 02:56:401140 // Deleted by TestConnectJobDelegate.
1141 TestConnectJob* job =
1142 new TestConnectJob(TestConnectJob::kMockPendingJob,
[email protected]ec08bb22009-08-12 00:25:121143 "a",
[email protected]6e713f02009-08-06 02:56:401144 request,
1145 base::TimeDelta::FromMicroseconds(1),
1146 &delegate,
1147 &client_socket_factory_);
1148 ASSERT_EQ(ERR_IO_PENDING, job->Connect());
1149 PlatformThread::Sleep(1);
1150 EXPECT_EQ(ERR_TIMED_OUT, delegate.WaitForResult());
1151}
1152
[email protected]5fc08e32009-07-15 17:09:571153TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531154 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571155
1156 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061157 ClientSocketHandle handle;
[email protected]684970b2009-08-14 04:54:461158 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority,
[email protected]a512f5982009-08-18 16:01:061159 &callback, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571160 EXPECT_TRUE(handle.is_initialized());
1161 EXPECT_TRUE(handle.socket());
1162 handle.Reset();
1163}
1164
1165TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531166 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571167
1168 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061169 TestSocketRequest req(&request_order_, &completion_count_);
1170 int rv = req.handle()->Init("a", ignored_request_info_, 0, &req,
1171 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571172 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331173 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571174 EXPECT_EQ(OK, req.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331175 EXPECT_TRUE(req.handle()->is_initialized());
1176 EXPECT_TRUE(req.handle()->socket());
1177 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571178}
1179
1180TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531181 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571182
1183 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]a512f5982009-08-18 16:01:061184 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571185 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]684970b2009-08-14 04:54:461186 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061187 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571188}
1189
1190TEST_F(ClientSocketPoolBaseTest_LateBinding,
1191 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531192 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571193
1194 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]a512f5982009-08-18 16:01:061195 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571196 EXPECT_EQ(ERR_IO_PENDING,
[email protected]a512f5982009-08-18 16:01:061197 req.handle()->Init("a", ignored_request_info_, kDefaultPriority,
1198 &req, pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331199 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req.handle()));
[email protected]5fc08e32009-07-15 17:09:571200 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1201}
1202
1203TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531204 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571205
1206 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1207 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1208 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1209 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1210 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1211 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1212 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1213
1214 ReleaseAllConnections(KEEP_ALIVE);
1215
1216 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1217 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171218 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571219
1220 EXPECT_EQ(1, GetOrderOfRequest(1));
1221 EXPECT_EQ(2, GetOrderOfRequest(2));
1222 EXPECT_EQ(6, GetOrderOfRequest(3));
1223 EXPECT_EQ(4, GetOrderOfRequest(4));
1224 EXPECT_EQ(3, GetOrderOfRequest(5));
1225 EXPECT_EQ(5, GetOrderOfRequest(6));
1226 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171227
1228 // Make sure we test order of all requests made.
1229 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571230}
1231
1232TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531233 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571234
1235 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1236 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1237 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1238 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1239 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1240 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1241 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1242
1243 ReleaseAllConnections(NO_KEEP_ALIVE);
1244
1245 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1246 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1247
1248 EXPECT_EQ(static_cast<int>(requests_.size()),
1249 client_socket_factory_.allocation_count());
[email protected]75439d3b2009-07-23 22:11:171250 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571251}
1252
1253// This test will start up a RequestSocket() and then immediately Cancel() it.
1254// The pending connect job will be cancelled and should not call back into
1255// ClientSocketPoolBase.
1256TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531257 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571258
1259 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061260 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571261 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:461262 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061263 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]a6c59f62009-07-29 16:33:331264 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571265}
1266
1267TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531268 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571269
1270 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061271 TestSocketRequest req(&request_order_, &completion_count_);
1272 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571273
1274 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:461275 req.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061276 kDefaultPriority, &req, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571277 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:461278 req2.handle()->Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061279 kDefaultPriority, &req2, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571280
[email protected]a6c59f62009-07-29 16:33:331281 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571282
1283 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331284 req2.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571285}
1286
1287TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531288 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571289
1290 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061291 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571292 TestCompletionCallback callback;
[email protected]a512f5982009-08-18 16:01:061293 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]5fc08e32009-07-15 17:09:571294
1295 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:461296 handle.Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061297 kDefaultPriority, &callback, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571298
1299 handle.Reset();
1300
1301 TestCompletionCallback callback2;
1302 EXPECT_EQ(ERR_IO_PENDING,
[email protected]684970b2009-08-14 04:54:461303 handle.Init("a", ignored_request_info_,
[email protected]a512f5982009-08-18 16:01:061304 kDefaultPriority, &callback2, pool_.get(), NULL));
[email protected]5fc08e32009-07-15 17:09:571305
1306 EXPECT_EQ(OK, callback2.WaitForResult());
1307 EXPECT_FALSE(callback.have_result());
1308
1309 handle.Reset();
1310}
1311
1312TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531313 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571314
1315 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1316 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1317 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1318 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1319 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1320 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1321 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1322
1323 // Cancel a request.
1324 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
[email protected]a6c59f62009-07-29 16:33:331325 EXPECT_FALSE(requests_[index_to_cancel]->handle()->is_initialized());
1326 requests_[index_to_cancel]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571327
1328 ReleaseAllConnections(KEEP_ALIVE);
1329
1330 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1331 client_socket_factory_.allocation_count());
1332 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
[email protected]75439d3b2009-07-23 22:11:171333 completion_count_);
[email protected]5fc08e32009-07-15 17:09:571334
1335 EXPECT_EQ(1, GetOrderOfRequest(1));
1336 EXPECT_EQ(2, GetOrderOfRequest(2));
1337 EXPECT_EQ(5, GetOrderOfRequest(3));
1338 EXPECT_EQ(3, GetOrderOfRequest(4));
1339 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1340 EXPECT_EQ(4, GetOrderOfRequest(6));
1341 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]75439d3b2009-07-23 22:11:171342
1343 // Make sure we test order of all requests made.
1344 EXPECT_EQ(kIndexOutOfBounds, GetOrderOfRequest(8));
[email protected]5fc08e32009-07-15 17:09:571345}
1346
[email protected]974ebd62009-08-03 23:14:341347TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestLimitsJobs) {
[email protected]974ebd62009-08-03 23:14:341348 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1349
[email protected]17a0c6c2009-08-04 00:07:041350 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1351
[email protected]974ebd62009-08-03 23:14:341352 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1353 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1354 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1355 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1356
1357 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1358 requests_[2]->handle()->Reset();
1359 requests_[3]->handle()->Reset();
1360 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1361
1362 requests_[1]->handle()->Reset();
1363 EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->NumConnectJobsInGroup("a"));
1364
1365 requests_[0]->handle()->Reset();
1366 EXPECT_EQ(kDefaultMaxSocketsPerGroup - 1, pool_->NumConnectJobsInGroup("a"));
1367}
1368
[email protected]5fc08e32009-07-15 17:09:571369TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531370 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571371
1372 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061373 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571374 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061375 &handle, pool_.get(), connect_job_factory_,
1376 TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571377 int rv = handle.Init(
[email protected]a512f5982009-08-18 16:01:061378 "a", ignored_request_info_, kDefaultPriority, &callback,
1379 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571380 ASSERT_EQ(ERR_IO_PENDING, rv);
1381
1382 EXPECT_EQ(OK, callback.WaitForResult());
1383 handle.Reset();
1384}
1385
1386TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531387 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571388
1389 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]a512f5982009-08-18 16:01:061390 ClientSocketHandle handle;
[email protected]5fc08e32009-07-15 17:09:571391 RequestSocketCallback callback(
[email protected]a512f5982009-08-18 16:01:061392 &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571393 int rv = handle.Init(
[email protected]a512f5982009-08-18 16:01:061394 "a", ignored_request_info_, kDefaultPriority, &callback,
1395 pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571396 ASSERT_EQ(ERR_IO_PENDING, rv);
1397
1398 EXPECT_EQ(OK, callback.WaitForResult());
1399 handle.Reset();
1400}
1401
1402// Make sure that pending requests get serviced after active requests get
1403// cancelled.
1404TEST_F(ClientSocketPoolBaseTest_LateBinding,
1405 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531406 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571407
1408 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1409
1410 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1411 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1412 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1414 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1415 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1416 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1417
1418 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1419 // Let's cancel them.
1420 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
[email protected]a6c59f62009-07-29 16:33:331421 ASSERT_FALSE(requests_[i]->handle()->is_initialized());
1422 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571423 }
1424
1425 // Let's wait for the rest to complete now.
1426 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1427 EXPECT_EQ(OK, requests_[i]->WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331428 requests_[i]->handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571429 }
1430
[email protected]75439d3b2009-07-23 22:11:171431 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571432}
1433
1434// Make sure that pending requests get serviced after active requests fail.
1435TEST_F(ClientSocketPoolBaseTest_LateBinding,
1436 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531437 const int kMaxSockets = 5;
1438 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571439
1440 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1441
[email protected]211d21722009-07-22 15:48:531442 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1443 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571444
1445 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531446 for (int i = 0; i < kNumberOfRequests; ++i)
1447 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571448
[email protected]211d21722009-07-22 15:48:531449 for (int i = 0; i < kNumberOfRequests; ++i)
1450 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571451}
1452
1453TEST_F(ClientSocketPoolBaseTest_LateBinding,
1454 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531455 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571456
1457 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1458
[email protected]a512f5982009-08-18 16:01:061459 TestSocketRequest req(&request_order_, &completion_count_);
[email protected]a6c59f62009-07-29 16:33:331460 int rv = req.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061461 "a", ignored_request_info_, kDefaultPriority, &req, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571462 EXPECT_EQ(ERR_IO_PENDING, rv);
1463
1464 // Cancel the active request.
[email protected]a6c59f62009-07-29 16:33:331465 req.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571466
[email protected]ec08bb22009-08-12 00:25:121467 rv = req.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061468 "a", ignored_request_info_, kDefaultPriority, &req, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571469 EXPECT_EQ(ERR_IO_PENDING, rv);
1470 EXPECT_EQ(OK, req.WaitForResult());
1471
[email protected]a6c59f62009-07-29 16:33:331472 EXPECT_FALSE(req.handle()->is_reused());
[email protected]75439d3b2009-07-23 22:11:171473 EXPECT_EQ(1U, completion_count_);
[email protected]5fc08e32009-07-15 17:09:571474 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1475}
1476
1477// When requests and ConnectJobs are not coupled, the request will get serviced
1478// by whatever comes first.
1479TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531480 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571481
1482 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321483 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571484
[email protected]a512f5982009-08-18 16:01:061485 TestSocketRequest req1(&request_order_, &completion_count_);
1486 int rv = req1.handle()->Init("a", ignored_request_info_, kDefaultPriority,
1487 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571488 EXPECT_EQ(ERR_IO_PENDING, rv);
1489 EXPECT_EQ(OK, req1.WaitForResult());
1490
1491 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1492 // without a job.
1493 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1494
[email protected]a512f5982009-08-18 16:01:061495 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121496 rv = req2.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061497 "a", ignored_request_info_, kDefaultPriority, &req2, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571498 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a512f5982009-08-18 16:01:061499 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121500 rv = req3.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061501 "a", ignored_request_info_, kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571502 EXPECT_EQ(ERR_IO_PENDING, rv);
1503
1504 // Both Requests 2 and 3 are pending. We release socket 1 which should
1505 // service request 2. Request 3 should still be waiting.
[email protected]a6c59f62009-07-29 16:33:331506 req1.handle()->Reset();
[email protected]5fc08e32009-07-15 17:09:571507 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
[email protected]a6c59f62009-07-29 16:33:331508 ASSERT_TRUE(req2.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571509 EXPECT_EQ(OK, req2.WaitForResult());
[email protected]a6c59f62009-07-29 16:33:331510 EXPECT_FALSE(req3.handle()->socket());
[email protected]5fc08e32009-07-15 17:09:571511
1512 // Signal job 2, which should service request 3.
1513
1514 client_socket_factory_.SignalJobs();
1515 EXPECT_EQ(OK, req3.WaitForResult());
1516
1517 ASSERT_EQ(3U, request_order_.size());
1518 EXPECT_EQ(&req1, request_order_[0]);
1519 EXPECT_EQ(&req2, request_order_[1]);
1520 EXPECT_EQ(&req3, request_order_[2]);
1521 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1522}
1523
1524// The requests are not coupled to the jobs. So, the requests should finish in
1525// their priority / insertion order.
1526TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531527 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571528 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321529 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571530
[email protected]a512f5982009-08-18 16:01:061531 TestSocketRequest req1(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121532 int rv = req1.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061533 "a", ignored_request_info_, kDefaultPriority, &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571534 EXPECT_EQ(ERR_IO_PENDING, rv);
1535
[email protected]a512f5982009-08-18 16:01:061536 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121537 rv = req2.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061538 "a", ignored_request_info_, kDefaultPriority, &req2, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571539 EXPECT_EQ(ERR_IO_PENDING, rv);
1540
1541 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321542 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571543
[email protected]a512f5982009-08-18 16:01:061544 TestSocketRequest req3(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121545 rv = req3.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061546 "a", ignored_request_info_, kDefaultPriority, &req3, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571547 EXPECT_EQ(ERR_IO_PENDING, rv);
1548
1549 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1550 EXPECT_EQ(OK, req2.WaitForResult());
1551 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1552
1553 ASSERT_EQ(3U, request_order_.size());
1554 EXPECT_EQ(&req1, request_order_[0]);
1555 EXPECT_EQ(&req2, request_order_[1]);
1556 EXPECT_EQ(&req3, request_order_[2]);
1557}
1558
[email protected]f0109a7d2009-07-16 00:09:521559TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531560 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571561 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321562 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571563
[email protected]a512f5982009-08-18 16:01:061564 TestSocketRequest req1(&request_order_, &completion_count_);
1565 int rv = req1.handle()->Init("a", ignored_request_info_, kDefaultPriority,
1566 &req1, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571567 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331568 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571569
1570 MessageLoop::current()->RunAllPending();
1571
[email protected]a512f5982009-08-18 16:01:061572 TestSocketRequest req2(&request_order_, &completion_count_);
[email protected]ec08bb22009-08-12 00:25:121573 rv = req2.handle()->Init(
[email protected]a512f5982009-08-18 16:01:061574 "a", ignored_request_info_, kDefaultPriority, &req2, pool_.get(), NULL);
[email protected]5fc08e32009-07-15 17:09:571575 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a6c59f62009-07-29 16:33:331576 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle()->GetLoadState());
1577 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle()->GetLoadState());
[email protected]5fc08e32009-07-15 17:09:571578}
1579
[email protected]2b7523d2009-07-29 20:29:231580// Regression test for http://crbug.com/17985.
1581TEST_F(ClientSocketPoolBaseTest_LateBinding,
1582 GroupWithPendingRequestsIsNotEmpty) {
1583 const int kMaxSockets = 3;
1584 const int kMaxSocketsPerGroup = 2;
1585 CreatePool(kMaxSockets, kMaxSocketsPerGroup);
1586
1587 const int kHighPriority = kDefaultPriority + 100;
1588
1589 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1590 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1591
1592 // This is going to be a pending request in an otherwise empty group.
1593 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1594
1595 // Reach the maximum socket limit.
1596 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
1597
1598 // Create a stalled group with high priorities.
1599 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1600 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kHighPriority));
1601 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
1602
1603 // Release the first two sockets from "a", which will make room
1604 // for requests from "c". After that "a" will have no active sockets
1605 // and one pending request.
1606 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1607 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
1608
1609 // Closing idle sockets should not get us into trouble, but in the bug
1610 // we were hitting a CHECK here.
1611 EXPECT_EQ(2, pool_->IdleSocketCountInGroup("a"));
1612 pool_->CloseIdleSockets();
1613 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1614}
1615
[email protected]f6d1d6eb2009-06-24 20:16:091616} // namespace
1617
1618} // namespace net