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

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

Issue 9667016: Close idle connections / SPDY sessions when needed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename test to CloseIdleSpdySessionToOpenNewOne Created 8 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/socket/client_socket_pool_base.cc ('k') | net/socket/socks_client_socket_pool.h » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <vector>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
9 #include "base/callback.h" 11 #include "base/callback.h"
10 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
11 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_vector.h" 14 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h" 15 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop.h" 16 #include "base/message_loop.h"
15 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
16 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
17 #include "base/threading/platform_thread.h" 19 #include "base/threading/platform_thread.h"
18 #include "base/values.h" 20 #include "base/values.h"
19 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
20 #include "net/base/net_log.h" 22 #include "net/base/net_log.h"
21 #include "net/base/net_log_unittest.h" 23 #include "net/base/net_log_unittest.h"
22 #include "net/base/request_priority.h" 24 #include "net/base/request_priority.h"
23 #include "net/base/test_completion_callback.h" 25 #include "net/base/test_completion_callback.h"
24 #include "net/http/http_response_headers.h" 26 #include "net/http/http_response_headers.h"
25 #include "net/socket/client_socket_factory.h" 27 #include "net/socket/client_socket_factory.h"
26 #include "net/socket/client_socket_handle.h" 28 #include "net/socket/client_socket_handle.h"
27 #include "net/socket/client_socket_pool_histograms.h" 29 #include "net/socket/client_socket_pool_histograms.h"
28 #include "net/socket/socket_test_util.h" 30 #include "net/socket/socket_test_util.h"
29 #include "net/socket/ssl_host_info.h" 31 #include "net/socket/ssl_host_info.h"
30 #include "net/socket/stream_socket.h" 32 #include "net/socket/stream_socket.h"
33 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
32 35
36 using ::testing::Invoke;
37 using ::testing::Return;
38
33 namespace net { 39 namespace net {
34 40
35 namespace { 41 namespace {
36 42
37 const int kDefaultMaxSockets = 4; 43 const int kDefaultMaxSockets = 4;
38 const int kDefaultMaxSocketsPerGroup = 2; 44 const int kDefaultMaxSocketsPerGroup = 2;
39 const net::RequestPriority kDefaultPriority = MEDIUM; 45 const net::RequestPriority kDefaultPriority = MEDIUM;
40 46
41 class TestSocketParams : public base::RefCounted<TestSocketParams> { 47 class TestSocketParams : public base::RefCounted<TestSocketParams> {
42 public: 48 public:
43 bool ignore_limits() { return false; } 49 TestSocketParams() : ignore_limits_(false) {}
50
51 void set_ignore_limits(bool ignore_limits) {
52 ignore_limits_ = ignore_limits;
53 }
54 bool ignore_limits() { return ignore_limits_; }
55
44 private: 56 private:
45 friend class base::RefCounted<TestSocketParams>; 57 friend class base::RefCounted<TestSocketParams>;
46 ~TestSocketParams() {} 58 ~TestSocketParams() {}
59
60 bool ignore_limits_;
47 }; 61 };
48 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase; 62 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase;
49 63
50 class MockClientSocket : public StreamSocket { 64 class MockClientSocket : public StreamSocket {
51 public: 65 public:
52 MockClientSocket() : connected_(false), was_used_to_convey_data_(false), 66 MockClientSocket() : connected_(false), was_used_to_convey_data_(false),
53 num_bytes_read_(0) {} 67 num_bytes_read_(0) {}
54 68
55 // Socket implementation. 69 // Socket implementation.
56 virtual int Read( 70 virtual int Read(
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 bool store_additional_error_state_; 362 bool store_additional_error_state_;
349 363
350 DISALLOW_COPY_AND_ASSIGN(TestConnectJob); 364 DISALLOW_COPY_AND_ASSIGN(TestConnectJob);
351 }; 365 };
352 366
353 class TestConnectJobFactory 367 class TestConnectJobFactory
354 : public TestClientSocketPoolBase::ConnectJobFactory { 368 : public TestClientSocketPoolBase::ConnectJobFactory {
355 public: 369 public:
356 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory) 370 explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory)
357 : job_type_(TestConnectJob::kMockJob), 371 : job_type_(TestConnectJob::kMockJob),
372 job_types_(NULL),
358 client_socket_factory_(client_socket_factory) {} 373 client_socket_factory_(client_socket_factory) {}
359 374
360 virtual ~TestConnectJobFactory() {} 375 virtual ~TestConnectJobFactory() {}
361 376
362 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; } 377 void set_job_type(TestConnectJob::JobType job_type) { job_type_ = job_type; }
363 378
379 void set_job_types(std::vector<TestConnectJob::JobType>* job_types) {
380 job_types_ = job_types;
381 CHECK(!job_types_->empty());
382 }
383
364 void set_timeout_duration(base::TimeDelta timeout_duration) { 384 void set_timeout_duration(base::TimeDelta timeout_duration) {
365 timeout_duration_ = timeout_duration; 385 timeout_duration_ = timeout_duration;
366 } 386 }
367 387
368 // ConnectJobFactory implementation. 388 // ConnectJobFactory implementation.
369 389
370 virtual ConnectJob* NewConnectJob( 390 virtual ConnectJob* NewConnectJob(
371 const std::string& group_name, 391 const std::string& group_name,
372 const TestClientSocketPoolBase::Request& request, 392 const TestClientSocketPoolBase::Request& request,
373 ConnectJob::Delegate* delegate) const { 393 ConnectJob::Delegate* delegate) const {
374 return new TestConnectJob(job_type_, 394 TestConnectJob::JobType job_type = job_type_;
mmenke 2012/03/19 18:43:35 nit: Maybe an EXPECT_TRUE(!job_types_ || !job_typ
Ryan Hamilton 2012/03/19 19:04:15 Done.
395 if (job_types_ && !job_types_->empty()) {
396 job_type = job_types_->back();
397 job_types_->pop_back();
mmenke 2012/03/19 18:43:35 Think going front to back is much clearer. Wasn't
Ryan Hamilton 2012/03/19 19:04:15 Done.
398 }
399 return new TestConnectJob(job_type,
375 group_name, 400 group_name,
376 request, 401 request,
377 timeout_duration_, 402 timeout_duration_,
378 delegate, 403 delegate,
379 client_socket_factory_, 404 client_socket_factory_,
380 NULL); 405 NULL);
381 } 406 }
382 407
383 virtual base::TimeDelta ConnectionTimeout() const { 408 virtual base::TimeDelta ConnectionTimeout() const {
384 return timeout_duration_; 409 return timeout_duration_;
385 } 410 }
386 411
387 private: 412 private:
388 TestConnectJob::JobType job_type_; 413 TestConnectJob::JobType job_type_;
414 std::vector<TestConnectJob::JobType>* job_types_;
389 base::TimeDelta timeout_duration_; 415 base::TimeDelta timeout_duration_;
390 MockClientSocketFactory* const client_socket_factory_; 416 MockClientSocketFactory* const client_socket_factory_;
391 417
392 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory); 418 DISALLOW_COPY_AND_ASSIGN(TestConnectJobFactory);
393 }; 419 };
394 420
395 class TestClientSocketPool : public ClientSocketPool { 421 class TestClientSocketPool : public ClientSocketPool {
396 public: 422 public:
397 TestClientSocketPool( 423 TestClientSocketPool(
398 int max_sockets, 424 int max_sockets,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 const std::string& group_name, 466 const std::string& group_name,
441 StreamSocket* socket, 467 StreamSocket* socket,
442 int id) OVERRIDE { 468 int id) OVERRIDE {
443 base_.ReleaseSocket(group_name, socket, id); 469 base_.ReleaseSocket(group_name, socket, id);
444 } 470 }
445 471
446 virtual void Flush() OVERRIDE { 472 virtual void Flush() OVERRIDE {
447 base_.Flush(); 473 base_.Flush();
448 } 474 }
449 475
476 virtual bool IsStalled() const OVERRIDE {
477 return base_.IsStalled();
478 }
479
450 virtual void CloseIdleSockets() OVERRIDE { 480 virtual void CloseIdleSockets() OVERRIDE {
451 base_.CloseIdleSockets(); 481 base_.CloseIdleSockets();
452 } 482 }
453 483
454 virtual int IdleSocketCount() const OVERRIDE { 484 virtual int IdleSocketCount() const OVERRIDE {
455 return base_.idle_socket_count(); 485 return base_.idle_socket_count();
456 } 486 }
457 487
458 virtual int IdleSocketCountInGroup( 488 virtual int IdleSocketCountInGroup(
459 const std::string& group_name) const OVERRIDE { 489 const std::string& group_name) const OVERRIDE {
460 return base_.IdleSocketCountInGroup(group_name); 490 return base_.IdleSocketCountInGroup(group_name);
461 } 491 }
462 492
463 virtual LoadState GetLoadState( 493 virtual LoadState GetLoadState(
464 const std::string& group_name, 494 const std::string& group_name,
465 const ClientSocketHandle* handle) const OVERRIDE { 495 const ClientSocketHandle* handle) const OVERRIDE {
466 return base_.GetLoadState(group_name, handle); 496 return base_.GetLoadState(group_name, handle);
467 } 497 }
468 498
499 virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE {
500 base_.AddLayeredPool(pool);
501 }
502
503 virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE {
504 base_.RemoveLayeredPool(pool);
505 }
506
469 virtual DictionaryValue* GetInfoAsValue( 507 virtual DictionaryValue* GetInfoAsValue(
470 const std::string& name, 508 const std::string& name,
471 const std::string& type, 509 const std::string& type,
472 bool include_nested_pools) const OVERRIDE { 510 bool include_nested_pools) const OVERRIDE {
473 return base_.GetInfoAsValue(name, type); 511 return base_.GetInfoAsValue(name, type);
474 } 512 }
475 513
476 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE { 514 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE {
477 return base_.ConnectionTimeout(); 515 return base_.ConnectionTimeout();
478 } 516 }
(...skipping 13 matching lines...) Expand all
492 } 530 }
493 531
494 bool HasGroup(const std::string& group_name) const { 532 bool HasGroup(const std::string& group_name) const {
495 return base_.HasGroup(group_name); 533 return base_.HasGroup(group_name);
496 } 534 }
497 535
498 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); } 536 void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); }
499 537
500 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); } 538 void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); }
501 539
540 bool CloseOneIdleConnectionInLayeredPool() {
541 return base_.CloseOneIdleConnectionInLayeredPool();
542 }
543
502 private: 544 private:
503 TestClientSocketPoolBase base_; 545 TestClientSocketPoolBase base_;
504 546
505 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool); 547 DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool);
506 }; 548 };
507 549
508 } // namespace 550 } // namespace
509 551
510 REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams); 552 REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams);
511 553
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 EXPECT_EQ(1, pool_->IdleSocketCount()); 1199 EXPECT_EQ(1, pool_->IdleSocketCount());
1158 } 1200 }
1159 1201
1160 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) { 1202 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) {
1161 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); 1203 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
1162 connect_job_factory_->set_job_type(TestConnectJob::kMockJob); 1204 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
1163 1205
1164 ClientSocketHandle stalled_handle; 1206 ClientSocketHandle stalled_handle;
1165 TestCompletionCallback callback; 1207 TestCompletionCallback callback;
1166 { 1208 {
1209 EXPECT_FALSE(pool_->IsStalled());
1167 ClientSocketHandle handles[kDefaultMaxSockets]; 1210 ClientSocketHandle handles[kDefaultMaxSockets];
1168 for (int i = 0; i < kDefaultMaxSockets; ++i) { 1211 for (int i = 0; i < kDefaultMaxSockets; ++i) {
1169 TestCompletionCallback callback; 1212 TestCompletionCallback callback;
1170 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf( 1213 EXPECT_EQ(OK, handles[i].Init(base::StringPrintf(
1171 "Take 2: %d", i), 1214 "Take 2: %d", i),
1172 params_, 1215 params_,
1173 kDefaultPriority, 1216 kDefaultPriority,
1174 callback.callback(), 1217 callback.callback(),
1175 pool_.get(), 1218 pool_.get(),
1176 BoundNetLog())); 1219 BoundNetLog()));
1177 } 1220 }
1178 1221
1179 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count()); 1222 EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
1180 EXPECT_EQ(0, pool_->IdleSocketCount()); 1223 EXPECT_EQ(0, pool_->IdleSocketCount());
1224 EXPECT_FALSE(pool_->IsStalled());
1181 1225
1182 // Now we will hit the socket limit. 1226 // Now we will hit the socket limit.
1183 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", 1227 EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo",
1184 params_, 1228 params_,
1185 kDefaultPriority, 1229 kDefaultPriority,
1186 callback.callback(), 1230 callback.callback(),
1187 pool_.get(), 1231 pool_.get(),
1188 BoundNetLog())); 1232 BoundNetLog()));
1233 EXPECT_TRUE(pool_->IsStalled());
1189 1234
1190 // Dropping out of scope will close all handles and return them to idle. 1235 // Dropping out of scope will close all handles and return them to idle.
1191 } 1236 }
1192 1237
1193 // But if we wait for it, the released idle sockets will be closed in 1238 // But if we wait for it, the released idle sockets will be closed in
1194 // preference of the waiting request. 1239 // preference of the waiting request.
1195 EXPECT_EQ(OK, callback.WaitForResult()); 1240 EXPECT_EQ(OK, callback.WaitForResult());
1196 1241
1197 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count()); 1242 EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count());
1198 EXPECT_EQ(3, pool_->IdleSocketCount()); 1243 EXPECT_EQ(3, pool_->IdleSocketCount());
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 // job. Release the socket. Run the loop again to make sure the second 2043 // job. Release the socket. Run the loop again to make sure the second
1999 // socket is sitting idle and the first one is released (since ReleaseSocket() 2044 // socket is sitting idle and the first one is released (since ReleaseSocket()
2000 // just posts a DoReleaseSocket() task). 2045 // just posts a DoReleaseSocket() task).
2001 2046
2002 handle.Reset(); 2047 handle.Reset();
2003 EXPECT_EQ(OK, callback2.WaitForResult()); 2048 EXPECT_EQ(OK, callback2.WaitForResult());
2004 // Use the socket. 2049 // Use the socket.
2005 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback())); 2050 EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, CompletionCallback()));
2006 handle2.Reset(); 2051 handle2.Reset();
2007 2052
2008 // The idle socket timeout value was set to 10 milliseconds. Wait 20 2053 // The idle socket timeout value was set to 10 milliseconds. Wait 100
2009 // milliseconds so the sockets timeout. 2054 // milliseconds so the sockets timeout.
2010 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20)); 2055 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
2011 MessageLoop::current()->RunAllPending(); 2056 MessageLoop::current()->RunAllPending();
2012 2057
2013 ASSERT_EQ(2, pool_->IdleSocketCount()); 2058 ASSERT_EQ(2, pool_->IdleSocketCount());
2014 2059
2015 // Request a new socket. This should cleanup the unused and timed out ones. 2060 // Request a new socket. This should cleanup the unused and timed out ones.
2016 // A new socket will be created rather than reusing the idle one. 2061 // A new socket will be created rather than reusing the idle one.
2017 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); 2062 CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
2018 TestCompletionCallback callback3; 2063 TestCompletionCallback callback3;
2019 rv = handle.Init("a", 2064 rv = handle.Init("a",
2020 params_, 2065 params_,
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
3032 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets); 3077 CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
3033 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 3078 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3034 3079
3035 ASSERT_FALSE(pool_->HasGroup("a")); 3080 ASSERT_FALSE(pool_->HasGroup("a"));
3036 3081
3037 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1, 3082 pool_->RequestSockets("a", &params_, kDefaultMaxSockets - 1,
3038 BoundNetLog()); 3083 BoundNetLog());
3039 3084
3040 ASSERT_TRUE(pool_->HasGroup("a")); 3085 ASSERT_TRUE(pool_->HasGroup("a"));
3041 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a")); 3086 EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a"));
3087 EXPECT_FALSE(pool_->IsStalled());
3042 3088
3043 ASSERT_FALSE(pool_->HasGroup("b")); 3089 ASSERT_FALSE(pool_->HasGroup("b"));
3044 3090
3045 pool_->RequestSockets("b", &params_, kDefaultMaxSockets, 3091 pool_->RequestSockets("b", &params_, kDefaultMaxSockets,
3046 BoundNetLog()); 3092 BoundNetLog());
3047 3093
3048 ASSERT_TRUE(pool_->HasGroup("b")); 3094 ASSERT_TRUE(pool_->HasGroup("b"));
3049 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b")); 3095 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b"));
3096 EXPECT_FALSE(pool_->IsStalled());
3050 } 3097 }
3051 3098
3052 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) { 3099 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) {
3053 CreatePool(4, 4); 3100 CreatePool(4, 4);
3054 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); 3101 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
3055 3102
3056 ClientSocketHandle handle1; 3103 ClientSocketHandle handle1;
3057 TestCompletionCallback callback1; 3104 TestCompletionCallback callback1;
3058 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", 3105 EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a",
3059 params_, 3106 params_,
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
3358 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a")); 3405 EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a"));
3359 ASSERT_EQ(OK, callback.WaitForResult()); 3406 ASSERT_EQ(OK, callback.WaitForResult());
3360 3407
3361 // The hung connect job should still be there, but everything else should be 3408 // The hung connect job should still be there, but everything else should be
3362 // complete. 3409 // complete.
3363 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); 3410 EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a"));
3364 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); 3411 EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a"));
3365 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a")); 3412 EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a"));
3366 } 3413 }
3367 3414
3415 class MockLayeredPool : public LayeredPool {
3416 public:
3417 MockLayeredPool(TestClientSocketPool* pool,
3418 const std::string& group_name)
3419 : pool_(pool),
3420 params_(new TestSocketParams),
3421 group_name_(group_name),
3422 can_release_connection_(true) {
3423 pool_->AddLayeredPool(this);
3424 }
3425
3426 ~MockLayeredPool() {
3427 pool_->RemoveLayeredPool(this);
3428 }
3429
3430 int RequestSocket(TestClientSocketPool* pool) {
3431 return handle_.Init(group_name_, params_, kDefaultPriority,
3432 callback_.callback(), pool, BoundNetLog());
3433 }
3434
3435 int RequestSocketWithoutLimits(TestClientSocketPool* pool) {
3436 params_->set_ignore_limits(true);
3437 return handle_.Init(group_name_, params_, kDefaultPriority,
3438 callback_.callback(), pool, BoundNetLog());
3439 }
3440
3441 bool ReleaseOneConnection() {
3442 if (!handle_.is_initialized() || !can_release_connection_) {
3443 return false;
3444 }
3445 handle_.socket()->Disconnect();
3446 handle_.Reset();
3447 return true;
3448 }
3449
3450 void set_can_release_connection(bool can_release_connection) {
3451 can_release_connection_ = can_release_connection;
3452 }
3453
3454 MOCK_METHOD0(CloseOneIdleConnection, bool());
3455
3456 private:
3457 TestClientSocketPool* const pool_;
3458 scoped_refptr<TestSocketParams> params_;
3459 ClientSocketHandle handle_;
3460 TestCompletionCallback callback_;
3461 const std::string group_name_;
3462 bool can_release_connection_;
3463 };
3464
3465 TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) {
3466 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3467 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3468
3469 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3470 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3471 .WillOnce(Return(false));
mmenke 2012/03/19 18:43:35 nit: To make this test more closely match the nex
Ryan Hamilton 2012/03/19 19:04:15 Done.
3472 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3473 EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool());
3474 }
3475
3476 TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) {
3477 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
3478 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3479
3480 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3481 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3482 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3483 .WillOnce(Invoke(&mock_layered_pool,
3484 &MockLayeredPool::ReleaseOneConnection));
3485 EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool());
3486 }
3487
3488 // This test exercises the codepath which caused http://crbug.com/109876
3489 TEST_F(ClientSocketPoolBaseTest,
3490 CloseIdleSocketsHeldByLayeredPoolInSameGroupWhenNeeded) {
3491 CreatePool(2, 2);
3492 std::vector<TestConnectJob::JobType> job_types;
3493 job_types.push_back(TestConnectJob::kMockJob);
3494 job_types.push_back(TestConnectJob::kMockFailingJob);
3495 job_types.push_back(TestConnectJob::kMockJob);
3496 job_types.push_back(TestConnectJob::kMockJob);
3497 connect_job_factory_->set_job_types(&job_types);
3498
3499 ClientSocketHandle handle1;
3500 TestCompletionCallback callback1;
3501 EXPECT_EQ(OK, handle1.Init("group1",
3502 params_,
3503 kDefaultPriority,
3504 callback1.callback(),
3505 pool_.get(),
3506 BoundNetLog()));
mmenke 2012/03/19 18:43:35 nit: Fix indent.
Ryan Hamilton 2012/03/19 19:04:15 Done.
3507
3508 MockLayeredPool mock_layered_pool(pool_.get(), "group2");
3509 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3510 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3511 .WillRepeatedly(Invoke(&mock_layered_pool,
3512 &MockLayeredPool::ReleaseOneConnection));
mmenke 2012/03/19 18:43:35 nit: -1 indent.
Ryan Hamilton 2012/03/19 19:04:15 Done.
3513 mock_layered_pool.set_can_release_connection(false);
3514
3515 ClientSocketHandle handle2;
mmenke 2012/03/19 18:43:35 Suggest you name these handle3 and handle4, so the
mmenke 2012/03/19 18:43:35 Suggest you add a comment here saying that this co
Ryan Hamilton 2012/03/19 19:04:15 Done. Good idea.
Ryan Hamilton 2012/03/19 19:04:15 Done.
3516 TestCompletionCallback callback2;
3517 EXPECT_EQ(ERR_IO_PENDING, handle2.Init("group2",
3518 params_,
3519 HIGHEST,
mmenke 2012/03/19 18:43:35 I don't think this or the next request has to be a
Ryan Hamilton 2012/03/19 19:04:15 Done. Yes, you're right. This was a leftover fro
3520 callback2.callback(),
3521 pool_.get(),
3522 BoundNetLog()));
3523
3524 mock_layered_pool.set_can_release_connection(true);
3525 ClientSocketHandle handle3;
3526 TestCompletionCallback callback3;
3527 EXPECT_EQ(OK, handle3.Init("group2",
3528 params_,
3529 HIGHEST,
3530 callback3.callback(),
3531 pool_.get(),
3532 BoundNetLog()));
mmenke 2012/03/19 18:43:35 nit: Fix indent.
Ryan Hamilton 2012/03/19 19:04:15 Done.
3533 }
3534
3535 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) {
3536 CreatePool(1, 1);
3537 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3538
3539 MockLayeredPool mock_layered_pool(pool_.get(), "foo");
3540 EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get()));
3541 EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection())
3542 .WillOnce(Invoke(&mock_layered_pool,
3543 &MockLayeredPool::ReleaseOneConnection));
3544 ClientSocketHandle handle;
3545 TestCompletionCallback callback;
3546 EXPECT_EQ(OK, handle.Init("a",
3547 params_,
3548 kDefaultPriority,
3549 callback.callback(),
3550 pool_.get(),
3551 BoundNetLog()));
3552 }
3553
3554 TEST_F(ClientSocketPoolBaseTest,
3555 CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) {
3556 CreatePool(1, 1);
3557 connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
3558
3559 MockLayeredPool mock_layered_pool1(pool_.get(), "foo");
3560 EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get()));
3561 EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection())
3562 .WillRepeatedly(Invoke(&mock_layered_pool1,
3563 &MockLayeredPool::ReleaseOneConnection));
3564 MockLayeredPool mock_layered_pool2(pool_.get(), "bar");
3565 EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get()));
3566 EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection())
3567 .WillRepeatedly(Invoke(&mock_layered_pool2,
3568 &MockLayeredPool::ReleaseOneConnection));
3569 ClientSocketHandle handle;
3570 TestCompletionCallback callback;
3571 EXPECT_EQ(OK, handle.Init("a",
3572 params_,
3573 kDefaultPriority,
3574 callback.callback(),
3575 pool_.get(),
3576 BoundNetLog()));
3577 }
3578
3368 } // namespace 3579 } // namespace
3369 3580
3370 } // namespace net 3581 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool_base.cc ('k') | net/socket/socks_client_socket_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698