blob: f5ad77e88b5f92c8d1715fa03c1dea56d34bdbd2 [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]c9d6a1d2009-07-14 16:15:209#include "base/scoped_vector.h"
[email protected]f6d1d6eb2009-06-24 20:16:0910#include "net/base/net_errors.h"
11#include "net/base/test_completion_callback.h"
12#include "net/socket/client_socket.h"
13#include "net/socket/client_socket_factory.h"
14#include "net/socket/client_socket_handle.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace net {
18
19namespace {
20
[email protected]211d21722009-07-22 15:48:5321const int kDefaultMaxSockets = 4;
22
[email protected]c9d6a1d2009-07-14 16:15:2023const int kDefaultMaxSocketsPerGroup = 2;
[email protected]f6d1d6eb2009-06-24 20:16:0924
[email protected]0b7648c2009-07-06 20:14:0125const int kDefaultPriority = 5;
26
[email protected]f6d1d6eb2009-06-24 20:16:0927class MockClientSocket : public ClientSocket {
28 public:
29 MockClientSocket() : connected_(false) {}
30
[email protected]ab838892009-06-30 18:49:0531 // Socket methods:
32 virtual int Read(
33 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
34 return ERR_UNEXPECTED;
35 }
36
37 virtual int Write(
38 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
39 return ERR_UNEXPECTED;
40 }
41
[email protected]f6d1d6eb2009-06-24 20:16:0942 // ClientSocket methods:
[email protected]ab838892009-06-30 18:49:0543
[email protected]f6d1d6eb2009-06-24 20:16:0944 virtual int Connect(CompletionCallback* callback) {
45 connected_ = true;
46 return OK;
47 }
[email protected]f6d1d6eb2009-06-24 20:16:0948
[email protected]ab838892009-06-30 18:49:0549 virtual void Disconnect() { connected_ = false; }
50 virtual bool IsConnected() const { return connected_; }
51 virtual bool IsConnectedAndIdle() const { return connected_; }
[email protected]0b7648c2009-07-06 20:14:0152
[email protected]ab838892009-06-30 18:49:0553#if defined(OS_LINUX)
54 virtual int GetPeerName(struct sockaddr* /* name */,
55 socklen_t* /* namelen */) {
56 return 0;
[email protected]f6d1d6eb2009-06-24 20:16:0957 }
[email protected]ab838892009-06-30 18:49:0558#endif
[email protected]f6d1d6eb2009-06-24 20:16:0959
60 private:
61 bool connected_;
[email protected]f6d1d6eb2009-06-24 20:16:0962
[email protected]ab838892009-06-30 18:49:0563 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
[email protected]f6d1d6eb2009-06-24 20:16:0964};
65
[email protected]5fc08e32009-07-15 17:09:5766class TestConnectJob;
67
[email protected]f6d1d6eb2009-06-24 20:16:0968class MockClientSocketFactory : public ClientSocketFactory {
69 public:
[email protected]ab838892009-06-30 18:49:0570 MockClientSocketFactory() : allocation_count_(0) {}
[email protected]f6d1d6eb2009-06-24 20:16:0971
72 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses) {
73 allocation_count_++;
[email protected]ab838892009-06-30 18:49:0574 return NULL;
[email protected]f6d1d6eb2009-06-24 20:16:0975 }
76
77 virtual SSLClientSocket* CreateSSLClientSocket(
78 ClientSocket* transport_socket,
79 const std::string& hostname,
80 const SSLConfig& ssl_config) {
81 NOTIMPLEMENTED();
82 return NULL;
83 }
84
[email protected]5fc08e32009-07-15 17:09:5785 void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
86 void SignalJobs();
87
[email protected]f6d1d6eb2009-06-24 20:16:0988 int allocation_count() const { return allocation_count_; }
89
[email protected]f6d1d6eb2009-06-24 20:16:0990 private:
91 int allocation_count_;
[email protected]5fc08e32009-07-15 17:09:5792 std::vector<TestConnectJob*> waiting_jobs_;
[email protected]f6d1d6eb2009-06-24 20:16:0993};
94
95class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
96 public:
97 TestSocketRequest(
98 ClientSocketPool* pool,
99 std::vector<TestSocketRequest*>* request_order)
100 : handle(pool), request_order_(request_order) {}
101
102 ClientSocketHandle handle;
103
104 int WaitForResult() {
105 return callback_.WaitForResult();
106 }
107
108 virtual void RunWithParams(const Tuple1<int>& params) {
109 callback_.RunWithParams(params);
110 completion_count++;
111 request_order_->push_back(this);
112 }
113
[email protected]c9d6a1d2009-07-14 16:15:20114 static size_t completion_count;
[email protected]f6d1d6eb2009-06-24 20:16:09115
116 private:
117 std::vector<TestSocketRequest*>* request_order_;
118 TestCompletionCallback callback_;
119};
120
[email protected]c9d6a1d2009-07-14 16:15:20121size_t TestSocketRequest::completion_count = 0;
[email protected]f6d1d6eb2009-06-24 20:16:09122
[email protected]ab838892009-06-30 18:49:05123class TestConnectJob : public ConnectJob {
124 public:
125 enum JobType {
126 kMockJob,
127 kMockFailingJob,
128 kMockPendingJob,
129 kMockPendingFailingJob,
[email protected]5fc08e32009-07-15 17:09:57130 kMockWaitingJob,
131 kMockAdvancingLoadStateJob,
[email protected]ab838892009-06-30 18:49:05132 };
133
134 TestConnectJob(JobType job_type,
135 const std::string& group_name,
136 const ClientSocketPoolBase::Request& request,
137 ConnectJob::Delegate* delegate,
[email protected]5fc08e32009-07-15 17:09:57138 MockClientSocketFactory* client_socket_factory)
[email protected]2ab05b52009-07-01 23:57:58139 : ConnectJob(group_name, request.handle, delegate),
140 job_type_(job_type),
[email protected]ab838892009-06-30 18:49:05141 client_socket_factory_(client_socket_factory),
[email protected]ab838892009-06-30 18:49:05142 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
143
144 // ConnectJob methods:
145
146 virtual int Connect() {
147 AddressList ignored;
148 client_socket_factory_->CreateTCPClientSocket(ignored);
149 switch (job_type_) {
150 case kMockJob:
151 return DoConnect(true /* successful */, false /* sync */);
152 case kMockFailingJob:
153 return DoConnect(false /* error */, false /* sync */);
154 case kMockPendingJob:
[email protected]5fc08e32009-07-15 17:09:57155 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05156 MessageLoop::current()->PostTask(
157 FROM_HERE,
158 method_factory_.NewRunnableMethod(
159 &TestConnectJob::DoConnect,
160 true /* successful */,
161 true /* async */));
162 return ERR_IO_PENDING;
163 case kMockPendingFailingJob:
[email protected]5fc08e32009-07-15 17:09:57164 set_load_state(LOAD_STATE_CONNECTING);
[email protected]ab838892009-06-30 18:49:05165 MessageLoop::current()->PostTask(
166 FROM_HERE,
167 method_factory_.NewRunnableMethod(
168 &TestConnectJob::DoConnect,
169 false /* error */,
170 true /* async */));
171 return ERR_IO_PENDING;
[email protected]5fc08e32009-07-15 17:09:57172 case kMockWaitingJob:
173 client_socket_factory_->WaitForSignal(this);
174 waiting_success_ = true;
175 return ERR_IO_PENDING;
176 case kMockAdvancingLoadStateJob:
177 MessageLoop::current()->PostTask(
178 FROM_HERE,
179 method_factory_.NewRunnableMethod(
180 &TestConnectJob::AdvanceLoadState, load_state()));
181 return ERR_IO_PENDING;
[email protected]ab838892009-06-30 18:49:05182 default:
183 NOTREACHED();
184 return ERR_FAILED;
185 }
186 }
187
[email protected]5fc08e32009-07-15 17:09:57188 void Signal() {
189 DoConnect(waiting_success_, true /* async */);
190 }
191
[email protected]ab838892009-06-30 18:49:05192 private:
193 int DoConnect(bool succeed, bool was_async) {
194 int result = ERR_CONNECTION_FAILED;
[email protected]ab838892009-06-30 18:49:05195 if (succeed) {
196 result = OK;
[email protected]2ab05b52009-07-01 23:57:58197 set_socket(new MockClientSocket());
198 socket()->Connect(NULL);
[email protected]ab838892009-06-30 18:49:05199 }
[email protected]2ab05b52009-07-01 23:57:58200
201 if (was_async)
202 delegate()->OnConnectJobComplete(result, this);
[email protected]ab838892009-06-30 18:49:05203 return result;
204 }
205
[email protected]5fc08e32009-07-15 17:09:57206 void AdvanceLoadState(LoadState state) {
207 int tmp = state;
208 tmp++;
209 state = static_cast<LoadState>(tmp);
210 set_load_state(state);
211 // Post a delayed task so RunAllPending() won't run it.
212 MessageLoop::current()->PostDelayedTask(
213 FROM_HERE,
214 method_factory_.NewRunnableMethod(&TestConnectJob::AdvanceLoadState,
215 state),
216 1 /* 1ms delay */);
217 }
218
219 bool waiting_success_;
[email protected]ab838892009-06-30 18:49:05220 const JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57221 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05222 ScopedRunnableMethodFactory<TestConnectJob> method_factory_;
223
224 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
225};
226
227class TestConnectJobFactory : public ClientSocketPoolBase::ConnectJobFactory {
228 public:
[email protected]5fc08e32009-07-15 17:09:57229 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
[email protected]ab838892009-06-30 18:49:05230 : job_type_(TestConnectJob::kMockJob),
231 client_socket_factory_(client_socket_factory) {}
232
233 virtual ~TestConnectJobFactory() {}
234
235 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
236
237 // ConnectJobFactory methods:
238
239 virtual ConnectJob* NewConnectJob(
240 const std::string& group_name,
241 const ClientSocketPoolBase::Request& request,
242 ConnectJob::Delegate* delegate) const {
243 return new TestConnectJob(job_type_,
244 group_name,
245 request,
246 delegate,
247 client_socket_factory_);
248 }
249
250 private:
251 TestConnectJob::JobType job_type_;
[email protected]5fc08e32009-07-15 17:09:57252 MockClientSocketFactory* const client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05253
254 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
255};
256
257class TestClientSocketPool : public ClientSocketPool {
258 public:
259 TestClientSocketPool(
[email protected]211d21722009-07-22 15:48:53260 int max_sockets,
[email protected]ab838892009-06-30 18:49:05261 int max_sockets_per_group,
262 ClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
263 : base_(new ClientSocketPoolBase(
[email protected]211d21722009-07-22 15:48:53264 max_sockets, max_sockets_per_group, connect_job_factory)) {}
[email protected]ab838892009-06-30 18:49:05265
266 virtual int RequestSocket(
267 const std::string& group_name,
268 const HostResolver::RequestInfo& resolve_info,
269 int priority,
270 ClientSocketHandle* handle,
271 CompletionCallback* callback) {
272 return base_->RequestSocket(
273 group_name, resolve_info, priority, handle, callback);
274 }
275
276 virtual void CancelRequest(
277 const std::string& group_name,
278 const ClientSocketHandle* handle) {
279 base_->CancelRequest(group_name, handle);
280 }
281
282 virtual void ReleaseSocket(
283 const std::string& group_name,
284 ClientSocket* socket) {
285 base_->ReleaseSocket(group_name, socket);
286 }
287
288 virtual void CloseIdleSockets() {
289 base_->CloseIdleSockets();
290 }
291
292 virtual int IdleSocketCount() const { return base_->idle_socket_count(); }
293
294 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
295 return base_->IdleSocketCountInGroup(group_name);
296 }
297
298 virtual LoadState GetLoadState(const std::string& group_name,
299 const ClientSocketHandle* handle) const {
300 return base_->GetLoadState(group_name, handle);
301 }
302
[email protected]211d21722009-07-22 15:48:53303 const ClientSocketPoolBase* base() const { return base_.get(); }
[email protected]c9d6a1d2009-07-14 16:15:20304
[email protected]ab838892009-06-30 18:49:05305 private:
306 const scoped_refptr<ClientSocketPoolBase> base_;
307
308 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
309};
310
[email protected]5fc08e32009-07-15 17:09:57311void MockClientSocketFactory::SignalJobs() {
312 for (std::vector<TestConnectJob*>::iterator it = waiting_jobs_.begin();
313 it != waiting_jobs_.end(); ++it) {
314 (*it)->Signal();
315 }
316 waiting_jobs_.clear();
317}
318
[email protected]ab838892009-06-30 18:49:05319class ClientSocketPoolBaseTest : public testing::Test {
[email protected]f6d1d6eb2009-06-24 20:16:09320 protected:
[email protected]ab838892009-06-30 18:49:05321 ClientSocketPoolBaseTest()
322 : ignored_request_info_("ignored", 80),
323 connect_job_factory_(
[email protected]c9d6a1d2009-07-14 16:15:20324 new TestConnectJobFactory(&client_socket_factory_)) {}
325
[email protected]211d21722009-07-22 15:48:53326 void CreatePool(int max_sockets, int max_sockets_per_group) {
[email protected]c9d6a1d2009-07-14 16:15:20327 DCHECK(!pool_.get());
[email protected]211d21722009-07-22 15:48:53328 pool_ = new TestClientSocketPool(max_sockets,
329 max_sockets_per_group,
[email protected]c9d6a1d2009-07-14 16:15:20330 connect_job_factory_);
331 }
[email protected]f6d1d6eb2009-06-24 20:16:09332
333 virtual void SetUp() {
[email protected]f6d1d6eb2009-06-24 20:16:09334 TestSocketRequest::completion_count = 0;
335 }
336
337 virtual void TearDown() {
338 // The tests often call Reset() on handles at the end which may post
339 // DoReleaseSocket() tasks.
340 MessageLoop::current()->RunAllPending();
[email protected]211d21722009-07-22 15:48:53341
342 // Need to delete |pool_| before we turn late binding back off. We also need
343 // to delete |requests_| because the pool is reference counted and requests
344 // keep reference to it.
345 // TODO(willchan): Remove this part when late binding becomes the default.
[email protected]5fc08e32009-07-15 17:09:57346 pool_ = NULL;
[email protected]211d21722009-07-22 15:48:53347 requests_.reset();
348
[email protected]5fc08e32009-07-15 17:09:57349 ClientSocketPoolBase::EnableLateBindingOfSockets(false);
[email protected]f6d1d6eb2009-06-24 20:16:09350 }
351
[email protected]c9d6a1d2009-07-14 16:15:20352 int StartRequest(const std::string& group_name, int priority) {
353 DCHECK(pool_.get());
354 TestSocketRequest* request = new TestSocketRequest(pool_.get(),
355 &request_order_);
356 requests_.push_back(request);
357 int rv = request->handle.Init(group_name, ignored_request_info_, priority,
358 request);
359 if (rv != ERR_IO_PENDING)
360 request_order_.push_back(request);
361 return rv;
362 }
[email protected]0b7648c2009-07-06 20:14:01363
[email protected]c9d6a1d2009-07-14 16:15:20364 static const int kIndexOutOfBounds;
365 static const int kRequestNotFound;
[email protected]0b7648c2009-07-06 20:14:01366
[email protected]c9d6a1d2009-07-14 16:15:20367 int GetOrderOfRequest(size_t index) {
368 index--;
369 if (index >= requests_.size())
370 return kIndexOutOfBounds;
371
372 for (size_t i = 0; i < request_order_.size(); i++)
373 if (requests_[index] == request_order_[i])
374 return i + 1;
375
376 return kRequestNotFound;
[email protected]0b7648c2009-07-06 20:14:01377 }
378
379 enum KeepAlive {
380 KEEP_ALIVE,
381 NO_KEEP_ALIVE,
382 };
383
[email protected]211d21722009-07-22 15:48:53384 bool ReleaseOneConnection(KeepAlive keep_alive) {
385 ScopedVector<TestSocketRequest>::iterator i;
386 for (i = requests_.begin(); i != requests_.end(); ++i) {
387 if ((*i)->handle.is_initialized()) {
388 if (keep_alive == NO_KEEP_ALIVE)
389 (*i)->handle.socket()->Disconnect();
390 (*i)->handle.Reset();
391 MessageLoop::current()->RunAllPending();
392 return true;
393 }
394 }
395 return false;
396 }
397
[email protected]c9d6a1d2009-07-14 16:15:20398 void ReleaseAllConnections(KeepAlive keep_alive) {
[email protected]0b7648c2009-07-06 20:14:01399 bool released_one;
400 do {
[email protected]211d21722009-07-22 15:48:53401 released_one = ReleaseOneConnection(keep_alive);
[email protected]0b7648c2009-07-06 20:14:01402 } while (released_one);
403 }
404
[email protected]ab838892009-06-30 18:49:05405 HostResolver::RequestInfo ignored_request_info_;
[email protected]f6d1d6eb2009-06-24 20:16:09406 MockClientSocketFactory client_socket_factory_;
[email protected]ab838892009-06-30 18:49:05407 TestConnectJobFactory* const connect_job_factory_;
[email protected]c9d6a1d2009-07-14 16:15:20408 scoped_refptr<TestClientSocketPool> pool_;
409 ScopedVector<TestSocketRequest> requests_;
[email protected]f6d1d6eb2009-06-24 20:16:09410 std::vector<TestSocketRequest*> request_order_;
411};
412
[email protected]c9d6a1d2009-07-14 16:15:20413// static
414const int ClientSocketPoolBaseTest::kIndexOutOfBounds = -1;
415
416// static
417const int ClientSocketPoolBaseTest::kRequestNotFound = -2;
418
[email protected]5fc08e32009-07-15 17:09:57419TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:53420 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20421
[email protected]f6d1d6eb2009-06-24 20:16:09422 TestCompletionCallback callback;
423 ClientSocketHandle handle(pool_.get());
[email protected]0b7648c2009-07-06 20:14:01424 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority,
425 &callback));
[email protected]f6d1d6eb2009-06-24 20:16:09426 EXPECT_TRUE(handle.is_initialized());
427 EXPECT_TRUE(handle.socket());
[email protected]f6d1d6eb2009-06-24 20:16:09428 handle.Reset();
429}
430
[email protected]5fc08e32009-07-15 17:09:57431TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:53432 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57433
434 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
435 TestSocketRequest req(pool_.get(), &request_order_);
436 int rv = req.handle.Init("a", ignored_request_info_, 0, &req);
437 EXPECT_EQ(ERR_IO_PENDING, rv);
438 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
439 EXPECT_EQ(OK, req.WaitForResult());
440 EXPECT_TRUE(req.handle.is_initialized());
441 EXPECT_TRUE(req.handle.socket());
442 req.handle.Reset();
443}
444
[email protected]ab838892009-06-30 18:49:05445TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:53446 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20447
[email protected]ab838892009-06-30 18:49:05448 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09449 TestSocketRequest req(pool_.get(), &request_order_);
[email protected]3ae82302009-06-26 06:01:21450 EXPECT_EQ(ERR_CONNECTION_FAILED,
[email protected]0b7648c2009-07-06 20:14:01451 req.handle.Init("a", ignored_request_info_,
452 kDefaultPriority, &req));
[email protected]f6d1d6eb2009-06-24 20:16:09453}
454
[email protected]5fc08e32009-07-15 17:09:57455TEST_F(ClientSocketPoolBaseTest, InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:53456 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57457
458 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
459 TestSocketRequest req(pool_.get(), &request_order_);
460 EXPECT_EQ(ERR_IO_PENDING,
461 req.handle.Init("a", ignored_request_info_, 5, &req));
462 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
463 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
464}
465
[email protected]211d21722009-07-22 15:48:53466TEST_F(ClientSocketPoolBaseTest, TotalLimit) {
467 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
468
469 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
470 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
471 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
472 EXPECT_EQ(OK, StartRequest("d", kDefaultPriority));
473
474 EXPECT_EQ(static_cast<int>(requests_.size()),
475 client_socket_factory_.allocation_count());
476 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
477 TestSocketRequest::completion_count);
478
479 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
480 EXPECT_EQ(ERR_IO_PENDING, StartRequest("f", kDefaultPriority));
481 EXPECT_EQ(ERR_IO_PENDING, StartRequest("g", kDefaultPriority));
482
483 ReleaseAllConnections(KEEP_ALIVE);
484
485 EXPECT_EQ(static_cast<int>(requests_.size()),
486 client_socket_factory_.allocation_count());
487 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
488 TestSocketRequest::completion_count);
489
490 EXPECT_EQ(1, GetOrderOfRequest(1));
491 EXPECT_EQ(2, GetOrderOfRequest(2));
492 EXPECT_EQ(3, GetOrderOfRequest(3));
493 EXPECT_EQ(4, GetOrderOfRequest(4));
494 EXPECT_EQ(5, GetOrderOfRequest(5));
495 EXPECT_EQ(6, GetOrderOfRequest(6));
496 EXPECT_EQ(7, GetOrderOfRequest(7));
497}
498
499TEST_F(ClientSocketPoolBaseTest, TotalLimitReachedNewGroup) {
500 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
501
502 // Reach all limits: max total sockets, and max sockets per group.
503 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
504 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
505 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
506 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
507
508 EXPECT_EQ(static_cast<int>(requests_.size()),
509 client_socket_factory_.allocation_count());
510 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
511 TestSocketRequest::completion_count);
512
513 // Now create a new group and verify that we don't starve it.
514 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
515
516 ReleaseAllConnections(KEEP_ALIVE);
517
518 EXPECT_EQ(static_cast<int>(requests_.size()),
519 client_socket_factory_.allocation_count());
520 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
521 TestSocketRequest::completion_count);
522
523 EXPECT_EQ(1, GetOrderOfRequest(1));
524 EXPECT_EQ(2, GetOrderOfRequest(2));
525 EXPECT_EQ(3, GetOrderOfRequest(3));
526 EXPECT_EQ(4, GetOrderOfRequest(4));
527 EXPECT_EQ(5, GetOrderOfRequest(5));
528}
529
530TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsPriority) {
531 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
532
533 EXPECT_EQ(OK, StartRequest("b", 3));
534 EXPECT_EQ(OK, StartRequest("a", 3));
535 EXPECT_EQ(OK, StartRequest("b", 6));
536 EXPECT_EQ(OK, StartRequest("a", 6));
537
538 EXPECT_EQ(static_cast<int>(requests_.size()),
539 client_socket_factory_.allocation_count());
540
541 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 4));
542 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 5));
543 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
544
545 ReleaseAllConnections(KEEP_ALIVE);
546
547 // We're re-using one socket for group "a", and one for "b".
548 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
549 client_socket_factory_.allocation_count());
550 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
551 TestSocketRequest::completion_count);
552
553 // First 4 requests don't have to wait, and finish in order.
554 EXPECT_EQ(1, GetOrderOfRequest(1));
555 EXPECT_EQ(2, GetOrderOfRequest(2));
556 EXPECT_EQ(3, GetOrderOfRequest(3));
557 EXPECT_EQ(4, GetOrderOfRequest(4));
558
559 // Request ("b", 7) has the highest priority, then ("a", 5),
560 // and then ("c", 4).
561 EXPECT_EQ(7, GetOrderOfRequest(5));
562 EXPECT_EQ(6, GetOrderOfRequest(6));
563 EXPECT_EQ(5, GetOrderOfRequest(7));
564}
565
566TEST_F(ClientSocketPoolBaseTest, TotalLimitRespectsGroupLimit) {
567 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
568
569 EXPECT_EQ(OK, StartRequest("a", 3));
570 EXPECT_EQ(OK, StartRequest("a", 6));
571 EXPECT_EQ(OK, StartRequest("b", 3));
572 EXPECT_EQ(OK, StartRequest("b", 6));
573
574 EXPECT_EQ(static_cast<int>(requests_.size()),
575 client_socket_factory_.allocation_count());
576
577 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", 6));
578 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
579 EXPECT_EQ(ERR_IO_PENDING, StartRequest("b", 7));
580
581 ReleaseAllConnections(KEEP_ALIVE);
582
583 // We're re-using one socket for group "a", and one for "b".
584 EXPECT_EQ(static_cast<int>(requests_.size()) - 2,
585 client_socket_factory_.allocation_count());
586 EXPECT_EQ(requests_.size() - kDefaultMaxSockets,
587 TestSocketRequest::completion_count);
588
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));
602}
603
604// Make sure that we count connecting sockets against the total limit.
605TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
606 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
607
608 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
609 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
610 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority));
611
612 // Create one asynchronous request.
613 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
614 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
615
616 // The next synchronous request should wait for its turn.
617 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
618 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority));
619
620 ReleaseAllConnections(KEEP_ALIVE);
621
622 EXPECT_EQ(static_cast<int>(requests_.size()),
623 client_socket_factory_.allocation_count());
624
625 EXPECT_EQ(1, GetOrderOfRequest(1));
626 EXPECT_EQ(2, GetOrderOfRequest(2));
627 EXPECT_EQ(3, GetOrderOfRequest(3));
628 EXPECT_EQ(4, GetOrderOfRequest(4));
629}
630
631// Inside ClientSocketPoolBase we have a may_have_stalled_group flag,
632// which tells it to use more expensive, but accurate, group selection
633// algorithm. Make sure it doesn't get stuck in the "on" state.
634TEST_F(ClientSocketPoolBaseTest, MayHaveStalledGroupReset) {
635 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
636
637 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
638
639 // Reach group socket limit.
640 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
641 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
642 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
643
644 // Reach total limit, but don't request more sockets.
645 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
646 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority));
647 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
648
649 // Request one more socket while we are at the maximum sockets limit.
650 // This should flip the may_have_stalled_group flag.
651 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
652 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
653
654 // After releasing first connection for "a", we're still at the
655 // maximum sockets limit, but every group's pending queue is empty,
656 // so we reset the flag.
657 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
658 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
659
660 // Requesting additional socket while at the total limit should
661 // flip the flag back to "on".
662 EXPECT_EQ(ERR_IO_PENDING, StartRequest("c", kDefaultPriority));
663 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
664
665 // We'll request one more socket to verify that we don't reset the flag
666 // too eagerly.
667 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
668 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
669
670 // We're at the maximum socket limit, and still have one request pending
671 // for "d". Flag should be "on".
672 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
673 EXPECT_TRUE(pool_->base()->may_have_stalled_group());
674
675 // Now every group's pending queue should be empty again.
676 EXPECT_TRUE(ReleaseOneConnection(KEEP_ALIVE));
677 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
678
679 ReleaseAllConnections(KEEP_ALIVE);
680 EXPECT_FALSE(pool_->base()->may_have_stalled_group());
681}
682
[email protected]ab838892009-06-30 18:49:05683TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
[email protected]211d21722009-07-22 15:48:53684 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09685
[email protected]c9d6a1d2009-07-14 16:15:20686 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
687 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
688 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
689 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
690 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
691 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
692 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09693
[email protected]c9d6a1d2009-07-14 16:15:20694 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09695
[email protected]c9d6a1d2009-07-14 16:15:20696 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
697 client_socket_factory_.allocation_count());
698 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
699 TestSocketRequest::completion_count);
[email protected]f6d1d6eb2009-06-24 20:16:09700
[email protected]c9d6a1d2009-07-14 16:15:20701 EXPECT_EQ(1, GetOrderOfRequest(1));
702 EXPECT_EQ(2, GetOrderOfRequest(2));
703 EXPECT_EQ(6, GetOrderOfRequest(3));
704 EXPECT_EQ(4, GetOrderOfRequest(4));
705 EXPECT_EQ(3, GetOrderOfRequest(5));
706 EXPECT_EQ(5, GetOrderOfRequest(6));
707 EXPECT_EQ(7, GetOrderOfRequest(7));
[email protected]f6d1d6eb2009-06-24 20:16:09708}
709
[email protected]ab838892009-06-30 18:49:05710TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:53711 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09712
[email protected]c9d6a1d2009-07-14 16:15:20713 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
714 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
715 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
716 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
717 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
718 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
719 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09720
[email protected]c9d6a1d2009-07-14 16:15:20721 ReleaseAllConnections(NO_KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09722
[email protected]c9d6a1d2009-07-14 16:15:20723 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
724 EXPECT_EQ(OK, requests_[i]->WaitForResult());
725
726 EXPECT_EQ(static_cast<int>(requests_.size()),
727 client_socket_factory_.allocation_count());
728 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
729 TestSocketRequest::completion_count);
[email protected]f6d1d6eb2009-06-24 20:16:09730}
731
732// This test will start up a RequestSocket() and then immediately Cancel() it.
[email protected]ab838892009-06-30 18:49:05733// The pending connect job will be cancelled and should not call back into
734// ClientSocketPoolBase.
735TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:53736 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20737
[email protected]ab838892009-06-30 18:49:05738 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09739 TestSocketRequest req(pool_.get(), &request_order_);
[email protected]ab838892009-06-30 18:49:05740 EXPECT_EQ(ERR_IO_PENDING,
[email protected]0b7648c2009-07-06 20:14:01741 req.handle.Init("a", ignored_request_info_,
742 kDefaultPriority, &req));
[email protected]f6d1d6eb2009-06-24 20:16:09743 req.handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09744}
745
[email protected]ab838892009-06-30 18:49:05746TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:53747 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20748
[email protected]ab838892009-06-30 18:49:05749 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09750 TestSocketRequest req(pool_.get(), &request_order_);
751 TestSocketRequest req2(pool_.get(), &request_order_);
752
[email protected]ab838892009-06-30 18:49:05753 EXPECT_EQ(ERR_IO_PENDING,
[email protected]0b7648c2009-07-06 20:14:01754 req.handle.Init("a", ignored_request_info_,
755 kDefaultPriority, &req));
[email protected]ab838892009-06-30 18:49:05756 EXPECT_EQ(ERR_IO_PENDING,
[email protected]0b7648c2009-07-06 20:14:01757 req2.handle.Init("a", ignored_request_info_,
758 kDefaultPriority, &req2));
[email protected]f6d1d6eb2009-06-24 20:16:09759
760 req.handle.Reset();
761
762 EXPECT_EQ(OK, req2.WaitForResult());
763 req2.handle.Reset();
764}
765
[email protected]ab838892009-06-30 18:49:05766TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:53767 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20768
[email protected]ab838892009-06-30 18:49:05769 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09770 ClientSocketHandle handle(pool_.get());
771 TestCompletionCallback callback;
772 TestSocketRequest req(pool_.get(), &request_order_);
773
[email protected]ab838892009-06-30 18:49:05774 EXPECT_EQ(ERR_IO_PENDING,
[email protected]0b7648c2009-07-06 20:14:01775 handle.Init("a", ignored_request_info_,
776 kDefaultPriority, &callback));
[email protected]f6d1d6eb2009-06-24 20:16:09777
778 handle.Reset();
779
780 TestCompletionCallback callback2;
[email protected]ab838892009-06-30 18:49:05781 EXPECT_EQ(ERR_IO_PENDING,
[email protected]0b7648c2009-07-06 20:14:01782 handle.Init("a", ignored_request_info_,
783 kDefaultPriority, &callback2));
[email protected]f6d1d6eb2009-06-24 20:16:09784
785 EXPECT_EQ(OK, callback2.WaitForResult());
786 EXPECT_FALSE(callback.have_result());
787
788 handle.Reset();
789}
790
[email protected]ab838892009-06-30 18:49:05791TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
[email protected]211d21722009-07-22 15:48:53792 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]f6d1d6eb2009-06-24 20:16:09793
[email protected]c9d6a1d2009-07-14 16:15:20794 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
795 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
796 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
797 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
798 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
799 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
800 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
[email protected]f6d1d6eb2009-06-24 20:16:09801
802 // Cancel a request.
[email protected]c9d6a1d2009-07-14 16:15:20803 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
804 EXPECT_FALSE(requests_[index_to_cancel]->handle.is_initialized());
805 requests_[index_to_cancel]->handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09806
[email protected]c9d6a1d2009-07-14 16:15:20807 ReleaseAllConnections(KEEP_ALIVE);
[email protected]f6d1d6eb2009-06-24 20:16:09808
[email protected]c9d6a1d2009-07-14 16:15:20809 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
810 client_socket_factory_.allocation_count());
811 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
812 TestSocketRequest::completion_count);
[email protected]f6d1d6eb2009-06-24 20:16:09813
[email protected]c9d6a1d2009-07-14 16:15:20814 EXPECT_EQ(1, GetOrderOfRequest(1));
815 EXPECT_EQ(2, GetOrderOfRequest(2));
816 EXPECT_EQ(5, GetOrderOfRequest(3));
817 EXPECT_EQ(3, GetOrderOfRequest(4));
818 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
819 EXPECT_EQ(4, GetOrderOfRequest(6));
820 EXPECT_EQ(6, GetOrderOfRequest(7));
[email protected]f6d1d6eb2009-06-24 20:16:09821}
822
823class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
824 public:
[email protected]2ab05b52009-07-01 23:57:58825 RequestSocketCallback(ClientSocketHandle* handle,
826 TestConnectJobFactory* test_connect_job_factory,
827 TestConnectJob::JobType next_job_type)
[email protected]f6d1d6eb2009-06-24 20:16:09828 : handle_(handle),
[email protected]2ab05b52009-07-01 23:57:58829 within_callback_(false),
830 test_connect_job_factory_(test_connect_job_factory),
831 next_job_type_(next_job_type) {}
[email protected]f6d1d6eb2009-06-24 20:16:09832
833 virtual void RunWithParams(const Tuple1<int>& params) {
834 callback_.RunWithParams(params);
835 ASSERT_EQ(OK, params.a);
836
837 if (!within_callback_) {
[email protected]2ab05b52009-07-01 23:57:58838 test_connect_job_factory_->set_job_type(next_job_type_);
[email protected]f6d1d6eb2009-06-24 20:16:09839 handle_->Reset();
840 within_callback_ = true;
841 int rv = handle_->Init(
[email protected]0b7648c2009-07-06 20:14:01842 "a", HostResolver::RequestInfo("www.google.com", 80),
843 kDefaultPriority, this);
[email protected]2ab05b52009-07-01 23:57:58844 switch (next_job_type_) {
845 case TestConnectJob::kMockJob:
846 EXPECT_EQ(OK, rv);
847 break;
848 case TestConnectJob::kMockPendingJob:
849 EXPECT_EQ(ERR_IO_PENDING, rv);
850 break;
851 default:
852 FAIL() << "Unexpected job type: " << next_job_type_;
853 break;
854 }
[email protected]f6d1d6eb2009-06-24 20:16:09855 }
856 }
857
858 int WaitForResult() {
859 return callback_.WaitForResult();
860 }
861
862 private:
863 ClientSocketHandle* const handle_;
864 bool within_callback_;
[email protected]2ab05b52009-07-01 23:57:58865 TestConnectJobFactory* const test_connect_job_factory_;
866 TestConnectJob::JobType next_job_type_;
[email protected]f6d1d6eb2009-06-24 20:16:09867 TestCompletionCallback callback_;
868};
869
[email protected]2ab05b52009-07-01 23:57:58870TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:53871 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20872
[email protected]0b7648c2009-07-06 20:14:01873 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09874 ClientSocketHandle handle(pool_.get());
[email protected]2ab05b52009-07-01 23:57:58875 RequestSocketCallback callback(
876 &handle, connect_job_factory_, TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09877 int rv = handle.Init(
[email protected]0b7648c2009-07-06 20:14:01878 "a", ignored_request_info_, kDefaultPriority, &callback);
[email protected]f6d1d6eb2009-06-24 20:16:09879 ASSERT_EQ(ERR_IO_PENDING, rv);
880
881 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ab05b52009-07-01 23:57:58882 handle.Reset();
883}
[email protected]f6d1d6eb2009-06-24 20:16:09884
[email protected]2ab05b52009-07-01 23:57:58885TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:53886 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20887
[email protected]0b7648c2009-07-06 20:14:01888 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]2ab05b52009-07-01 23:57:58889 ClientSocketHandle handle(pool_.get());
890 RequestSocketCallback callback(
891 &handle, connect_job_factory_, TestConnectJob::kMockJob);
892 int rv = handle.Init(
[email protected]0b7648c2009-07-06 20:14:01893 "a", ignored_request_info_, kDefaultPriority, &callback);
[email protected]2ab05b52009-07-01 23:57:58894 ASSERT_EQ(ERR_IO_PENDING, rv);
895
896 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09897 handle.Reset();
898}
899
900// Make sure that pending requests get serviced after active requests get
901// cancelled.
[email protected]ab838892009-06-30 18:49:05902TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:53903 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20904
[email protected]0b7648c2009-07-06 20:14:01905 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09906
[email protected]c9d6a1d2009-07-14 16:15:20907 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
908 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
909 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
910 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
911 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
912 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
913 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:09914
[email protected]c9d6a1d2009-07-14 16:15:20915 // Now, kDefaultMaxSocketsPerGroup requests should be active.
916 // Let's cancel them.
917 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
918 ASSERT_FALSE(requests_[i]->handle.is_initialized());
919 requests_[i]->handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09920 }
921
[email protected]f6d1d6eb2009-06-24 20:16:09922 // Let's wait for the rest to complete now.
[email protected]c9d6a1d2009-07-14 16:15:20923 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
924 EXPECT_EQ(OK, requests_[i]->WaitForResult());
925 requests_[i]->handle.Reset();
[email protected]f6d1d6eb2009-06-24 20:16:09926 }
927
[email protected]c9d6a1d2009-07-14 16:15:20928 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
929 TestSocketRequest::completion_count);
[email protected]f6d1d6eb2009-06-24 20:16:09930}
931
932// Make sure that pending requests get serviced after active requests fail.
[email protected]ab838892009-06-30 18:49:05933TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:53934 const size_t kMaxSockets = 5;
935 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20936
[email protected]0b7648c2009-07-06 20:14:01937 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]f6d1d6eb2009-06-24 20:16:09938
[email protected]211d21722009-07-22 15:48:53939 const size_t kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
940 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test will hang.
[email protected]f6d1d6eb2009-06-24 20:16:09941
942 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:53943 for (size_t i = 0; i < kNumberOfRequests; ++i)
944 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]f6d1d6eb2009-06-24 20:16:09945
[email protected]211d21722009-07-22 15:48:53946 for (size_t i = 0; i < kNumberOfRequests; ++i)
947 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]f6d1d6eb2009-06-24 20:16:09948}
949
[email protected]5fc08e32009-07-15 17:09:57950TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:53951 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:57952
953 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
954
955 TestSocketRequest req(pool_.get(), &request_order_);
956 int rv = req.handle.Init(
957 "a", ignored_request_info_, kDefaultPriority, &req);
958 EXPECT_EQ(ERR_IO_PENDING, rv);
959
960 // Cancel the active request.
961 req.handle.Reset();
962
963 rv = req.handle.Init("a", ignored_request_info_, kDefaultPriority, &req);
964 EXPECT_EQ(ERR_IO_PENDING, rv);
965 EXPECT_EQ(OK, req.WaitForResult());
966
967 EXPECT_FALSE(req.handle.is_reused());
968 EXPECT_EQ(1U, TestSocketRequest::completion_count);
969 EXPECT_EQ(2, client_socket_factory_.allocation_count());
970}
971
[email protected]2ab05b52009-07-01 23:57:58972// A pending asynchronous job completes, which will free up a socket slot. The
973// next job finishes synchronously. The callback for the asynchronous job
974// should be first though.
975TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:53976 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]c9d6a1d2009-07-14 16:15:20977
[email protected]2ab05b52009-07-01 23:57:58978 // First two jobs are async.
[email protected]0b7648c2009-07-06 20:14:01979 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]2ab05b52009-07-01 23:57:58980
981 // Start job 1 (async error).
982 TestSocketRequest req1(pool_.get(), &request_order_);
[email protected]0b7648c2009-07-06 20:14:01983 int rv = req1.handle.Init("a", ignored_request_info_,
984 kDefaultPriority, &req1);
[email protected]2ab05b52009-07-01 23:57:58985 EXPECT_EQ(ERR_IO_PENDING, rv);
986
987 // Start job 2 (async error).
988 TestSocketRequest req2(pool_.get(), &request_order_);
[email protected]0b7648c2009-07-06 20:14:01989 rv = req2.handle.Init("a", ignored_request_info_, kDefaultPriority, &req2);
[email protected]2ab05b52009-07-01 23:57:58990 EXPECT_EQ(ERR_IO_PENDING, rv);
991
992 // The pending job is sync.
[email protected]0b7648c2009-07-06 20:14:01993 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]2ab05b52009-07-01 23:57:58994
995 // Request 3 does not have a ConnectJob yet. It's just pending.
996 TestSocketRequest req3(pool_.get(), &request_order_);
[email protected]0b7648c2009-07-06 20:14:01997 rv = req3.handle.Init("a", ignored_request_info_, kDefaultPriority, &req3);
[email protected]2ab05b52009-07-01 23:57:58998 EXPECT_EQ(ERR_IO_PENDING, rv);
999
1000 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1001 EXPECT_EQ(ERR_CONNECTION_FAILED, req2.WaitForResult());
1002 EXPECT_EQ(OK, req3.WaitForResult());
1003
1004 ASSERT_EQ(3U, request_order_.size());
1005
1006 // After job 1 finishes unsuccessfully, it will try to process the pending
1007 // requests queue, so it starts up job 3 for request 3. This job
1008 // synchronously succeeds, so the request order is 1, 3, 2.
1009 EXPECT_EQ(&req1, request_order_[0]);
1010 EXPECT_EQ(&req2, request_order_[2]);
1011 EXPECT_EQ(&req3, request_order_[1]);
1012}
1013
[email protected]5fc08e32009-07-15 17:09:571014// When a ConnectJob is coupled to a request, even if a free socket becomes
1015// available, the request will be serviced by the ConnectJob.
1016TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531017 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571018 ClientSocketPoolBase::EnableLateBindingOfSockets(false);
1019
1020 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321021 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571022
1023 TestSocketRequest req1(pool_.get(), &request_order_);
1024 int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
1025 EXPECT_EQ(ERR_IO_PENDING, rv);
1026 EXPECT_EQ(OK, req1.WaitForResult());
1027
1028 // Job 1 finished OK. Start job 2 (also async OK). Release socket 1.
1029 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1030
1031 TestSocketRequest req2(pool_.get(), &request_order_);
1032 rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
1033 EXPECT_EQ(ERR_IO_PENDING, rv);
1034 req1.handle.Reset();
1035 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1036
1037 // Job 2 is pending. Start request 3 (which has no associated job since it
1038 // will use the idle socket).
1039
1040 TestSocketRequest req3(pool_.get(), &request_order_);
1041 rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
1042 EXPECT_EQ(OK, rv);
1043
1044 EXPECT_FALSE(req2.handle.socket());
1045 client_socket_factory_.SignalJobs();
1046 EXPECT_EQ(OK, req2.WaitForResult());
1047
1048 ASSERT_EQ(2U, request_order_.size());
1049 EXPECT_EQ(&req1, request_order_[0]);
1050 EXPECT_EQ(&req2, request_order_[1]);
1051 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1052}
1053
1054class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest {
1055 protected:
1056 virtual void SetUp() {
1057 ClientSocketPoolBaseTest::SetUp();
1058 ClientSocketPoolBase::EnableLateBindingOfSockets(true);
1059 }
1060};
1061
1062TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicSynchronous) {
[email protected]211d21722009-07-22 15:48:531063 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571064
1065 TestCompletionCallback callback;
1066 ClientSocketHandle handle(pool_.get());
1067 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority,
1068 &callback));
1069 EXPECT_TRUE(handle.is_initialized());
1070 EXPECT_TRUE(handle.socket());
1071 handle.Reset();
1072}
1073
1074TEST_F(ClientSocketPoolBaseTest_LateBinding, BasicAsynchronous) {
[email protected]211d21722009-07-22 15:48:531075 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571076
1077 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1078 TestSocketRequest req(pool_.get(), &request_order_);
1079 int rv = req.handle.Init("a", ignored_request_info_, 0, &req);
1080 EXPECT_EQ(ERR_IO_PENDING, rv);
1081 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
1082 EXPECT_EQ(OK, req.WaitForResult());
1083 EXPECT_TRUE(req.handle.is_initialized());
1084 EXPECT_TRUE(req.handle.socket());
1085 req.handle.Reset();
1086}
1087
1088TEST_F(ClientSocketPoolBaseTest_LateBinding, InitConnectionFailure) {
[email protected]211d21722009-07-22 15:48:531089 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571090
1091 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
1092 TestSocketRequest req(pool_.get(), &request_order_);
1093 EXPECT_EQ(ERR_CONNECTION_FAILED,
1094 req.handle.Init("a", ignored_request_info_,
1095 kDefaultPriority, &req));
1096}
1097
1098TEST_F(ClientSocketPoolBaseTest_LateBinding,
1099 InitConnectionAsynchronousFailure) {
[email protected]211d21722009-07-22 15:48:531100 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571101
1102 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1103 TestSocketRequest req(pool_.get(), &request_order_);
1104 EXPECT_EQ(ERR_IO_PENDING,
1105 req.handle.Init("a", ignored_request_info_, 5, &req));
1106 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", &req.handle));
1107 EXPECT_EQ(ERR_CONNECTION_FAILED, req.WaitForResult());
1108}
1109
1110TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests) {
[email protected]211d21722009-07-22 15:48:531111 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571112
1113 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1114 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1115 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1116 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1117 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1118 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1119 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1120
1121 ReleaseAllConnections(KEEP_ALIVE);
1122
1123 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1124 client_socket_factory_.allocation_count());
1125 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
1126 TestSocketRequest::completion_count);
1127
1128 EXPECT_EQ(1, GetOrderOfRequest(1));
1129 EXPECT_EQ(2, GetOrderOfRequest(2));
1130 EXPECT_EQ(6, GetOrderOfRequest(3));
1131 EXPECT_EQ(4, GetOrderOfRequest(4));
1132 EXPECT_EQ(3, GetOrderOfRequest(5));
1133 EXPECT_EQ(5, GetOrderOfRequest(6));
1134 EXPECT_EQ(7, GetOrderOfRequest(7));
1135}
1136
1137TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingRequests_NoKeepAlive) {
[email protected]211d21722009-07-22 15:48:531138 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571139
1140 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1141 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1142 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1143 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1144 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1145 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1146 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1147
1148 ReleaseAllConnections(NO_KEEP_ALIVE);
1149
1150 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
1151 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1152
1153 EXPECT_EQ(static_cast<int>(requests_.size()),
1154 client_socket_factory_.allocation_count());
1155 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
1156 TestSocketRequest::completion_count);
1157}
1158
1159// This test will start up a RequestSocket() and then immediately Cancel() it.
1160// The pending connect job will be cancelled and should not call back into
1161// ClientSocketPoolBase.
1162TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequestClearGroup) {
[email protected]211d21722009-07-22 15:48:531163 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571164
1165 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1166 TestSocketRequest req(pool_.get(), &request_order_);
1167 EXPECT_EQ(ERR_IO_PENDING,
1168 req.handle.Init("a", ignored_request_info_,
1169 kDefaultPriority, &req));
1170 req.handle.Reset();
1171}
1172
1173TEST_F(ClientSocketPoolBaseTest_LateBinding, TwoRequestsCancelOne) {
[email protected]211d21722009-07-22 15:48:531174 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571175
1176 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1177 TestSocketRequest req(pool_.get(), &request_order_);
1178 TestSocketRequest req2(pool_.get(), &request_order_);
1179
1180 EXPECT_EQ(ERR_IO_PENDING,
1181 req.handle.Init("a", ignored_request_info_,
1182 kDefaultPriority, &req));
1183 EXPECT_EQ(ERR_IO_PENDING,
1184 req2.handle.Init("a", ignored_request_info_,
1185 kDefaultPriority, &req2));
1186
1187 req.handle.Reset();
1188
1189 EXPECT_EQ(OK, req2.WaitForResult());
1190 req2.handle.Reset();
1191}
1192
1193TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectCancelConnect) {
[email protected]211d21722009-07-22 15:48:531194 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571195
1196 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1197 ClientSocketHandle handle(pool_.get());
1198 TestCompletionCallback callback;
1199 TestSocketRequest req(pool_.get(), &request_order_);
1200
1201 EXPECT_EQ(ERR_IO_PENDING,
1202 handle.Init("a", ignored_request_info_,
1203 kDefaultPriority, &callback));
1204
1205 handle.Reset();
1206
1207 TestCompletionCallback callback2;
1208 EXPECT_EQ(ERR_IO_PENDING,
1209 handle.Init("a", ignored_request_info_,
1210 kDefaultPriority, &callback2));
1211
1212 EXPECT_EQ(OK, callback2.WaitForResult());
1213 EXPECT_FALSE(callback.have_result());
1214
1215 handle.Reset();
1216}
1217
1218TEST_F(ClientSocketPoolBaseTest_LateBinding, CancelRequest) {
[email protected]211d21722009-07-22 15:48:531219 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571220
1221 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1222 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
1223 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1224 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
1225 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
1226 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
1227 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
1228
1229 // Cancel a request.
1230 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
1231 EXPECT_FALSE(requests_[index_to_cancel]->handle.is_initialized());
1232 requests_[index_to_cancel]->handle.Reset();
1233
1234 ReleaseAllConnections(KEEP_ALIVE);
1235
1236 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
1237 client_socket_factory_.allocation_count());
1238 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
1239 TestSocketRequest::completion_count);
1240
1241 EXPECT_EQ(1, GetOrderOfRequest(1));
1242 EXPECT_EQ(2, GetOrderOfRequest(2));
1243 EXPECT_EQ(5, GetOrderOfRequest(3));
1244 EXPECT_EQ(3, GetOrderOfRequest(4));
1245 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
1246 EXPECT_EQ(4, GetOrderOfRequest(6));
1247 EXPECT_EQ(6, GetOrderOfRequest(7));
1248}
1249
1250TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobTwice) {
[email protected]211d21722009-07-22 15:48:531251 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571252
1253 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1254 ClientSocketHandle handle(pool_.get());
1255 RequestSocketCallback callback(
1256 &handle, connect_job_factory_, TestConnectJob::kMockPendingJob);
1257 int rv = handle.Init(
1258 "a", ignored_request_info_, kDefaultPriority, &callback);
1259 ASSERT_EQ(ERR_IO_PENDING, rv);
1260
1261 EXPECT_EQ(OK, callback.WaitForResult());
1262 handle.Reset();
1263}
1264
1265TEST_F(ClientSocketPoolBaseTest_LateBinding, RequestPendingJobThenSynchronous) {
[email protected]211d21722009-07-22 15:48:531266 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571267
1268 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1269 ClientSocketHandle handle(pool_.get());
1270 RequestSocketCallback callback(
1271 &handle, connect_job_factory_, TestConnectJob::kMockJob);
1272 int rv = handle.Init(
1273 "a", ignored_request_info_, kDefaultPriority, &callback);
1274 ASSERT_EQ(ERR_IO_PENDING, rv);
1275
1276 EXPECT_EQ(OK, callback.WaitForResult());
1277 handle.Reset();
1278}
1279
1280// Make sure that pending requests get serviced after active requests get
1281// cancelled.
1282TEST_F(ClientSocketPoolBaseTest_LateBinding,
1283 CancelActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531284 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571285
1286 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1287
1288 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1289 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1290 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1291 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1292 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1293 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1294 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
1295
1296 // Now, kDefaultMaxSocketsPerGroup requests should be active.
1297 // Let's cancel them.
1298 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
1299 ASSERT_FALSE(requests_[i]->handle.is_initialized());
1300 requests_[i]->handle.Reset();
1301 }
1302
1303 // Let's wait for the rest to complete now.
1304 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
1305 EXPECT_EQ(OK, requests_[i]->WaitForResult());
1306 requests_[i]->handle.Reset();
1307 }
1308
1309 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
1310 TestSocketRequest::completion_count);
1311}
1312
1313// Make sure that pending requests get serviced after active requests fail.
1314TEST_F(ClientSocketPoolBaseTest_LateBinding,
1315 FailingActiveRequestWithPendingRequests) {
[email protected]211d21722009-07-22 15:48:531316 const int kMaxSockets = 5;
1317 CreatePool(kMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571318
1319 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
1320
[email protected]211d21722009-07-22 15:48:531321 const int kNumberOfRequests = 2 * kDefaultMaxSocketsPerGroup + 1;
1322 ASSERT_LE(kNumberOfRequests, kMaxSockets); // Otherwise the test hangs.
[email protected]5fc08e32009-07-15 17:09:571323
1324 // Queue up all the requests
[email protected]211d21722009-07-22 15:48:531325 for (int i = 0; i < kNumberOfRequests; ++i)
1326 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
[email protected]5fc08e32009-07-15 17:09:571327
[email protected]211d21722009-07-22 15:48:531328 for (int i = 0; i < kNumberOfRequests; ++i)
1329 EXPECT_EQ(ERR_CONNECTION_FAILED, requests_[i]->WaitForResult());
[email protected]5fc08e32009-07-15 17:09:571330}
1331
1332TEST_F(ClientSocketPoolBaseTest_LateBinding,
1333 CancelActiveRequestThenRequestSocket) {
[email protected]211d21722009-07-22 15:48:531334 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571335
1336 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
1337
1338 TestSocketRequest req(pool_.get(), &request_order_);
1339 int rv = req.handle.Init(
1340 "a", ignored_request_info_, kDefaultPriority, &req);
1341 EXPECT_EQ(ERR_IO_PENDING, rv);
1342
1343 // Cancel the active request.
1344 req.handle.Reset();
1345
1346 rv = req.handle.Init("a", ignored_request_info_, kDefaultPriority, &req);
1347 EXPECT_EQ(ERR_IO_PENDING, rv);
1348 EXPECT_EQ(OK, req.WaitForResult());
1349
1350 EXPECT_FALSE(req.handle.is_reused());
1351 EXPECT_EQ(1U, TestSocketRequest::completion_count);
1352 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1353}
1354
1355// When requests and ConnectJobs are not coupled, the request will get serviced
1356// by whatever comes first.
1357TEST_F(ClientSocketPoolBaseTest_LateBinding, ReleaseSockets) {
[email protected]211d21722009-07-22 15:48:531358 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571359
1360 // Start job 1 (async OK)
[email protected]b59ff372009-07-15 22:04:321361 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
[email protected]5fc08e32009-07-15 17:09:571362
1363 TestSocketRequest req1(pool_.get(), &request_order_);
1364 int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
1365 EXPECT_EQ(ERR_IO_PENDING, rv);
1366 EXPECT_EQ(OK, req1.WaitForResult());
1367
1368 // Job 1 finished OK. Start job 2 (also async OK). Request 3 is pending
1369 // without a job.
1370 connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
1371
1372 TestSocketRequest req2(pool_.get(), &request_order_);
1373 rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
1374 EXPECT_EQ(ERR_IO_PENDING, rv);
1375 TestSocketRequest req3(pool_.get(), &request_order_);
1376 rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
1377 EXPECT_EQ(ERR_IO_PENDING, rv);
1378
1379 // Both Requests 2 and 3 are pending. We release socket 1 which should
1380 // service request 2. Request 3 should still be waiting.
1381 req1.handle.Reset();
1382 MessageLoop::current()->RunAllPending(); // Run the DoReleaseSocket()
1383 ASSERT_TRUE(req2.handle.socket());
1384 EXPECT_EQ(OK, req2.WaitForResult());
1385 EXPECT_FALSE(req3.handle.socket());
1386
1387 // Signal job 2, which should service request 3.
1388
1389 client_socket_factory_.SignalJobs();
1390 EXPECT_EQ(OK, req3.WaitForResult());
1391
1392 ASSERT_EQ(3U, request_order_.size());
1393 EXPECT_EQ(&req1, request_order_[0]);
1394 EXPECT_EQ(&req2, request_order_[1]);
1395 EXPECT_EQ(&req3, request_order_[2]);
1396 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
1397}
1398
1399// The requests are not coupled to the jobs. So, the requests should finish in
1400// their priority / insertion order.
1401TEST_F(ClientSocketPoolBaseTest_LateBinding, PendingJobCompletionOrder) {
[email protected]211d21722009-07-22 15:48:531402 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571403 // First two jobs are async.
[email protected]b59ff372009-07-15 22:04:321404 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
[email protected]5fc08e32009-07-15 17:09:571405
1406 TestSocketRequest req1(pool_.get(), &request_order_);
1407 int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
1408 EXPECT_EQ(ERR_IO_PENDING, rv);
1409
1410 TestSocketRequest req2(pool_.get(), &request_order_);
1411 rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
1412 EXPECT_EQ(ERR_IO_PENDING, rv);
1413
1414 // The pending job is sync.
[email protected]b59ff372009-07-15 22:04:321415 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
[email protected]5fc08e32009-07-15 17:09:571416
1417 TestSocketRequest req3(pool_.get(), &request_order_);
1418 rv = req3.handle.Init("a", ignored_request_info_, 5, &req3);
1419 EXPECT_EQ(ERR_IO_PENDING, rv);
1420
1421 EXPECT_EQ(ERR_CONNECTION_FAILED, req1.WaitForResult());
1422 EXPECT_EQ(OK, req2.WaitForResult());
1423 EXPECT_EQ(ERR_CONNECTION_FAILED, req3.WaitForResult());
1424
1425 ASSERT_EQ(3U, request_order_.size());
1426 EXPECT_EQ(&req1, request_order_[0]);
1427 EXPECT_EQ(&req2, request_order_[1]);
1428 EXPECT_EQ(&req3, request_order_[2]);
1429}
1430
[email protected]f0109a7d2009-07-16 00:09:521431TEST_F(ClientSocketPoolBaseTest_LateBinding, DISABLED_LoadState) {
[email protected]211d21722009-07-22 15:48:531432 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
[email protected]5fc08e32009-07-15 17:09:571433 connect_job_factory_->set_job_type(
[email protected]b59ff372009-07-15 22:04:321434 TestConnectJob::kMockAdvancingLoadStateJob);
[email protected]5fc08e32009-07-15 17:09:571435
1436 TestSocketRequest req1(pool_.get(), &request_order_);
1437 int rv = req1.handle.Init("a", ignored_request_info_, 5, &req1);
1438 EXPECT_EQ(ERR_IO_PENDING, rv);
1439 EXPECT_EQ(LOAD_STATE_IDLE, req1.handle.GetLoadState());
1440
1441 MessageLoop::current()->RunAllPending();
1442
1443 TestSocketRequest req2(pool_.get(), &request_order_);
1444 rv = req2.handle.Init("a", ignored_request_info_, 5, &req2);
1445 EXPECT_EQ(ERR_IO_PENDING, rv);
1446 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req1.handle.GetLoadState());
1447 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, req2.handle.GetLoadState());
1448}
1449
[email protected]f6d1d6eb2009-06-24 20:16:091450} // namespace
1451
1452} // namespace net