Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: net/socket/client_socket_pool_base_unittest.cc

Issue 149545: Refactoring needed before adding good unit tests for limiting total socket count. (Closed)
Patch Set: fixes Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/socket/client_socket_pool_base.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/client_socket_pool_base.h" 5 #include "net/socket/client_socket_pool_base.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/scoped_vector.h"
9 #include "net/base/host_resolver_unittest.h" 10 #include "net/base/host_resolver_unittest.h"
10 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
11 #include "net/base/test_completion_callback.h" 12 #include "net/base/test_completion_callback.h"
12 #include "net/socket/client_socket.h" 13 #include "net/socket/client_socket.h"
13 #include "net/socket/client_socket_factory.h" 14 #include "net/socket/client_socket_factory.h"
14 #include "net/socket/client_socket_handle.h" 15 #include "net/socket/client_socket_handle.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
16 17
17 namespace net { 18 namespace net {
18 19
19 namespace { 20 namespace {
20 21
21 const int kMaxSocketsPerGroup = 2; 22 const int kDefaultMaxSocketsPerGroup = 2;
22
23 // Note that the first and the last are the same, the first should be handled
24 // before the last, since it was inserted first.
25 const int kPriorities[] = { 1, 3, 4, 2, 1 };
26
27 // This is the number of extra requests beyond the first few that use up all
28 // available sockets in the socket group.
29 const int kNumPendingRequests = arraysize(kPriorities);
30
31 const int kNumRequests = kMaxSocketsPerGroup + kNumPendingRequests;
32 23
33 const int kDefaultPriority = 5; 24 const int kDefaultPriority = 5;
34 25
35 class MockClientSocket : public ClientSocket { 26 class MockClientSocket : public ClientSocket {
36 public: 27 public:
37 MockClientSocket() : connected_(false) {} 28 MockClientSocket() : connected_(false) {}
38 29
39 // Socket methods: 30 // Socket methods:
40 virtual int Read( 31 virtual int Read(
41 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) { 32 IOBuffer* /* buf */, int /* len */, CompletionCallback* /* callback */) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 int WaitForResult() { 97 int WaitForResult() {
107 return callback_.WaitForResult(); 98 return callback_.WaitForResult();
108 } 99 }
109 100
110 virtual void RunWithParams(const Tuple1<int>& params) { 101 virtual void RunWithParams(const Tuple1<int>& params) {
111 callback_.RunWithParams(params); 102 callback_.RunWithParams(params);
112 completion_count++; 103 completion_count++;
113 request_order_->push_back(this); 104 request_order_->push_back(this);
114 } 105 }
115 106
116 static int completion_count; 107 static size_t completion_count;
117 108
118 private: 109 private:
119 std::vector<TestSocketRequest*>* request_order_; 110 std::vector<TestSocketRequest*>* request_order_;
120 TestCompletionCallback callback_; 111 TestCompletionCallback callback_;
121 }; 112 };
122 113
123 int TestSocketRequest::completion_count = 0; 114 size_t TestSocketRequest::completion_count = 0;
124 115
125 class TestConnectJob : public ConnectJob { 116 class TestConnectJob : public ConnectJob {
126 public: 117 public:
127 enum JobType { 118 enum JobType {
128 kMockJob, 119 kMockJob,
129 kMockFailingJob, 120 kMockFailingJob,
130 kMockPendingJob, 121 kMockPendingJob,
131 kMockPendingFailingJob, 122 kMockPendingFailingJob,
132 }; 123 };
133 124
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 214
224 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory); 215 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
225 }; 216 };
226 217
227 class TestClientSocketPool : public ClientSocketPool { 218 class TestClientSocketPool : public ClientSocketPool {
228 public: 219 public:
229 TestClientSocketPool( 220 TestClientSocketPool(
230 int max_sockets_per_group, 221 int max_sockets_per_group,
231 ClientSocketPoolBase::ConnectJobFactory* connect_job_factory) 222 ClientSocketPoolBase::ConnectJobFactory* connect_job_factory)
232 : base_(new ClientSocketPoolBase( 223 : base_(new ClientSocketPoolBase(
233 kMaxSocketsPerGroup, connect_job_factory)) {} 224 max_sockets_per_group, connect_job_factory)) {}
234 225
235 virtual int RequestSocket( 226 virtual int RequestSocket(
236 const std::string& group_name, 227 const std::string& group_name,
237 const HostResolver::RequestInfo& resolve_info, 228 const HostResolver::RequestInfo& resolve_info,
238 int priority, 229 int priority,
239 ClientSocketHandle* handle, 230 ClientSocketHandle* handle,
240 CompletionCallback* callback) { 231 CompletionCallback* callback) {
241 return base_->RequestSocket( 232 return base_->RequestSocket(
242 group_name, resolve_info, priority, handle, callback); 233 group_name, resolve_info, priority, handle, callback);
243 } 234 }
(...skipping 18 matching lines...) Expand all
262 253
263 virtual int IdleSocketCountInGroup(const std::string& group_name) const { 254 virtual int IdleSocketCountInGroup(const std::string& group_name) const {
264 return base_->IdleSocketCountInGroup(group_name); 255 return base_->IdleSocketCountInGroup(group_name);
265 } 256 }
266 257
267 virtual LoadState GetLoadState(const std::string& group_name, 258 virtual LoadState GetLoadState(const std::string& group_name,
268 const ClientSocketHandle* handle) const { 259 const ClientSocketHandle* handle) const {
269 return base_->GetLoadState(group_name, handle); 260 return base_->GetLoadState(group_name, handle);
270 } 261 }
271 262
263 int MaxSocketsPerGroup() const {
264 return base_->max_sockets_per_group();
265 }
266
272 private: 267 private:
273 const scoped_refptr<ClientSocketPoolBase> base_; 268 const scoped_refptr<ClientSocketPoolBase> base_;
274 269
275 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool); 270 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
276 }; 271 };
277 272
278 class ClientSocketPoolBaseTest : public testing::Test { 273 class ClientSocketPoolBaseTest : public testing::Test {
279 protected: 274 protected:
280 ClientSocketPoolBaseTest() 275 ClientSocketPoolBaseTest()
281 : ignored_request_info_("ignored", 80), 276 : ignored_request_info_("ignored", 80),
282 connect_job_factory_( 277 connect_job_factory_(
283 new TestConnectJobFactory(&client_socket_factory_)), 278 new TestConnectJobFactory(&client_socket_factory_)) {}
284 pool_(new TestClientSocketPool(kMaxSocketsPerGroup, 279
285 connect_job_factory_)) {} 280 void CreatePool(int max_sockets_per_group) {
281 DCHECK(!pool_.get());
282 pool_ = new TestClientSocketPool(max_sockets_per_group,
283 connect_job_factory_);
284 }
286 285
287 virtual void SetUp() { 286 virtual void SetUp() {
288 TestSocketRequest::completion_count = 0; 287 TestSocketRequest::completion_count = 0;
289 } 288 }
290 289
291 virtual void TearDown() { 290 virtual void TearDown() {
292 // The tests often call Reset() on handles at the end which may post 291 // The tests often call Reset() on handles at the end which may post
293 // DoReleaseSocket() tasks. 292 // DoReleaseSocket() tasks.
294 MessageLoop::current()->RunAllPending(); 293 MessageLoop::current()->RunAllPending();
295 } 294 }
296 295
297 void CreateConnections(scoped_ptr<TestSocketRequest>* reqs, size_t count) { 296 int StartRequest(const std::string& group_name, int priority) {
298 for (size_t i = 0; i < count; ++i) 297 DCHECK(pool_.get());
299 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 298 TestSocketRequest* request = new TestSocketRequest(pool_.get(),
299 &request_order_);
300 requests_.push_back(request);
301 int rv = request->handle.Init(group_name, ignored_request_info_, priority,
302 request);
303 if (rv != ERR_IO_PENDING)
304 request_order_.push_back(request);
305 return rv;
306 }
300 307
301 // Create connections or queue up requests. 308 static const int kIndexOutOfBounds;
302 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 309 static const int kRequestNotFound;
303 int rv = reqs[i]->handle.Init("a", ignored_request_info_,
304 kDefaultPriority, reqs[i].get());
305 EXPECT_EQ(OK, rv);
306 request_order_.push_back(reqs[i].get());
307 }
308 310
309 // The rest are pending since we've used all active sockets. 311 int GetOrderOfRequest(size_t index) {
310 for (int i = 0; i < kNumPendingRequests; ++i) { 312 index--;
311 int rv = reqs[kMaxSocketsPerGroup + i]->handle.Init( 313 if (index >= requests_.size())
312 "a", ignored_request_info_, kPriorities[i], 314 return kIndexOutOfBounds;
313 reqs[kMaxSocketsPerGroup + i].get()); 315
314 EXPECT_EQ(ERR_IO_PENDING, rv); 316 for (size_t i = 0; i < request_order_.size(); i++)
315 } 317 if (requests_[index] == request_order_[i])
318 return i + 1;
319
320 return kRequestNotFound;
316 } 321 }
317 322
318 enum KeepAlive { 323 enum KeepAlive {
319 KEEP_ALIVE, 324 KEEP_ALIVE,
320 NO_KEEP_ALIVE, 325 NO_KEEP_ALIVE,
321 }; 326 };
322 327
323 void ReleaseAllConnections(scoped_ptr<TestSocketRequest>* reqs, 328 void ReleaseAllConnections(KeepAlive keep_alive) {
324 size_t count, KeepAlive keep_alive) {
325 bool released_one; 329 bool released_one;
326 do { 330 do {
327 released_one = false; 331 released_one = false;
328 for (size_t i = 0; i < count; ++i) { 332 ScopedVector<TestSocketRequest>::iterator i;
329 if (reqs[i]->handle.is_initialized()) { 333 for (i = requests_.begin(); i != requests_.end(); ++i) {
334 if ((*i)->handle.is_initialized()) {
330 if (keep_alive == NO_KEEP_ALIVE) 335 if (keep_alive == NO_KEEP_ALIVE)
331 reqs[i]->handle.socket()->Disconnect(); 336 (*i)->handle.socket()->Disconnect();
332 reqs[i]->handle.Reset(); 337 (*i)->handle.Reset();
333 MessageLoop::current()->RunAllPending(); 338 MessageLoop::current()->RunAllPending();
334 released_one = true; 339 released_one = true;
335 } 340 }
336 } 341 }
337 } while (released_one); 342 } while (released_one);
338 } 343 }
339 344
340 HostResolver::RequestInfo ignored_request_info_; 345 HostResolver::RequestInfo ignored_request_info_;
341 MockClientSocketFactory client_socket_factory_; 346 MockClientSocketFactory client_socket_factory_;
342 TestConnectJobFactory* const connect_job_factory_; 347 TestConnectJobFactory* const connect_job_factory_;
343 scoped_refptr<ClientSocketPool> pool_; 348 scoped_refptr<TestClientSocketPool> pool_;
349 ScopedVector<TestSocketRequest> requests_;
344 std::vector<TestSocketRequest*> request_order_; 350 std::vector<TestSocketRequest*> request_order_;
345 }; 351 };
346 352
353 // static
354 const int ClientSocketPoolBaseTest::kIndexOutOfBounds = -1;
355
356 // static
357 const int ClientSocketPoolBaseTest::kRequestNotFound = -2;
358
347 TEST_F(ClientSocketPoolBaseTest, Basic) { 359 TEST_F(ClientSocketPoolBaseTest, Basic) {
360 CreatePool(kDefaultMaxSocketsPerGroup);
361
348 TestCompletionCallback callback; 362 TestCompletionCallback callback;
349 ClientSocketHandle handle(pool_.get()); 363 ClientSocketHandle handle(pool_.get());
350 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority, 364 EXPECT_EQ(OK, handle.Init("a", ignored_request_info_, kDefaultPriority,
351 &callback)); 365 &callback));
352 EXPECT_TRUE(handle.is_initialized()); 366 EXPECT_TRUE(handle.is_initialized());
353 EXPECT_TRUE(handle.socket()); 367 EXPECT_TRUE(handle.socket());
354 handle.Reset(); 368 handle.Reset();
355 } 369 }
356 370
357 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) { 371 TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) {
372 CreatePool(kDefaultMaxSocketsPerGroup);
373
358 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob); 374 connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
359 TestSocketRequest req(pool_.get(), &request_order_); 375 TestSocketRequest req(pool_.get(), &request_order_);
360 EXPECT_EQ(ERR_CONNECTION_FAILED, 376 EXPECT_EQ(ERR_CONNECTION_FAILED,
361 req.handle.Init("a", ignored_request_info_, 377 req.handle.Init("a", ignored_request_info_,
362 kDefaultPriority, &req)); 378 kDefaultPriority, &req));
363 } 379 }
364 380
365 TEST_F(ClientSocketPoolBaseTest, PendingRequests) { 381 TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
366 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 382 CreatePool(kDefaultMaxSocketsPerGroup);
367 383
368 CreateConnections(reqs, arraysize(reqs)); 384 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
369 ReleaseAllConnections(reqs, arraysize(reqs), KEEP_ALIVE); 385 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
386 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
387 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
388 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
389 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
390 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
370 391
371 EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count()); 392 ReleaseAllConnections(KEEP_ALIVE);
372 EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count);
373 393
374 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 394 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
375 EXPECT_EQ(request_order_[i], reqs[i].get()) << 395 client_socket_factory_.allocation_count());
376 "Request " << i << " was not in order."; 396 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
377 } 397 TestSocketRequest::completion_count);
378 398
379 for (int i = 0; i < kNumPendingRequests - 1; ++i) { 399 EXPECT_EQ(1, GetOrderOfRequest(1));
380 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i]; 400 EXPECT_EQ(2, GetOrderOfRequest(2));
381 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue], 401 EXPECT_EQ(6, GetOrderOfRequest(3));
382 reqs[kMaxSocketsPerGroup + i].get()) << 402 EXPECT_EQ(4, GetOrderOfRequest(4));
383 "Request " << kMaxSocketsPerGroup + i << " was not in order."; 403 EXPECT_EQ(3, GetOrderOfRequest(5));
384 } 404 EXPECT_EQ(5, GetOrderOfRequest(6));
385 405 EXPECT_EQ(7, GetOrderOfRequest(7));
386 EXPECT_EQ(request_order_[arraysize(reqs) - 1],
387 reqs[arraysize(reqs) - 1].get()) <<
388 "The last request with priority 1 should not have been inserted "
389 "earlier into the queue.";
390 } 406 }
391 407
392 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) { 408 TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) {
393 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 409 CreatePool(kDefaultMaxSocketsPerGroup);
394 410
395 CreateConnections(reqs, arraysize(reqs)); 411 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
396 ReleaseAllConnections(reqs, arraysize(reqs), NO_KEEP_ALIVE); 412 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
413 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
414 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
415 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
416 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
417 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
397 418
398 for (int i = kMaxSocketsPerGroup; i < kNumRequests; ++i) 419 ReleaseAllConnections(NO_KEEP_ALIVE);
399 EXPECT_EQ(OK, reqs[i]->WaitForResult());
400 420
401 EXPECT_EQ(kNumRequests, client_socket_factory_.allocation_count()); 421 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i)
402 EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); 422 EXPECT_EQ(OK, requests_[i]->WaitForResult());
423
424 EXPECT_EQ(static_cast<int>(requests_.size()),
425 client_socket_factory_.allocation_count());
426 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
427 TestSocketRequest::completion_count);
403 } 428 }
404 429
405 // This test will start up a RequestSocket() and then immediately Cancel() it. 430 // This test will start up a RequestSocket() and then immediately Cancel() it.
406 // The pending connect job will be cancelled and should not call back into 431 // The pending connect job will be cancelled and should not call back into
407 // ClientSocketPoolBase. 432 // ClientSocketPoolBase.
408 TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) { 433 TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) {
434 CreatePool(kDefaultMaxSocketsPerGroup);
435
409 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 436 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
410 TestSocketRequest req(pool_.get(), &request_order_); 437 TestSocketRequest req(pool_.get(), &request_order_);
411 EXPECT_EQ(ERR_IO_PENDING, 438 EXPECT_EQ(ERR_IO_PENDING,
412 req.handle.Init("a", ignored_request_info_, 439 req.handle.Init("a", ignored_request_info_,
413 kDefaultPriority, &req)); 440 kDefaultPriority, &req));
414 req.handle.Reset(); 441 req.handle.Reset();
415 } 442 }
416 443
417 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) { 444 TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) {
445 CreatePool(kDefaultMaxSocketsPerGroup);
446
418 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 447 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
419 TestSocketRequest req(pool_.get(), &request_order_); 448 TestSocketRequest req(pool_.get(), &request_order_);
420 TestSocketRequest req2(pool_.get(), &request_order_); 449 TestSocketRequest req2(pool_.get(), &request_order_);
421 450
422 EXPECT_EQ(ERR_IO_PENDING, 451 EXPECT_EQ(ERR_IO_PENDING,
423 req.handle.Init("a", ignored_request_info_, 452 req.handle.Init("a", ignored_request_info_,
424 kDefaultPriority, &req)); 453 kDefaultPriority, &req));
425 EXPECT_EQ(ERR_IO_PENDING, 454 EXPECT_EQ(ERR_IO_PENDING,
426 req2.handle.Init("a", ignored_request_info_, 455 req2.handle.Init("a", ignored_request_info_,
427 kDefaultPriority, &req2)); 456 kDefaultPriority, &req2));
428 457
429 req.handle.Reset(); 458 req.handle.Reset();
430 459
431 EXPECT_EQ(OK, req2.WaitForResult()); 460 EXPECT_EQ(OK, req2.WaitForResult());
432 req2.handle.Reset(); 461 req2.handle.Reset();
433 } 462 }
434 463
435 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) { 464 TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) {
465 CreatePool(kDefaultMaxSocketsPerGroup);
466
436 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 467 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
437 ClientSocketHandle handle(pool_.get()); 468 ClientSocketHandle handle(pool_.get());
438 TestCompletionCallback callback; 469 TestCompletionCallback callback;
439 TestSocketRequest req(pool_.get(), &request_order_); 470 TestSocketRequest req(pool_.get(), &request_order_);
440 471
441 EXPECT_EQ(ERR_IO_PENDING, 472 EXPECT_EQ(ERR_IO_PENDING,
442 handle.Init("a", ignored_request_info_, 473 handle.Init("a", ignored_request_info_,
443 kDefaultPriority, &callback)); 474 kDefaultPriority, &callback));
444 475
445 handle.Reset(); 476 handle.Reset();
446 477
447 TestCompletionCallback callback2; 478 TestCompletionCallback callback2;
448 EXPECT_EQ(ERR_IO_PENDING, 479 EXPECT_EQ(ERR_IO_PENDING,
449 handle.Init("a", ignored_request_info_, 480 handle.Init("a", ignored_request_info_,
450 kDefaultPriority, &callback2)); 481 kDefaultPriority, &callback2));
451 482
452 EXPECT_EQ(OK, callback2.WaitForResult()); 483 EXPECT_EQ(OK, callback2.WaitForResult());
453 EXPECT_FALSE(callback.have_result()); 484 EXPECT_FALSE(callback.have_result());
454 485
455 handle.Reset(); 486 handle.Reset();
456 } 487 }
457 488
458 TEST_F(ClientSocketPoolBaseTest, CancelRequest) { 489 TEST_F(ClientSocketPoolBaseTest, CancelRequest) {
459 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 490 CreatePool(kDefaultMaxSocketsPerGroup);
460 491
461 CreateConnections(reqs, arraysize(reqs)); 492 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
493 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
494 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
495 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 3));
496 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 4));
497 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 2));
498 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", 1));
462 499
463 // Cancel a request. 500 // Cancel a request.
464 size_t index_to_cancel = kMaxSocketsPerGroup + 2; 501 size_t index_to_cancel = kDefaultMaxSocketsPerGroup + 2;
465 EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized()); 502 EXPECT_FALSE(requests_[index_to_cancel]->handle.is_initialized());
466 reqs[index_to_cancel]->handle.Reset(); 503 requests_[index_to_cancel]->handle.Reset();
467 504
468 ReleaseAllConnections(reqs, arraysize(reqs), KEEP_ALIVE); 505 ReleaseAllConnections(KEEP_ALIVE);
469 506
470 EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count()); 507 EXPECT_EQ(kDefaultMaxSocketsPerGroup,
471 EXPECT_EQ(kNumPendingRequests - 1, TestSocketRequest::completion_count); 508 client_socket_factory_.allocation_count());
509 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup - 1,
510 TestSocketRequest::completion_count);
472 511
473 for (int i = 0; i < kMaxSocketsPerGroup; ++i) { 512 EXPECT_EQ(1, GetOrderOfRequest(1));
474 EXPECT_EQ(request_order_[i], reqs[i].get()) << 513 EXPECT_EQ(2, GetOrderOfRequest(2));
475 "Request " << i << " was not in order."; 514 EXPECT_EQ(5, GetOrderOfRequest(3));
476 } 515 EXPECT_EQ(3, GetOrderOfRequest(4));
477 516 EXPECT_EQ(kRequestNotFound, GetOrderOfRequest(5)); // Canceled request.
478 for (int i = 0; i < kNumPendingRequests - 1; ++i) { 517 EXPECT_EQ(4, GetOrderOfRequest(6));
479 if (i == 2) continue; 518 EXPECT_EQ(6, GetOrderOfRequest(7));
480 int index_in_queue = (kNumPendingRequests - 1) - kPriorities[i];
481 if (kPriorities[i] < kPriorities[index_to_cancel - kMaxSocketsPerGroup])
482 index_in_queue--;
483 EXPECT_EQ(request_order_[kMaxSocketsPerGroup + index_in_queue],
484 reqs[kMaxSocketsPerGroup + i].get()) <<
485 "Request " << kMaxSocketsPerGroup + i << " was not in order.";
486 }
487
488 EXPECT_EQ(request_order_[arraysize(reqs) - 2],
489 reqs[arraysize(reqs) - 1].get()) <<
490 "The last request with priority 1 should not have been inserted "
491 "earlier into the queue.";
492 } 519 }
493 520
494 class RequestSocketCallback : public CallbackRunner< Tuple1<int> > { 521 class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
495 public: 522 public:
496 RequestSocketCallback(ClientSocketHandle* handle, 523 RequestSocketCallback(ClientSocketHandle* handle,
497 TestConnectJobFactory* test_connect_job_factory, 524 TestConnectJobFactory* test_connect_job_factory,
498 TestConnectJob::JobType next_job_type) 525 TestConnectJob::JobType next_job_type)
499 : handle_(handle), 526 : handle_(handle),
500 within_callback_(false), 527 within_callback_(false),
501 test_connect_job_factory_(test_connect_job_factory), 528 test_connect_job_factory_(test_connect_job_factory),
(...skipping 30 matching lines...) Expand all
532 559
533 private: 560 private:
534 ClientSocketHandle* const handle_; 561 ClientSocketHandle* const handle_;
535 bool within_callback_; 562 bool within_callback_;
536 TestConnectJobFactory* const test_connect_job_factory_; 563 TestConnectJobFactory* const test_connect_job_factory_;
537 TestConnectJob::JobType next_job_type_; 564 TestConnectJob::JobType next_job_type_;
538 TestCompletionCallback callback_; 565 TestCompletionCallback callback_;
539 }; 566 };
540 567
541 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) { 568 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) {
569 CreatePool(kDefaultMaxSocketsPerGroup);
570
542 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 571 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
543 ClientSocketHandle handle(pool_.get()); 572 ClientSocketHandle handle(pool_.get());
544 RequestSocketCallback callback( 573 RequestSocketCallback callback(
545 &handle, connect_job_factory_, TestConnectJob::kMockPendingJob); 574 &handle, connect_job_factory_, TestConnectJob::kMockPendingJob);
546 int rv = handle.Init( 575 int rv = handle.Init(
547 "a", ignored_request_info_, kDefaultPriority, &callback); 576 "a", ignored_request_info_, kDefaultPriority, &callback);
548 ASSERT_EQ(ERR_IO_PENDING, rv); 577 ASSERT_EQ(ERR_IO_PENDING, rv);
549 578
550 EXPECT_EQ(OK, callback.WaitForResult()); 579 EXPECT_EQ(OK, callback.WaitForResult());
551 handle.Reset(); 580 handle.Reset();
552 } 581 }
553 582
554 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) { 583 TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) {
584 CreatePool(kDefaultMaxSocketsPerGroup);
585
555 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 586 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
556 ClientSocketHandle handle(pool_.get()); 587 ClientSocketHandle handle(pool_.get());
557 RequestSocketCallback callback( 588 RequestSocketCallback callback(
558 &handle, connect_job_factory_, TestConnectJob::kMockJob); 589 &handle, connect_job_factory_, TestConnectJob::kMockJob);
559 int rv = handle.Init( 590 int rv = handle.Init(
560 "a", ignored_request_info_, kDefaultPriority, &callback); 591 "a", ignored_request_info_, kDefaultPriority, &callback);
561 ASSERT_EQ(ERR_IO_PENDING, rv); 592 ASSERT_EQ(ERR_IO_PENDING, rv);
562 593
563 EXPECT_EQ(OK, callback.WaitForResult()); 594 EXPECT_EQ(OK, callback.WaitForResult());
564 handle.Reset(); 595 handle.Reset();
565 } 596 }
566 597
567 // Make sure that pending requests get serviced after active requests get 598 // Make sure that pending requests get serviced after active requests get
568 // cancelled. 599 // cancelled.
569 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) { 600 TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestWithPendingRequests) {
601 CreatePool(kDefaultMaxSocketsPerGroup);
602
570 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 603 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
571 604
572 scoped_ptr<TestSocketRequest> reqs[kNumRequests]; 605 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
606 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
607 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
608 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
609 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
610 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
611 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
573 612
574 // Queue up all the requests 613 // Now, kDefaultMaxSocketsPerGroup requests should be active.
575 for (size_t i = 0; i < arraysize(reqs); ++i) { 614 // Let's cancel them.
576 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 615 for (int i = 0; i < kDefaultMaxSocketsPerGroup; ++i) {
577 int rv = reqs[i]->handle.Init("a", ignored_request_info_, 616 ASSERT_FALSE(requests_[i]->handle.is_initialized());
578 kDefaultPriority, reqs[i].get()); 617 requests_[i]->handle.Reset();
579 EXPECT_EQ(ERR_IO_PENDING, rv);
580 } 618 }
581 619
582 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
583 for (int i = 0; i < kMaxSocketsPerGroup; ++i)
584 reqs[i]->handle.Reset();
585
586 // Let's wait for the rest to complete now. 620 // Let's wait for the rest to complete now.
587 for (size_t i = kMaxSocketsPerGroup; i < arraysize(reqs); ++i) { 621 for (size_t i = kDefaultMaxSocketsPerGroup; i < requests_.size(); ++i) {
588 EXPECT_EQ(OK, reqs[i]->WaitForResult()); 622 EXPECT_EQ(OK, requests_[i]->WaitForResult());
589 reqs[i]->handle.Reset(); 623 requests_[i]->handle.Reset();
590 } 624 }
591 625
592 EXPECT_EQ(kNumPendingRequests, TestSocketRequest::completion_count); 626 EXPECT_EQ(requests_.size() - kDefaultMaxSocketsPerGroup,
627 TestSocketRequest::completion_count);
593 } 628 }
594 629
595 // Make sure that pending requests get serviced after active requests fail. 630 // Make sure that pending requests get serviced after active requests fail.
596 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) { 631 TEST_F(ClientSocketPoolBaseTest, FailingActiveRequestWithPendingRequests) {
632 CreatePool(kDefaultMaxSocketsPerGroup);
633
597 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob); 634 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
598 635
599 scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup * 2 + 1]; 636 scoped_ptr<TestSocketRequest> reqs[kDefaultMaxSocketsPerGroup * 2 + 1];
600 637
601 // Queue up all the requests 638 // Queue up all the requests
602 for (size_t i = 0; i < arraysize(reqs); ++i) { 639 for (size_t i = 0; i < arraysize(reqs); ++i) {
603 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_)); 640 reqs[i].reset(new TestSocketRequest(pool_.get(), &request_order_));
604 int rv = reqs[i]->handle.Init("a", ignored_request_info_, 641 int rv = reqs[i]->handle.Init("a", ignored_request_info_,
605 kDefaultPriority, reqs[i].get()); 642 kDefaultPriority, reqs[i].get());
606 EXPECT_EQ(ERR_IO_PENDING, rv); 643 EXPECT_EQ(ERR_IO_PENDING, rv);
607 } 644 }
608 645
609 for (size_t i = 0; i < arraysize(reqs); ++i) 646 for (size_t i = 0; i < arraysize(reqs); ++i)
610 EXPECT_EQ(ERR_CONNECTION_FAILED, reqs[i]->WaitForResult()); 647 EXPECT_EQ(ERR_CONNECTION_FAILED, reqs[i]->WaitForResult());
611 } 648 }
612 649
613 // A pending asynchronous job completes, which will free up a socket slot. The 650 // A pending asynchronous job completes, which will free up a socket slot. The
614 // next job finishes synchronously. The callback for the asynchronous job 651 // next job finishes synchronously. The callback for the asynchronous job
615 // should be first though. 652 // should be first though.
616 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) { 653 TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) {
654 CreatePool(kDefaultMaxSocketsPerGroup);
655
617 // First two jobs are async. 656 // First two jobs are async.
618 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob); 657 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingFailingJob);
619 658
620 // Start job 1 (async error). 659 // Start job 1 (async error).
621 TestSocketRequest req1(pool_.get(), &request_order_); 660 TestSocketRequest req1(pool_.get(), &request_order_);
622 int rv = req1.handle.Init("a", ignored_request_info_, 661 int rv = req1.handle.Init("a", ignored_request_info_,
623 kDefaultPriority, &req1); 662 kDefaultPriority, &req1);
624 EXPECT_EQ(ERR_IO_PENDING, rv); 663 EXPECT_EQ(ERR_IO_PENDING, rv);
625 664
626 // Start job 2 (async error). 665 // Start job 2 (async error).
(...skipping 19 matching lines...) Expand all
646 // requests queue, so it starts up job 3 for request 3. This job 685 // requests queue, so it starts up job 3 for request 3. This job
647 // synchronously succeeds, so the request order is 1, 3, 2. 686 // synchronously succeeds, so the request order is 1, 3, 2.
648 EXPECT_EQ(&req1, request_order_[0]); 687 EXPECT_EQ(&req1, request_order_[0]);
649 EXPECT_EQ(&req2, request_order_[2]); 688 EXPECT_EQ(&req2, request_order_[2]);
650 EXPECT_EQ(&req3, request_order_[1]); 689 EXPECT_EQ(&req3, request_order_[1]);
651 } 690 }
652 691
653 } // namespace 692 } // namespace
654 693
655 } // namespace net 694 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool_base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698