| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/callback.h" | 7 #include "base/callback.h" | 
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" | 
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" | 
| 10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" | 
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" | 
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" | 
| 13 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" | 
| 14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" | 
| 15 #include "base/values.h" | 15 #include "base/values.h" | 
| 16 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" | 
| 17 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" | 
| 18 #include "net/base/net_log_unittest.h" | 18 #include "net/base/net_log_unittest.h" | 
| 19 #include "net/base/request_priority.h" | 19 #include "net/base/request_priority.h" | 
| 20 #include "net/base/test_completion_callback.h" | 20 #include "net/base/test_completion_callback.h" | 
| 21 #include "net/http/http_response_headers.h" | 21 #include "net/http/http_response_headers.h" | 
| 22 #include "net/socket/client_socket_factory.h" | 22 #include "net/socket/client_socket_factory.h" | 
| 23 #include "net/socket/client_socket_handle.h" | 23 #include "net/socket/client_socket_handle.h" | 
| 24 #include "net/socket/client_socket_pool_histograms.h" | 24 #include "net/socket/client_socket_pool_histograms.h" | 
| 25 #include "net/socket/socket_test_util.h" | 25 #include "net/socket/socket_test_util.h" | 
| 26 #include "net/socket/ssl_host_info.h" | 26 #include "net/socket/ssl_host_info.h" | 
| 27 #include "net/socket/stream_socket.h" | 27 #include "net/socket/stream_socket.h" | 
| 28 #include "testing/gmock/include/gmock/gmock.h" |  | 
| 29 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" | 
| 30 | 29 | 
| 31 using ::testing::Invoke; |  | 
| 32 using ::testing::Return; |  | 
| 33 |  | 
| 34 namespace net { | 30 namespace net { | 
| 35 | 31 | 
| 36 namespace { | 32 namespace { | 
| 37 | 33 | 
| 38 const int kDefaultMaxSockets = 4; | 34 const int kDefaultMaxSockets = 4; | 
| 39 const int kDefaultMaxSocketsPerGroup = 2; | 35 const int kDefaultMaxSocketsPerGroup = 2; | 
| 40 const net::RequestPriority kDefaultPriority = MEDIUM; | 36 const net::RequestPriority kDefaultPriority = MEDIUM; | 
| 41 | 37 | 
| 42 class TestSocketParams : public base::RefCounted<TestSocketParams> { | 38 class TestSocketParams : public base::RefCounted<TestSocketParams> { | 
| 43  public: | 39  public: | 
| 44   TestSocketParams() : ignore_limits_(false) {} | 40   bool ignore_limits() { return false; } | 
| 45 |  | 
| 46   void set_ignore_limits(bool ignore_limits) { |  | 
| 47     ignore_limits_ = ignore_limits; |  | 
| 48   } |  | 
| 49   bool ignore_limits() { return ignore_limits_; } |  | 
| 50 |  | 
| 51  private: | 41  private: | 
| 52   friend class base::RefCounted<TestSocketParams>; | 42   friend class base::RefCounted<TestSocketParams>; | 
| 53   ~TestSocketParams() {} | 43   ~TestSocketParams() {} | 
| 54 |  | 
| 55   bool ignore_limits_; |  | 
| 56 }; | 44 }; | 
| 57 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase; | 45 typedef ClientSocketPoolBase<TestSocketParams> TestClientSocketPoolBase; | 
| 58 | 46 | 
| 59 class MockClientSocket : public StreamSocket { | 47 class MockClientSocket : public StreamSocket { | 
| 60  public: | 48  public: | 
| 61   MockClientSocket() : connected_(false), was_used_to_convey_data_(false), | 49   MockClientSocket() : connected_(false), was_used_to_convey_data_(false), | 
| 62                        num_bytes_read_(0) {} | 50                        num_bytes_read_(0) {} | 
| 63 | 51 | 
| 64   // Socket methods: | 52   // Socket methods: | 
| 65   virtual int Read( | 53   virtual int Read( | 
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 416               connect_job_factory) {} | 404               connect_job_factory) {} | 
| 417 | 405 | 
| 418   virtual ~TestClientSocketPool() {} | 406   virtual ~TestClientSocketPool() {} | 
| 419 | 407 | 
| 420   virtual int RequestSocket( | 408   virtual int RequestSocket( | 
| 421       const std::string& group_name, | 409       const std::string& group_name, | 
| 422       const void* params, | 410       const void* params, | 
| 423       net::RequestPriority priority, | 411       net::RequestPriority priority, | 
| 424       ClientSocketHandle* handle, | 412       ClientSocketHandle* handle, | 
| 425       OldCompletionCallback* callback, | 413       OldCompletionCallback* callback, | 
| 426       const BoundNetLog& net_log) OVERRIDE { | 414       const BoundNetLog& net_log) { | 
| 427     const scoped_refptr<TestSocketParams>* casted_socket_params = | 415     const scoped_refptr<TestSocketParams>* casted_socket_params = | 
| 428         static_cast<const scoped_refptr<TestSocketParams>*>(params); | 416         static_cast<const scoped_refptr<TestSocketParams>*>(params); | 
| 429     return base_.RequestSocket(group_name, *casted_socket_params, priority, | 417     return base_.RequestSocket(group_name, *casted_socket_params, priority, | 
| 430                                handle, callback, net_log); | 418                                handle, callback, net_log); | 
| 431   } | 419   } | 
| 432 | 420 | 
| 433   virtual void RequestSockets(const std::string& group_name, | 421   virtual void RequestSockets(const std::string& group_name, | 
| 434                               const void* params, | 422                               const void* params, | 
| 435                               int num_sockets, | 423                               int num_sockets, | 
| 436                               const BoundNetLog& net_log) OVERRIDE { | 424                               const BoundNetLog& net_log) { | 
| 437     const scoped_refptr<TestSocketParams>* casted_params = | 425     const scoped_refptr<TestSocketParams>* casted_params = | 
| 438         static_cast<const scoped_refptr<TestSocketParams>*>(params); | 426         static_cast<const scoped_refptr<TestSocketParams>*>(params); | 
| 439 | 427 | 
| 440     base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); | 428     base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); | 
| 441   } | 429   } | 
| 442 | 430 | 
| 443   virtual void CancelRequest( | 431   virtual void CancelRequest( | 
| 444       const std::string& group_name, | 432       const std::string& group_name, | 
| 445       ClientSocketHandle* handle) OVERRIDE { | 433       ClientSocketHandle* handle) { | 
| 446     base_.CancelRequest(group_name, handle); | 434     base_.CancelRequest(group_name, handle); | 
| 447   } | 435   } | 
| 448 | 436 | 
| 449   virtual void ReleaseSocket( | 437   virtual void ReleaseSocket( | 
| 450       const std::string& group_name, | 438       const std::string& group_name, | 
| 451       StreamSocket* socket, | 439       StreamSocket* socket, | 
| 452       int id) OVERRIDE { | 440       int id) { | 
| 453     base_.ReleaseSocket(group_name, socket, id); | 441     base_.ReleaseSocket(group_name, socket, id); | 
| 454   } | 442   } | 
| 455 | 443 | 
| 456   virtual void Flush() OVERRIDE { | 444   virtual void Flush() { | 
| 457     base_.Flush(); | 445     base_.Flush(); | 
| 458   } | 446   } | 
| 459 | 447 | 
| 460   virtual bool IsStalled() const OVERRIDE { | 448   virtual void CloseIdleSockets() { | 
| 461     return base_.IsStalled(); |  | 
| 462   } |  | 
| 463 |  | 
| 464   virtual void CloseIdleSockets() OVERRIDE { |  | 
| 465     base_.CloseIdleSockets(); | 449     base_.CloseIdleSockets(); | 
| 466   } | 450   } | 
| 467 | 451 | 
| 468   virtual int IdleSocketCount() const OVERRIDE { | 452   virtual int IdleSocketCount() const { return base_.idle_socket_count(); } | 
| 469     return base_.idle_socket_count(); |  | 
| 470   } |  | 
| 471 | 453 | 
| 472   virtual int IdleSocketCountInGroup( | 454   virtual int IdleSocketCountInGroup(const std::string& group_name) const { | 
| 473       const std::string& group_name) const OVERRIDE { |  | 
| 474     return base_.IdleSocketCountInGroup(group_name); | 455     return base_.IdleSocketCountInGroup(group_name); | 
| 475   } | 456   } | 
| 476 | 457 | 
| 477   virtual LoadState GetLoadState( | 458   virtual LoadState GetLoadState(const std::string& group_name, | 
| 478       const std::string& group_name, | 459                                  const ClientSocketHandle* handle) const { | 
| 479       const ClientSocketHandle* handle) const OVERRIDE { |  | 
| 480     return base_.GetLoadState(group_name, handle); | 460     return base_.GetLoadState(group_name, handle); | 
| 481   } | 461   } | 
| 482 | 462 | 
| 483   virtual void AddLayeredPool(LayeredPool* pool) OVERRIDE { | 463   virtual DictionaryValue* GetInfoAsValue(const std::string& name, | 
| 484     base_.AddLayeredPool(pool); | 464                                           const std::string& type, | 
| 485   } | 465                                           bool include_nested_pools) const { | 
| 486 |  | 
| 487   virtual void RemoveLayeredPool(LayeredPool* pool) OVERRIDE { |  | 
| 488     base_.RemoveLayeredPool(pool); |  | 
| 489   } |  | 
| 490 |  | 
| 491   virtual DictionaryValue* GetInfoAsValue( |  | 
| 492       const std::string& name, |  | 
| 493       const std::string& type, |  | 
| 494       bool include_nested_pools) const OVERRIDE { |  | 
| 495     return base_.GetInfoAsValue(name, type); | 466     return base_.GetInfoAsValue(name, type); | 
| 496   } | 467   } | 
| 497 | 468 | 
| 498   virtual base::TimeDelta ConnectionTimeout() const OVERRIDE { | 469   virtual base::TimeDelta ConnectionTimeout() const { | 
| 499     return base_.ConnectionTimeout(); | 470     return base_.ConnectionTimeout(); | 
| 500   } | 471   } | 
| 501 | 472 | 
| 502   virtual ClientSocketPoolHistograms* histograms() const OVERRIDE { | 473   virtual ClientSocketPoolHistograms* histograms() const { | 
| 503     return base_.histograms(); | 474     return base_.histograms(); | 
| 504   } | 475   } | 
| 505 | 476 | 
| 506   const TestClientSocketPoolBase* base() const { return &base_; } | 477   const TestClientSocketPoolBase* base() const { return &base_; } | 
| 507 | 478 | 
| 508   int NumConnectJobsInGroup(const std::string& group_name) const { | 479   int NumConnectJobsInGroup(const std::string& group_name) const { | 
| 509     return base_.NumConnectJobsInGroup(group_name); | 480     return base_.NumConnectJobsInGroup(group_name); | 
| 510   } | 481   } | 
| 511 | 482 | 
| 512   int NumActiveSocketsInGroup(const std::string& group_name) const { | 483   int NumActiveSocketsInGroup(const std::string& group_name) const { | 
| 513     return base_.NumActiveSocketsInGroup(group_name); | 484     return base_.NumActiveSocketsInGroup(group_name); | 
| 514   } | 485   } | 
| 515 | 486 | 
| 516   bool HasGroup(const std::string& group_name) const { | 487   bool HasGroup(const std::string& group_name) const { | 
| 517     return base_.HasGroup(group_name); | 488     return base_.HasGroup(group_name); | 
| 518   } | 489   } | 
| 519 | 490 | 
| 520   void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); } | 491   void CleanupTimedOutIdleSockets() { base_.CleanupIdleSockets(false); } | 
| 521 | 492 | 
| 522   void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); } | 493   void EnableConnectBackupJobs() { base_.EnableConnectBackupJobs(); } | 
| 523 | 494 | 
| 524   bool CloseOneIdleConnectionInLayeredPool() { |  | 
| 525     return base_.CloseOneIdleConnectionInLayeredPool(); |  | 
| 526   } |  | 
| 527 |  | 
| 528  private: | 495  private: | 
| 529   TestClientSocketPoolBase base_; | 496   TestClientSocketPoolBase base_; | 
| 530 | 497 | 
| 531   DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool); | 498   DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool); | 
| 532 }; | 499 }; | 
| 533 | 500 | 
| 534 }  // namespace | 501 }  // namespace | 
| 535 | 502 | 
| 536 REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams); | 503 REGISTER_SOCKET_PARAMS_FOR_POOL(TestClientSocketPool, TestSocketParams); | 
| 537 | 504 | 
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1183   EXPECT_EQ(1, pool_->IdleSocketCount()); | 1150   EXPECT_EQ(1, pool_->IdleSocketCount()); | 
| 1184 } | 1151 } | 
| 1185 | 1152 | 
| 1186 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) { | 1153 TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) { | 
| 1187   CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 1154   CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 
| 1188   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); | 1155   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); | 
| 1189 | 1156 | 
| 1190   ClientSocketHandle stalled_handle; | 1157   ClientSocketHandle stalled_handle; | 
| 1191   TestOldCompletionCallback callback; | 1158   TestOldCompletionCallback callback; | 
| 1192   { | 1159   { | 
| 1193     EXPECT_FALSE(pool_->IsStalled()); |  | 
| 1194     ClientSocketHandle handles[kDefaultMaxSockets]; | 1160     ClientSocketHandle handles[kDefaultMaxSockets]; | 
| 1195     for (int i = 0; i < kDefaultMaxSockets; ++i) { | 1161     for (int i = 0; i < kDefaultMaxSockets; ++i) { | 
| 1196       TestOldCompletionCallback callback; | 1162       TestOldCompletionCallback callback; | 
| 1197       EXPECT_EQ(OK, handles[i].Init(base::StringPrintf( | 1163       EXPECT_EQ(OK, handles[i].Init(base::StringPrintf( | 
| 1198           "Take 2: %d", i), | 1164           "Take 2: %d", i), | 
| 1199           params_, | 1165           params_, | 
| 1200           kDefaultPriority, | 1166           kDefaultPriority, | 
| 1201           &callback, | 1167           &callback, | 
| 1202           pool_.get(), | 1168           pool_.get(), | 
| 1203           BoundNetLog())); | 1169           BoundNetLog())); | 
| 1204     } | 1170     } | 
| 1205 | 1171 | 
| 1206     EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count()); | 1172     EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count()); | 
| 1207     EXPECT_EQ(0, pool_->IdleSocketCount()); | 1173     EXPECT_EQ(0, pool_->IdleSocketCount()); | 
| 1208     EXPECT_FALSE(pool_->IsStalled()); |  | 
| 1209 | 1174 | 
| 1210     // Now we will hit the socket limit. | 1175     // Now we will hit the socket limit. | 
| 1211     EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", | 1176     EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init("foo", | 
| 1212                                                   params_, | 1177                                                   params_, | 
| 1213                                                   kDefaultPriority, | 1178                                                   kDefaultPriority, | 
| 1214                                                   &callback, | 1179                                                   &callback, | 
| 1215                                                   pool_.get(), | 1180                                                   pool_.get(), | 
| 1216                                                   BoundNetLog())); | 1181                                                   BoundNetLog())); | 
| 1217     EXPECT_TRUE(pool_->IsStalled()); |  | 
| 1218 | 1182 | 
| 1219     // Dropping out of scope will close all handles and return them to idle. | 1183     // Dropping out of scope will close all handles and return them to idle. | 
| 1220   } | 1184   } | 
| 1221 | 1185 | 
| 1222   // But if we wait for it, the released idle sockets will be closed in | 1186   // But if we wait for it, the released idle sockets will be closed in | 
| 1223   // preference of the waiting request. | 1187   // preference of the waiting request. | 
| 1224   EXPECT_EQ(OK, callback.WaitForResult()); | 1188   EXPECT_EQ(OK, callback.WaitForResult()); | 
| 1225 | 1189 | 
| 1226   EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count()); | 1190   EXPECT_EQ(kDefaultMaxSockets + 1, client_socket_factory_.allocation_count()); | 
| 1227   EXPECT_EQ(3, pool_->IdleSocketCount()); | 1191   EXPECT_EQ(3, pool_->IdleSocketCount()); | 
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2028   // just posts a DoReleaseSocket() task). | 1992   // just posts a DoReleaseSocket() task). | 
| 2029 | 1993 | 
| 2030   handle.Reset(); | 1994   handle.Reset(); | 
| 2031   EXPECT_EQ(OK, callback2.WaitForResult()); | 1995   EXPECT_EQ(OK, callback2.WaitForResult()); | 
| 2032   // Use the socket. | 1996   // Use the socket. | 
| 2033   EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL)); | 1997   EXPECT_EQ(1, handle2.socket()->Write(NULL, 1, NULL)); | 
| 2034   handle2.Reset(); | 1998   handle2.Reset(); | 
| 2035 | 1999 | 
| 2036   // The idle socket timeout value was set to 10 milliseconds. Wait 20 | 2000   // The idle socket timeout value was set to 10 milliseconds. Wait 20 | 
| 2037   // milliseconds so the sockets timeout. | 2001   // milliseconds so the sockets timeout. | 
| 2038   base::PlatformThread::Sleep(100); | 2002   base::PlatformThread::Sleep(20); | 
| 2039   MessageLoop::current()->RunAllPending(); | 2003   MessageLoop::current()->RunAllPending(); | 
| 2040 | 2004 | 
| 2041   ASSERT_EQ(2, pool_->IdleSocketCount()); | 2005   ASSERT_EQ(2, pool_->IdleSocketCount()); | 
| 2042 | 2006 | 
| 2043   // Request a new socket. This should cleanup the unused and timed out ones. | 2007   // Request a new socket. This should cleanup the unused and timed out ones. | 
| 2044   // A new socket will be created rather than reusing the idle one. | 2008   // A new socket will be created rather than reusing the idle one. | 
| 2045   CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 2009   CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 
| 2046   rv = handle.Init("a", | 2010   rv = handle.Init("a", | 
| 2047                    params_, | 2011                    params_, | 
| 2048                    LOWEST, | 2012                    LOWEST, | 
| (...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3055   CreatePool(kDefaultMaxSockets, kDefaultMaxSockets); | 3019   CreatePool(kDefaultMaxSockets, kDefaultMaxSockets); | 
| 3056   connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 3020   connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 
| 3057 | 3021 | 
| 3058   ASSERT_FALSE(pool_->HasGroup("a")); | 3022   ASSERT_FALSE(pool_->HasGroup("a")); | 
| 3059 | 3023 | 
| 3060   pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets - 1, | 3024   pool_->RequestSockets("a", ¶ms_, kDefaultMaxSockets - 1, | 
| 3061                         BoundNetLog()); | 3025                         BoundNetLog()); | 
| 3062 | 3026 | 
| 3063   ASSERT_TRUE(pool_->HasGroup("a")); | 3027   ASSERT_TRUE(pool_->HasGroup("a")); | 
| 3064   EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a")); | 3028   EXPECT_EQ(kDefaultMaxSockets - 1, pool_->NumConnectJobsInGroup("a")); | 
| 3065   EXPECT_FALSE(pool_->IsStalled()); |  | 
| 3066 | 3029 | 
| 3067   ASSERT_FALSE(pool_->HasGroup("b")); | 3030   ASSERT_FALSE(pool_->HasGroup("b")); | 
| 3068 | 3031 | 
| 3069   pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets, | 3032   pool_->RequestSockets("b", ¶ms_, kDefaultMaxSockets, | 
| 3070                         BoundNetLog()); | 3033                         BoundNetLog()); | 
| 3071 | 3034 | 
| 3072   ASSERT_TRUE(pool_->HasGroup("b")); | 3035   ASSERT_TRUE(pool_->HasGroup("b")); | 
| 3073   EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b")); | 3036   EXPECT_EQ(1, pool_->NumConnectJobsInGroup("b")); | 
| 3074   EXPECT_FALSE(pool_->IsStalled()); |  | 
| 3075 } | 3037 } | 
| 3076 | 3038 | 
| 3077 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) { | 3039 TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) { | 
| 3078   CreatePool(4, 4); | 3040   CreatePool(4, 4); | 
| 3079   connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 3041   connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 
| 3080 | 3042 | 
| 3081   ClientSocketHandle handle1; | 3043   ClientSocketHandle handle1; | 
| 3082   TestOldCompletionCallback callback1; | 3044   TestOldCompletionCallback callback1; | 
| 3083   EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", | 3045   EXPECT_EQ(ERR_IO_PENDING, handle1.Init("a", | 
| 3084                                          params_, | 3046                                          params_, | 
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3383   EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a")); | 3345   EXPECT_EQ(0, pool_->NumActiveSocketsInGroup("a")); | 
| 3384   ASSERT_EQ(OK, callback.WaitForResult()); | 3346   ASSERT_EQ(OK, callback.WaitForResult()); | 
| 3385 | 3347 | 
| 3386   // The hung connect job should still be there, but everything else should be | 3348   // The hung connect job should still be there, but everything else should be | 
| 3387   // complete. | 3349   // complete. | 
| 3388   EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); | 3350   EXPECT_EQ(1, pool_->NumConnectJobsInGroup("a")); | 
| 3389   EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); | 3351   EXPECT_EQ(0, pool_->IdleSocketCountInGroup("a")); | 
| 3390   EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a")); | 3352   EXPECT_EQ(1, pool_->NumActiveSocketsInGroup("a")); | 
| 3391 } | 3353 } | 
| 3392 | 3354 | 
| 3393 class MockLayeredPool : public LayeredPool { |  | 
| 3394  public: |  | 
| 3395   MockLayeredPool(TestClientSocketPool* pool, |  | 
| 3396                   const std::string& group_name) |  | 
| 3397       : pool_(pool), |  | 
| 3398         params_(new TestSocketParams), |  | 
| 3399         group_name_(group_name) { |  | 
| 3400     pool_->AddLayeredPool(this); |  | 
| 3401   } |  | 
| 3402 |  | 
| 3403   ~MockLayeredPool() { |  | 
| 3404     pool_->RemoveLayeredPool(this); |  | 
| 3405   } |  | 
| 3406 |  | 
| 3407   int RequestSocket(TestClientSocketPool* pool) { |  | 
| 3408     return handle_.Init(group_name_, params_, kDefaultPriority, &callback_, |  | 
| 3409                         pool, BoundNetLog()); |  | 
| 3410   } |  | 
| 3411 |  | 
| 3412   int RequestSocketWithoutLimits(TestClientSocketPool* pool) { |  | 
| 3413     params_->set_ignore_limits(true); |  | 
| 3414     return handle_.Init(group_name_, params_, kDefaultPriority, &callback_, |  | 
| 3415                         pool, BoundNetLog()); |  | 
| 3416   } |  | 
| 3417 |  | 
| 3418   bool ReleaseOneConnection() { |  | 
| 3419     if (!handle_.is_initialized()) { |  | 
| 3420       return false; |  | 
| 3421     } |  | 
| 3422     handle_.socket()->Disconnect(); |  | 
| 3423     handle_.Reset(); |  | 
| 3424     return true; |  | 
| 3425   } |  | 
| 3426 |  | 
| 3427   MOCK_METHOD0(CloseOneIdleConnection, bool()); |  | 
| 3428 |  | 
| 3429  private: |  | 
| 3430   TestClientSocketPool* const pool_; |  | 
| 3431   scoped_refptr<TestSocketParams> params_; |  | 
| 3432   ClientSocketHandle handle_; |  | 
| 3433   TestOldCompletionCallback callback_; |  | 
| 3434   const std::string group_name_; |  | 
| 3435 }; |  | 
| 3436 |  | 
| 3437 TEST_F(ClientSocketPoolBaseTest, FailToCloseIdleSocketsNotHeldByLayeredPool) { |  | 
| 3438   CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |  | 
| 3439   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |  | 
| 3440 |  | 
| 3441   MockLayeredPool mock_layered_pool(pool_.get(), "foo"); |  | 
| 3442   EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection()) |  | 
| 3443       .WillOnce(Return(false)); |  | 
| 3444   EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get())); |  | 
| 3445   EXPECT_FALSE(pool_->CloseOneIdleConnectionInLayeredPool()); |  | 
| 3446 } |  | 
| 3447 |  | 
| 3448 TEST_F(ClientSocketPoolBaseTest, ForciblyCloseIdleSocketsHeldByLayeredPool) { |  | 
| 3449   CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |  | 
| 3450   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |  | 
| 3451 |  | 
| 3452   MockLayeredPool mock_layered_pool(pool_.get(), "foo"); |  | 
| 3453   EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get())); |  | 
| 3454   EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection()) |  | 
| 3455       .WillOnce(Invoke(&mock_layered_pool, |  | 
| 3456                        &MockLayeredPool::ReleaseOneConnection)); |  | 
| 3457   EXPECT_TRUE(pool_->CloseOneIdleConnectionInLayeredPool()); |  | 
| 3458 } |  | 
| 3459 |  | 
| 3460 TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) { |  | 
| 3461   CreatePool(1, 1); |  | 
| 3462   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |  | 
| 3463 |  | 
| 3464   MockLayeredPool mock_layered_pool(pool_.get(), "foo"); |  | 
| 3465   EXPECT_EQ(OK, mock_layered_pool.RequestSocket(pool_.get())); |  | 
| 3466   EXPECT_CALL(mock_layered_pool, CloseOneIdleConnection()) |  | 
| 3467       .WillOnce(Invoke(&mock_layered_pool, |  | 
| 3468                        &MockLayeredPool::ReleaseOneConnection)); |  | 
| 3469   ClientSocketHandle handle; |  | 
| 3470   TestOldCompletionCallback callback; |  | 
| 3471   EXPECT_EQ(OK, handle.Init("a", |  | 
| 3472                             params_, |  | 
| 3473                             kDefaultPriority, |  | 
| 3474                             &callback, |  | 
| 3475                             pool_.get(), |  | 
| 3476                             BoundNetLog())); |  | 
| 3477 } |  | 
| 3478 |  | 
| 3479 TEST_F(ClientSocketPoolBaseTest, |  | 
| 3480        CloseMultipleIdleSocketsHeldByLayeredPoolWhenNeeded) { |  | 
| 3481   CreatePool(1, 1); |  | 
| 3482   connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |  | 
| 3483 |  | 
| 3484   MockLayeredPool mock_layered_pool1(pool_.get(), "foo"); |  | 
| 3485   EXPECT_EQ(OK, mock_layered_pool1.RequestSocket(pool_.get())); |  | 
| 3486   EXPECT_CALL(mock_layered_pool1, CloseOneIdleConnection()) |  | 
| 3487       .Times(1).WillRepeatedly(Invoke(&mock_layered_pool1, |  | 
| 3488                                       &MockLayeredPool::ReleaseOneConnection)); |  | 
| 3489   MockLayeredPool mock_layered_pool2(pool_.get(), "bar"); |  | 
| 3490   EXPECT_EQ(OK, mock_layered_pool2.RequestSocketWithoutLimits(pool_.get())); |  | 
| 3491   EXPECT_CALL(mock_layered_pool2, CloseOneIdleConnection()) |  | 
| 3492       .Times(2).WillRepeatedly(Invoke(&mock_layered_pool2, |  | 
| 3493                                       &MockLayeredPool::ReleaseOneConnection)); |  | 
| 3494   ClientSocketHandle handle; |  | 
| 3495   TestOldCompletionCallback callback; |  | 
| 3496   EXPECT_EQ(OK, handle.Init("a", |  | 
| 3497                             params_, |  | 
| 3498                             kDefaultPriority, |  | 
| 3499                             &callback, |  | 
| 3500                             pool_.get(), |  | 
| 3501                             BoundNetLog())); |  | 
| 3502 } |  | 
| 3503 |  | 
| 3504 }  // namespace | 3355 }  // namespace | 
| 3505 | 3356 | 
| 3506 }  // namespace net | 3357 }  // namespace net | 
| OLD | NEW | 
|---|